Real AWS interview questions with detailed answers on EC2, S3, IAM, VPC, Lambda, DynamoDB and cost optimization, grouped by difficulty.
88questions with answers
A Region is a separate geographic area (for example Ireland or Oregon) that holds several Availability Zones, an Availability Zone (AZ) is one or more isolated data centers inside a Region, and an edge location is a small site used to serve content close to users.
Each AZ has its own power, cooling and networking, and the AZs in a Region are connected by fast, low-latency links. This is why you spread an application across at least two AZs: if one data center has a problem, the others keep running. Regions are completely separate from each other, which is useful for data residency (keeping data in one country) and for disaster recovery. Edge locations are not where you run servers. Services like CloudFront (content delivery) and Route 53 (DNS) use them to answer users from a nearby place.
The common trap: AZ names such as us-east-1a are mapped differently for each AWS account, so your 1a may be a different physical zone than your colleague's 1a. When two accounts must agree on the same zone, use the AZ ID (like use1-az1) instead.
Further reading: AWS Global Infrastructure
AWS is responsible for the security of the cloud, and you are responsible for security in the cloud.
AWS looks after the physical data centers, the hardware, the network and the software that runs its services. You look after what you put on top: your data, who can access it (IAM), how it is encrypted, your network rules and any operating system you manage yourself.
The line moves depending on the service. On EC2 you patch the operating system. On RDS, AWS patches the database engine and the OS, but you still control who can connect and what data is stored. On S3, AWS runs the storage, but a public bucket that leaks customer data is your configuration mistake, not an AWS failure. Interviewers like this question because a good answer shows you know exactly which side of the line a given service puts you on.
Further reading: AWS Shared Responsibility Model
A user is a long-term identity for one person or application, a group is a set of users that share permissions, a role is an identity that is assumed temporarily, and a policy is the JSON document that says what is allowed or denied.
s3:GetObject), resources and an effect (Allow or Deny).Why roles matter: temporary credentials expire by themselves, so a leak has a short life. That is why AWS recommends roles for applications and, for people, signing in through IAM Identity Center rather than creating many IAM users with long-lived keys. The common wrong answer is attaching policies to individual users, which becomes impossible to audit once you have more than a few people.
Further reading: IAM best practices
The root user is the identity created with the account's email address, it has unrestricted access to everything, and you should lock it away and almost never use it.
You cannot limit the root user with IAM policies, so protect it hard:
Why interviewers ask: a leaked root credential means total account takeover with no way to restrict the damage. In a multi-account setup, member-account root users can also be limited by Service Control Policies, which is another reason to use AWS Organizations.
Further reading: The AWS account root user
A VPC (Virtual Private Cloud) is your own isolated virtual network inside one AWS Region, where you choose the IP address range and place your resources.
A VPC is divided into subnets, and each subnet lives in exactly one Availability Zone. What makes a subnet "public" is not its name. It is public when its route table sends internet traffic (0.0.0.0/0) to an internet gateway, and the resources in it have public IP addresses. A private subnet has no route to the internet gateway, so nothing from the internet can reach its resources directly.
A typical layout puts load balancers in public subnets and application servers and databases in private subnets. If private resources need to reach out to the internet (for software updates, for example), they go through a NAT gateway.
Further reading: What is Amazon VPC?
EC2 gives you virtual servers in the cloud, and an instance type name tells you the family, generation, special features and size of the server.
Take m7g.large:
m is the family, here general purpose (balanced CPU and memory).7 is the generation. Newer generations are usually faster and cheaper per unit of work.g is a feature letter: g means AWS Graviton (ARM) processors, a means AMD, d means local NVMe disks, n means faster networking.large is the size.Common families: t (burstable, cheap, good for light or spiky use), m (general), c (compute-heavy), r and x (memory-heavy), i (fast local storage), g and p (GPUs). To choose, find your bottleneck (CPU, memory, disk or network), start with a sensible size, then right-size using real CloudWatch metrics. A common trap with t instances is running them at high CPU for a long time: they run out of CPU credits and get throttled.
Further reading: Amazon EC2 concepts
EBS is a persistent network-attached disk for one EC2 instance in one AZ, instance store is a fast temporary disk physically inside the host, and EFS is a shared network file system.
Volume types to know: gp3 is the general-purpose SSD default (a baseline of 3,000 IOPS and 125 MiB/s no matter the size, and you can pay for more). io2 is for demanding databases that need high, consistent IOPS. st1 and sc1 are cheaper HDD types for large sequential data. Prefer gp3 over the older gp2, because gp2 ties performance to volume size.
Further reading: Amazon EBS volume types
An Elastic Load Balancer (ELB) receives incoming traffic on one address and spreads it across several healthy targets in different Availability Zones.
It does three useful things: it distributes load so no single server is overwhelmed, it runs health checks and stops sending traffic to targets that fail them, and it gives you one stable DNS name even as servers come and go. Most load balancers can also terminate TLS, so your instances do not have to handle certificates.
Because the load balancer works across AZs and removes failed targets, it is one of the main building blocks of a highly available application. It is usually paired with an Auto Scaling group, so new instances register automatically and failed ones are replaced.
Further reading: What is Elastic Load Balancing?
An Auto Scaling group keeps a set number of EC2 instances running, replaces unhealthy ones and adds or removes instances as demand changes.
You give it a launch template (which AMI, instance type, security groups and so on) plus a minimum, desired and maximum size. It spreads instances across the AZs you choose, so losing one AZ does not take everything down. When connected to a load balancer, it can use the load balancer's health checks, so an instance that stops answering requests is terminated and replaced automatically.
This gives you two things at once: resilience (broken servers heal themselves) and cost control (you only run as many servers as you need). It is the standard way to run a fleet of stateless web or application servers.
Further reading: What is Amazon EC2 Auto Scaling?
S3 is object storage: you store files (called objects) in containers called buckets and access them by key over HTTP.
Each object has the data, some metadata and a unique key like reports/2026/jan.csv. S3 has no real folders. The / characters in the key are just part of the name, and the console only shows them as folders for convenience. Bucket names are globally unique.
Facts worth knowing:
S3 is not a file system or a disk. You cannot edit part of an object in place, you replace the whole object, and it is not a good place for a database's data files.
Further reading: What is Amazon S3?
You use RDS because AWS runs the boring, risky parts of database administration for you (provisioning, patching, backups, failover and monitoring), so your team can focus on schema design and queries.
With a database on EC2 you own everything: installing and patching the OS and the database engine, configuring backups and testing restores, setting up replication and failover, and watching disk space and performance. Each of those is a place where a small mistake can cause data loss or downtime. RDS handles them as managed features:
RDS supports Aurora, MySQL, PostgreSQL, MariaDB, Oracle, SQL Server and Db2. What you give up is control: you do not get operating system access (RDS Custom is the exception for some engines), you can only install the extensions and versions RDS supports, and you cannot tune everything at OS level.
When is EC2 the right answer? When you need an unsupported engine or plugin, need deep OS-level control, or have a licensing model that does not fit RDS. For almost everything else, the honest answer is that your engineers' time costs more than the RDS premium. The common wrong answer is "EC2 is cheaper", which only looks true if you ignore the cost of the people who have to run it.
Further reading: What is Amazon RDS?
SQS is a managed message queue where one part of your system sends messages and another part picks them up and processes them later, so the two parts do not have to run at the same speed or at the same time.
Imagine a website where users upload photos that must be resized. If the web server resizes each photo while the user waits, a traffic spike makes pages slow and a crash loses the work. If the web server instead drops a message ("resize photo 123") into a queue and responds right away, a separate group of workers takes messages from the queue at their own pace.
What the queue gives you:
Handy facts: messages can be up to 1 MiB (raised from 256 KiB in August 2025), and are kept up to 14 days (4 days by default). Consumers pull messages by polling, and after processing they must delete the message. There are two queue types, Standard and FIFO, which the next question covers.
Further reading: What is Amazon SQS?
Lambda runs your code in response to events without you managing any servers, and you pay only for the time your code actually runs.
You upload a function, choose a runtime (Python, Node.js, Java, .NET, Go, Ruby or a container image), and connect it to a trigger: an API request, a file landing in S3, a message in SQS, a schedule, a database change and many more. AWS creates execution environments, runs your code and scales the number of copies up and down automatically. You are billed by the number of requests and by duration in milliseconds, multiplied by the memory you configured.
It is a good fit for:
It is a weaker fit for:
Remember that Lambda functions are stateless. Any state you keep in memory may disappear, so durable data belongs in S3, DynamoDB or a database. Key limits to remember: up to 10,240 MB of memory (CPU grows with memory), 15-minute timeout and 6 MB request and response payloads for synchronous calls.
Further reading: What is AWS Lambda?
Route 53 is AWS's managed DNS service, and it also registers domain names and runs health checks on your endpoints.
DNS is the system that turns a name like www.example.com into an IP address. In Route 53 you create a hosted zone for your domain and add records (A, AAAA, CNAME, MX, TXT and so on). A public hosted zone answers queries from the internet. A private hosted zone answers only inside the VPCs you attach it to, which is handy for internal names like db.internal.example.
Route 53 does more than answer questions:
Route 53 is built for very high availability and is a core piece of most failover designs. Two small facts that come up often: DNS answers are cached according to the record's TTL, so changes are not instant everywhere, and the name "53" comes from the DNS port number.
Further reading: What is Amazon Route 53?
CloudWatch tells you how your systems are performing, and CloudTrail tells you who did what in your AWS account.
CloudWatch collects metrics (CPU, request count, queue depth), logs (from applications and AWS services), alarms (act when a metric crosses a threshold) and dashboards. Use it for monitoring, troubleshooting and automatic reactions, such as an alarm that triggers Auto Scaling or sends a notification.
CloudTrail records API calls made in your account, from the console, CLI, SDKs and other services: who made the call, when, from which IP, and what the request and result were. It is your audit trail. Management events are recorded by default and visible in 90-day event history, and you create a trail that writes to S3 for long-term storage, or an organization-wide trail for all accounts.
Quick examples:
A third service often asked alongside is AWS Config, which records how resource configurations change over time and checks them against rules (for example "all EBS volumes must be encrypted").
One detail interviewers love: EC2 does not report memory or disk usage by default, because the hypervisor cannot see inside your OS. To get those metrics, install the CloudWatch agent on the instance.
Further reading: What is Amazon CloudWatch?
CloudFormation lets you describe AWS resources in a template file (YAML or JSON), and it creates, updates and deletes them together as a single unit called a stack.
Instead of clicking through the console, you write something like "a VPC, two subnets, a load balancer and an Auto Scaling group", and CloudFormation works out the order, creates everything and tracks it. If something fails during creation, it rolls back so you are not left with half a system.
Why this matters:
Related tools: the AWS CDK lets you write infrastructure in a normal programming language and generates CloudFormation for you, and Terraform is a popular third-party alternative that works across clouds. Manual console changes to a resource that a stack owns cause drift, which the next question covers.
Further reading: What is AWS CloudFormation?
The framework has six pillars: Operational Excellence, Security, Reliability, Performance Efficiency, Cost Optimization and Sustainability.
| Pillar | The core question |
|---|---|
| Operational Excellence | Can we run, monitor and improve this system, and learn from failures? (automation, runbooks, small reversible changes) |
| Security | Is data protected and access limited? (least privilege, encryption, traceability, detection) |
| Reliability | Does it recover from failure and meet demand? (multi-AZ, backups, tested recovery, avoiding single points of failure) |
| Performance Efficiency | Are we using the right resources for the job and keeping up as needs change? |
| Cost Optimization | Are we paying only for what delivers value? (right-sizing, commitments, removing waste) |
| Sustainability | Are we minimizing the environmental impact of the workload? |
The mature part of the answer is that the pillars pull against each other, and architecture is about choosing deliberately. For example, higher reliability (multi-Region, more replicas) raises cost. The cheapest design (a single instance) is the least reliable. Aggressive caching improves performance but adds complexity and a risk of stale data.
How it is used in practice: teams run a Well-Architected Review (AWS provides a free Well-Architected Tool in the console) against a workload, which asks structured questions per pillar and produces a list of risks to fix, ranked by importance. There are also "lenses" for specific areas, such as serverless, SaaS or machine learning.
In an interview, tie each design decision you make back to a pillar. For instance: "I used a Multi-AZ database for reliability, and Graviton instances for cost and sustainability." That shows you think in trade-offs.
Further reading: AWS Well-Architected Framework
Stopping shuts the instance down but keeps its disks, hibernating also saves the contents of memory so it can resume where it left off, and terminating deletes the instance for good.
DeleteOnTermination setting), while extra volumes you attached are kept unless you change that setting.Why interviewers ask this: it tests whether you know what survives. Three traps come up again and again. First, keeping important data on instance store, which disappears on stop or hardware failure. Second, pointing DNS at a normal public IP, which changes after a stop and start. Third, forgetting that a stopped instance still costs money for its volumes and any idle Elastic IP.
Good habits to mention: turn on termination protection for important servers so a mistaken click cannot delete them, and remember that in an Auto Scaling group instances are replaced automatically, so anything you want to keep must live outside the instance (a database, S3, EFS or snapshots).
Further reading: EC2 instance lifecycle
Scalability is the ability to handle more load, elasticity is adding and removing capacity automatically to match demand, high availability means staying up with only a very short interruption when something fails, and fault tolerance means continuing with no interruption at all.
A simple test to tell the last two apart: if a database fails over to its standby in about a minute, that is high availability. If two systems process every request in parallel and one can die without anyone noticing, that is fault tolerance.
Availability is often quoted in "nines": 99.9% allows about 8.8 hours of downtime per year, 99.99% about 52 minutes and 99.999% about 5 minutes. Each extra nine usually costs much more, so a strong answer links the target to what downtime really costs the business.
AWS examples to quote: multiple AZs for HA, multiple Regions for disaster recovery, S3's built-in redundancy for durability, and the habit of designing as if any single component can disappear at any moment.
Further reading: Reliability pillar of the Well-Architected Framework
A private IP is used inside your VPC and stays with the instance, a public IP is reachable from the internet but can change, and an Elastic IP is a static public IPv4 address that belongs to your account and can be moved between resources.
Cost is worth mentioning. Since early 2024, AWS charges a small hourly fee for every public IPv4 address, including ones attached to running instances, and not only idle ones. That is a good reason to put servers in private subnets behind a load balancer, use NAT or VPC endpoints for outbound access, and use IPv6 where you can.
When an Elastic IP is the right tool: a partner must allow-list one fixed address and you cannot use a load balancer with static IPs, or you need a simple manual failover. For most web apps, a load balancer plus a DNS name is better than an Elastic IP on one server.
Troubleshooting tip: for an instance to be reachable from the internet it needs three things together: a route to an internet gateway, a public or Elastic IP, and security group rules that allow the traffic. If it is missing any one of them, you get "I cannot reach my instance", and checking the three in turn solves most cases.
Further reading: Elastic IP addresses
You attach an IAM role to the instance through an instance profile, and the AWS SDK automatically fetches short-lived credentials for that role from the instance metadata service.
The credentials rotate on their own, never appear in your code, and are only valid from that instance. With access keys, the usual story is a key pasted into a config file, baked into an AMI or committed to Git, which then lives forever until someone notices.
A few details that show depth:
Further reading: Using instance profiles
With envelope encryption, KMS creates a small data key, you use that data key to encrypt your actual data, and KMS protects the data key itself with a master key that never leaves KMS.
The steps:
GenerateDataKey).Decrypt), get the plain key back and decrypt locally.Why this design: KMS can directly encrypt only about 4 KB, so it cannot handle big files, and sending gigabytes over the network to KMS would be slow. Envelope encryption also gives each object its own key. S3, EBS and RDS all do this for you when you turn on encryption.
Key types to know: AWS owned keys (invisible to you), AWS managed keys (like aws/s3) and customer managed keys, where you control the key policy, rotation and the ability to disable the key. The trap: if a customer managed key is deleted after its waiting period (7 to 30 days), every piece of data encrypted under it is gone for good.
Further reading: AWS KMS overview
Secrets Manager is built for secrets that need automatic rotation and costs per secret, while Parameter Store is a cheaper general store for configuration values and simple secrets.
| Secrets Manager | Parameter Store | |
|---|---|---|
| Automatic rotation | Yes, built in (for example RDS passwords) | No built-in rotation |
| Cost | Monthly fee per secret plus API calls | Standard parameters are free |
| Encryption | Always, with KMS | Optional, use SecureString |
| Best for | Database credentials, API keys | Config values, feature settings, low-cost secrets |
A good rule: if the value must rotate (database passwords), use Secrets Manager. If it is plain configuration (a URL, a feature flag), use Parameter Store. In both cases the application should read the value at runtime using its IAM role, and the secret should never be written into code, a container image or a Git repository.
Further reading: AWS Secrets Manager
AWS Organizations lets you manage many AWS accounts as a group, and an SCP is a guardrail that sets the maximum permissions accounts in that group can ever have.
You arrange accounts into Organizational Units (OUs) and attach SCPs to the root, an OU or a single account. Typical SCPs block disabling CloudTrail, block using regions you do not operate in, or stop accounts from leaving the organization.
The most important point: an SCP never grants permissions. It only filters. The real permission an identity has is the overlap of what the SCP allows and what its own IAM policies allow. If an SCP denies an action, even an account administrator cannot do it.
The traps to mention: SCPs do not apply to the management account (so keep workloads out of it), and people often assume that attaching an "allow everything" SCP gives access, when the IAM policy still has to allow the action too.
Further reading: Service control policies
A security group is a stateful firewall attached to a network interface (usually an instance), while a network ACL is a stateless firewall attached to a whole subnet.
| Security group | Network ACL | |
|---|---|---|
| Level | Instance / network interface | Subnet |
| State | Stateful: return traffic is allowed automatically | Stateless: you must allow return traffic yourself |
| Rules | Allow rules only | Allow and deny rules |
| Evaluation | All rules together | In number order, first match wins |
"Stateful" means that if a request is allowed in, the reply is allowed out without any extra rule. With a network ACL, you must also open the reply ports (the ephemeral range, 1024 to 65535) or connections will hang. That is the classic mistake.
In practice, security groups do most of the work, and they can reference other security groups (for example, "the database accepts traffic from the app servers' group"). Network ACLs are used as a coarse extra layer, such as blocking a known bad IP range for a whole subnet.
Further reading: Security groups
An internet gateway lets resources with public IPs talk to the internet in both directions, while a NAT gateway lets private resources start connections to the internet but blocks connections started from outside.
The NAT gateway sits in a public subnet and has an Elastic IP. The private subnet's route table sends 0.0.0.0/0 to the NAT gateway, and the NAT gateway's subnet sends it on to the internet gateway.
Things interviewers listen for:
Further reading: NAT gateways
A VPC endpoint lets your resources reach an AWS service privately, over the AWS network, without going through an internet gateway or NAT gateway.
Why use them: traffic stays off the public internet, you can lock down access with an endpoint policy, and you avoid NAT per-GB charges. Sending large S3 traffic through a free gateway endpoint instead of a NAT gateway is one of the easiest cost savings in AWS.
The trap: a gateway endpoint cannot be reached from on-premises networks or from peered VPCs. If you need private S3 access from those places, use an interface endpoint for S3.
Further reading: AWS PrivateLink concepts
Use VPC peering to connect a small number of VPCs directly, and use Transit Gateway when you have many VPCs or need to connect on-premises networks through one central hub.
VPC peering is a one-to-one link. It is simple and has no hourly fee, and it works across accounts and Regions. Its big limitation: it is not transitive. If A peers with B and B peers with C, then A still cannot reach C. Also, the VPCs cannot have overlapping IP ranges. Connecting 10 VPCs to each other needs 45 peering links, which is unmanageable.
Transit Gateway is a regional router in the middle. Every VPC, VPN and Direct Connect connection attaches to it once, and routing between them is transitive. You can use separate route tables to keep groups apart (for example, production cannot talk to development). It costs an hourly fee per attachment plus a per-GB fee.
Simple rule: two or three VPCs, use peering. A growing network or a hybrid setup, use Transit Gateway.
Further reading: What is a transit gateway?
The main options are On-Demand, Savings Plans (and Reserved Instances), and Spot, and the best answer combines them.
A practical strategy: cover your steady baseline with Savings Plans, handle spikes with On-Demand, and run interruption-tolerant work on Spot. The traps: running a database on Spot without a plan for interruption, and buying a commitment before you have right-sized the instances you are committing to.
Further reading: EC2 purchasing options
An ALB routes HTTP and HTTPS traffic using its content, an NLB moves raw TCP/UDP traffic extremely fast, and a GWLB sends traffic through third-party security appliances.
/api to one service, /images to another), host name or header, redirect HTTP to HTTPS, and authenticate users. Targets can be instances, IP addresses, containers or Lambda functions. Best for websites and microservices.The common trap: "a customer needs to allowlist our IP address". An ALB's IPs change, so you use an NLB, or put AWS Global Accelerator in front of the ALB to get static IPs. The old Classic Load Balancer is a legacy option you should not choose for new work.
Further reading: Elastic Load Balancing documentation
For most cases use target tracking, add scheduled scaling for predictable patterns, and consider predictive scaling when traffic repeats daily or weekly.
The part many candidates miss is choosing the right metric. CPU is not always the bottleneck. For a web tier, requests per target from the load balancer is often better. For queue workers, scale on backlog per instance (messages waiting divided by running workers). Also set an instance warm-up time so new instances are not counted before they can handle traffic, otherwise the group over-scales. The trap is a metric that does not track real load, which makes the group scale too late or flap up and down.
Further reading: Scaling policies for EC2 Auto Scaling
S3 storage classes trade lower storage prices for slower or costlier access, and lifecycle rules move or delete objects automatically as they age.
| Class | Use it for |
|---|---|
| Standard | Frequently accessed data |
| Intelligent-Tiering | Unknown or changing access patterns (moves objects automatically for a small monitoring fee) |
| Standard-IA | Infrequent access, still needs milliseconds retrieval |
| One Zone-IA | Infrequent data you can re-create, stored in only one AZ |
| Glacier Instant Retrieval | Archive that is rarely read but must be instant when it is |
| Glacier Flexible Retrieval | Archive, retrieval in minutes to hours |
| Glacier Deep Archive | Cheapest, long-term retention, retrieval in hours |
A lifecycle rule might say: after 30 days move logs to Standard-IA, after 90 days move to Glacier, after 7 years delete. Good rules also clean up incomplete multipart uploads and old non-current versions, which silently cost money.
The traps: the infrequent-access classes have a minimum storage duration and a retrieval fee, and Standard-IA bills small objects as at least 128 KB. So moving tiny or short-lived objects there can cost more, not less. When you do not know the access pattern, Intelligent-Tiering is the safe choice.
Further reading: Amazon S3 storage classes
Combine versioning with Object Lock or replication, restrict who can delete, and keep a copy in a separate account.
s3:DeleteObject for most principals. MFA Delete adds an MFA check for permanent deletes.The trap to mention: versioning alone is not a full defense. Someone with enough permissions can still delete specific versions, and replication can copy a deletion to the other side depending on configuration. For real protection against ransomware or a compromised admin, you want Object Lock or a backup in a separate account with tight access.
Further reading: Using versioning in S3 buckets
IAM policies attach to the caller, bucket policies attach to the bucket, and ACLs are an old per-object mechanism you should avoid. A presigned URL gives someone temporary access to one object without needing AWS credentials.
Inside one account, an Allow in either the IAM policy or the bucket policy is enough (unless something denies it). For cross-account access, both sides must allow: the caller's identity policy in their account and the bucket policy in the bucket owner's account.
A presigned URL is created by someone who already has access. It contains a signature, works for a limited time, and lets the holder GET or PUT that one object. It is perfect for letting a browser upload directly to S3 or share a private file briefly. The trap: the URL is only valid while the credentials that signed it are valid, so a URL made from an IAM role session stops working when that session expires, even if you asked for a longer expiry.
Further reading: Sharing objects with presigned URLs
Multi-AZ is for high availability (surviving a failure), while read replicas are for scaling reads (handling more queries). They solve different problems and are often used together.
Multi-AZ keeps a standby copy of your database in a second Availability Zone. Data is written to both synchronously, so the standby is always up to date. If the primary fails, RDS flips the database endpoint to the standby automatically, usually within a minute or two, and your application reconnects using the same endpoint name. In the classic Multi-AZ instance setup, the standby cannot serve any traffic, it only waits. A newer option, the Multi-AZ DB cluster, has two readable standbys and faster failover.
Read replicas are copies that receive changes asynchronously. They have their own endpoint and serve read queries, so you can send reports and read-heavy traffic to them and keep the primary free for writes. They can live in another Region, and you can promote one to become a standalone database, which is useful for disaster recovery and for migrations.
| Multi-AZ | Read replica | |
|---|---|---|
| Purpose | Availability and durability | Read scaling |
| Replication | Synchronous | Asynchronous (lag possible) |
| Failover | Automatic | Manual promotion |
| Readable | Not in the classic setup | Yes |
The traps: a read replica is not automatic high availability, and because replication is asynchronous, a read right after a write may return old data (replica lag). Your application has to be designed to tolerate that, for example by reading from the primary right after a write when freshness matters.
Further reading: Multi-AZ DB instance deployments
Aurora is AWS's own MySQL- and PostgreSQL-compatible database that separates compute from a shared, self-healing storage layer, which gives it faster failover and easier scaling than standard RDS engines.
In standard RDS, each database instance has its own attached EBS storage, and replication copies data between instances. In Aurora, the database instances all use one shared cluster volume that is automatically replicated six ways across three AZs. The storage grows on its own (up to 128 TiB) and repairs bad blocks in the background.
What that design gives you:
The trade-offs: Aurora costs more per hour than comparable RDS, its pricing has an I/O component (there is an I/O-Optimized option for heavy workloads), and it only exists for MySQL and PostgreSQL compatibility. A good answer is: choose Aurora for production workloads that need high availability, many replicas or global reach, and choose plain RDS for small, simple, cost-sensitive databases or engines Aurora does not support (such as Oracle or SQL Server).
Further reading: What is Amazon Aurora?
RDS takes a daily automated snapshot and continuously saves transaction logs, which lets you restore to any second within your retention period. A restore always creates a new database instance, it never overwrites the existing one.
There are two kinds of backup:
The important detail interviewers look for: a restore creates a new instance with a new endpoint. So after restoring, you must either point the application at the new endpoint, or rename the old and new instances so the original name belongs to the restored one. Plan for this before an incident, not during.
Other things worth saying:
DELETE with no WHERE. Both matter, and Multi-AZ would faithfully replicate your mistake to the standby.Further reading: Backing up and restoring an Amazon RDS DB instance
DynamoDB is a fully managed key-value and document database that gives single-digit millisecond reads and writes at almost any scale, and you design its tables around your access patterns rather than around relationships.
Every item is found by its primary key. This is either a partition key alone, or a partition key plus a sort key. DynamoDB hashes the partition key to decide which physical partition stores the item. With a sort key, all items sharing a partition key are stored together in sorted order, so you can fetch ranges efficiently, for example all orders for one customer between two dates. An item can be up to 400 KB.
Capacity modes:
For sizing: one RCU gives one strongly consistent read per second of up to 4 KB (or two eventually consistent reads), and one WCU gives one write per second of up to 1 KB. Larger items use more units.
How to think about design: list your queries first ("get the latest 20 orders for a customer", "get an order by ID"), then pick keys and indexes that serve them. DynamoDB has no joins, so related data is often stored together in one table. The classic mistakes are:
Scan (reads the whole table) instead of a Query (reads one partition key).status or date, which sends most traffic to one partition (see the hot partition question).Further reading: What is Amazon DynamoDB?
A GSI lets you query by a completely different key and can be added any time, while an LSI uses the same partition key with a different sort key and must be created with the table.
| GSI | LSI | |
|---|---|---|
| Partition key | Different from the table | Same as the table |
| Sort key | Any attribute | A different attribute |
| When you can create it | Any time | Only when creating the table |
| Capacity | Its own read/write capacity | Shares the table's capacity |
| Strongly consistent reads | No, eventually consistent only | Yes |
| Size limit | None | 10 GB per partition key value |
Read consistency: by default DynamoDB reads are eventually consistent, meaning a read right after a write might return the old value for a short moment. You can ask for a strongly consistent read on the base table (and on an LSI), which always returns the latest write but costs twice the read capacity and has slightly higher latency. A GSI is always eventually consistent, because it is updated asynchronously.
An important operational detail that shows real experience: writes to the base table are copied to each GSI. If a GSI does not have enough write capacity, it throttles writes to the base table too. So a badly sized index can make your whole table look broken. With on-demand mode, this risk is much lower.
In practice, most teams use GSIs because LSIs have to be planned on day one and add the 10 GB limit. Choose an LSI only when you need strongly consistent reads on an alternate sort order.
Further reading: Using Global Secondary Indexes in DynamoDB
ElastiCache is a managed in-memory cache (Redis OSS, Valkey or Memcached) that you put in front of a slower data store to cut latency and reduce load.
Reading from memory takes well under a millisecond, while a database query may take many milliseconds and costs real CPU. A cache helps when the same data is read often and does not change every second: product pages, user sessions, leaderboards, configuration, results of expensive queries.
The two main strategies:
Most real systems combine them with a TTL (time to live) so that even if an update is missed, stale data disappears after a set time.
Which engine? Redis/Valkey supports rich data types (lists, sets, sorted sets), persistence, replication and Multi-AZ failover, so it is the usual choice. Memcached is simpler and multi-threaded, useful for plain key-value caching. (For DynamoDB specifically, DAX is a purpose-built cache.)
Things that show experience: the cache stampede problem (a popular key expires and hundreds of requests hit the database at once, fixed by staggered TTLs or locking), and remembering that the cache is never the source of truth, so the application must work, just slower, when it is empty.
Further reading: Amazon ElastiCache
Use RDS for day-to-day transactions, Athena for occasional SQL queries over files in S3, and Redshift for heavy, repeated analytics on large structured data.
The AWS Glue Data Catalog acts as the shared table definition for Athena and others, and Glue ETL jobs can transform raw data into query-friendly formats.
A sensible decision path: if you query rarely or unpredictably over files in S3, choose Athena. If you have steady, heavy BI traffic with many concurrent users, choose Redshift. If the question is about the live application, that is RDS or DynamoDB. The trap is running analytics directly on the production database, or paying for a Redshift cluster that sits idle most of the day when Athena would do.
Further reading: Amazon Athena
Standard queues give nearly unlimited throughput but may deliver a message twice and may reorder messages, while FIFO queues keep strict order and prevent duplicates at lower throughput.
Standard: at-least-once delivery and best-effort ordering. Your code must be idempotent, meaning that processing the same message twice must not cause harm (for example, charging a customer twice).
FIFO: the queue name ends in .fifo. Messages with the same message group ID are delivered in exact order, and a deduplication ID stops duplicates within a 5-minute window, giving exactly-once processing. Throughput is lower (a high-throughput mode raises it). Use it for things like bank transactions or edits to the same record, where order matters.
Visibility timeout: when a consumer receives a message, SQS hides it from others for a set time (default 30 seconds, up to 12 hours). If the consumer deletes the message in time, it is done. If not, the message becomes visible again and someone else processes it. Set the timeout longer than your processing time. If it is too short, the same message is handled twice at the same time.
Dead-letter queue (DLQ): a message that fails repeatedly (after maxReceiveCount attempts) is moved to a separate queue. This stops a "poison message" from looping forever and gives you a place to inspect and redrive failures. Always put an alarm on the DLQ.
Also mention long polling (waiting up to 20 seconds for messages), which cuts empty responses and cost. The common mistakes are skipping idempotency on Standard queues, setting the visibility timeout too low and forgetting the DLQ.
Further reading: Amazon SQS visibility timeout
SQS holds work for consumers to pull, SNS pushes one message to many subscribers, and EventBridge routes events by rules to many targets with rich filtering.
A very common pattern is SNS plus SQS fan-out: an "order placed" message goes to an SNS topic, and each interested system (billing, shipping, email) has its own SQS queue subscribed to it. Each team processes at its own speed, has its own retries and DLQ, and a slow consumer cannot hurt the others.
How to choose: use SQS to smooth out and retry work, SNS for simple high-volume broadcast, and EventBridge when you want to route events between many services based on what the event contains, or react to AWS service events and schedules. The trap is using SNS alone when consumers can be down: if a subscriber is unavailable, a plain SNS message may be lost after retries, whereas an SQS queue keeps it.
Further reading: What is Amazon EventBridge?
Choose Kinesis Data Streams when many consumers need to read the same ordered stream of events, or you need to replay data, and choose SQS when you simply need a work queue.
In SQS, a message is a task. Once a consumer processes and deletes it, it is gone, and no other consumer ever sees it. There is no replay, and you do not manage capacity.
In Kinesis Data Streams, records are written to a log divided into shards. Records stay in the stream for a retention period (24 hours by default, up to 365 days), and any number of consumers can read them independently and at their own position. A new application can even start from the beginning and replay history. Order is guaranteed per shard, and the partition key decides which shard a record goes to.
| SQS | Kinesis Data Streams | |
|---|---|---|
| Model | Queue of tasks | Retained log of events |
| After reading | Message is deleted | Record stays until retention ends |
| Multiple independent consumers | Needs fan-out with SNS | Built in |
| Replay | No | Yes |
| Ordering | Only FIFO queues | Per shard |
| Capacity | Automatic | Shards (or on-demand mode) |
Use Kinesis for clickstreams, application logs, IoT telemetry, real-time analytics or feeding several downstream systems from one source. Kinesis Data Firehose (now called Amazon Data Firehose) is the easy way to deliver a stream into S3, Redshift or OpenSearch without writing consumers. If you need Kafka itself, there is Amazon MSK.
The trap in Kinesis is a hot shard: if most records share the same partition key, one shard takes all the traffic while the others sit idle, so choose a high-cardinality key.
Further reading: Amazon Kinesis Data Streams
Concurrency is how many copies of your function run at the same time, and a cold start is the extra delay when Lambda has to create a brand new execution environment for a request.
Concurrency is roughly requests per second multiplied by average duration in seconds. If you get 100 requests per second and each takes 0.5 seconds, you need about 50 concurrent executions. All functions in an account and Region share a concurrency quota (new accounts start lower, and it can be raised). If you hit it, synchronous calls fail with a throttle error (HTTP 429), and asynchronous calls are queued and retried.
Two controls:
Cold start: for a new environment, Lambda downloads your code, starts the runtime and runs your initialization code before the handler runs. It can be tens of milliseconds for light runtimes and a second or more for heavy ones like Java with big frameworks. How to reduce it:
A trap worth naming: cold starts only matter for user-facing, latency-sensitive calls. For background work from a queue, they rarely matter, and paying for provisioned concurrency there is wasted money.
Further reading: Understanding Lambda function scaling
Lambda can be called synchronously (the caller waits), asynchronously (Lambda queues the event) or by polling a stream or queue for you, and each has different retry rules.
Synchronous (API Gateway, ALB, the SDK Invoke call by default): the caller waits for the response. If the function fails or is throttled, the caller gets the error and is responsible for retrying.
Asynchronous (S3 events, SNS, EventBridge): Lambda places the event in an internal queue and returns immediately. If the function fails, Lambda retries up to two more times by default, with delays, and keeps the event for up to 6 hours. You can configure the retry count and maximum event age, and send failed events to a dead-letter queue or an on-failure destination (SQS, SNS, EventBridge or another Lambda) so they are not lost.
Event source mapping (SQS, Kinesis, DynamoDB Streams): Lambda itself polls the source and invokes your function with a batch of records. The retry behavior depends on the source:
Why it matters: retries mean your function can run more than once for the same event, so handlers must be idempotent. Also, with batches, return partial batch failures (the batchItemFailures response) so that one bad record does not cause the entire batch to be retried.
Further reading: Asynchronous invocation in Lambda
API Gateway is a managed front door for your APIs that handles routing, authentication, throttling and monitoring, and it comes in REST, HTTP and WebSocket flavors.
It receives requests from clients and forwards them to a backend such as Lambda, an ALB, or any HTTP endpoint. It can authorize callers (IAM, Cognito, JWT or a custom Lambda authorizer), throttle traffic, validate requests, and give you metrics and logs without you running a gateway server.
REST APIs are the full-featured option: API keys and usage plans (to meter customers), request and response transformation, request validation, built-in caching, per-method throttling, AWS WAF integration and private APIs inside a VPC. HTTP APIs are the simpler, cheaper and lower-latency option, with JWT authorizers and automatic deployments but fewer features. WebSocket APIs keep a two-way connection open, used for chat or live updates.
A practical rule: choose an HTTP API unless you specifically need a REST API feature such as usage plans, caching or request validation.
Points that show experience:
202 Accepted with a job ID, process it asynchronously (queue plus Lambda) and let the client poll or receive a callback.Further reading: Choose between REST APIs and HTTP APIs
Step Functions is a managed workflow service that runs a multi-step process as a state machine, handling ordering, branching, retries, waiting and error handling for you.
You describe the workflow in Amazon States Language (or design it visually). Each state can call a Lambda function, start an ECS task, write to DynamoDB, publish to SNS or call hundreds of other AWS services directly, without any glue code. Special states handle Choice (if/else), Parallel, Map (loop over a list), Wait and Catch/Retry for errors. Every execution has a visual history, so you can see exactly which step failed and with what input.
There are two workflow types:
When to use it: whenever the process has more than a couple of steps, needs conditional logic, must compensate when a later step fails (the saga pattern, such as refunding a payment if shipping fails) or must wait for something.
The wrong answers to avoid:
A neat way to remember it: queues and events are choreography (each part reacts independently), and Step Functions is orchestration (one coordinator controls the sequence).
Further reading: What is AWS Step Functions?
ECS and EKS are container orchestrators (they decide where containers run), and Fargate is a way to run containers without managing servers. Fargate works with both ECS and EKS.
The alternative to Fargate is the EC2 launch type, where you run the worker nodes yourself in an Auto Scaling group. That is more work, but it can be cheaper for large, steady fleets, and it is needed for GPUs, special instance types or when you need fine-grained control of the host.
How to decide:
The classic wrong answer is treating Fargate as an alternative to ECS or EKS. It is not an orchestrator. Also mention Amazon ECR as the place to store container images, and App Runner as an even simpler option for a web app from a container or source repository.
Further reading: What is Amazon ECS?
CloudFront is a content delivery network that caches your content at edge locations around the world, so users get responses from a nearby place instead of from your origin every time.
When a user requests a file, DNS sends them to a nearby edge location. If the edge has a fresh copy (a cache hit), it answers immediately. If not (a cache miss), it fetches the file from your origin, which can be an S3 bucket, an ALB, an API or any HTTP server, stores it for the configured TTL and returns it. You get lower latency, less load on the origin, built-in DDoS protection through AWS Shield Standard, free-ish HTTPS with ACM certificates and integration with AWS WAF.
Securing it:
Tuning it:
Cache-Control headers. Static assets can have long TTLs.app.3f9a1.js) over invalidations for deployments. Invalidations work (the first 1,000 paths per month are free) but are slow to rely on and cost money at scale.It also accelerates dynamic content, because requests travel over AWS's backbone network instead of the public internet. And remember Lambda@Edge and CloudFront Functions let you run small pieces of code at the edge, such as redirects or header changes.
Further reading: What is Amazon CloudFront?
A routing policy decides which answer Route 53 gives for a name, and an alias record is a Route 53-specific way to point a name at an AWS resource that, unlike a CNAME, works at the root of your domain.
Routing policies:
Alias vs CNAME:
| Alias | CNAME | |
|---|---|---|
Works at the zone apex (example.com) |
Yes | No |
| Query charges for AWS targets | Free | Charged |
| Targets | AWS resources (CloudFront, ELB, S3 website, API Gateway and more) | Any DNS name |
| Follows the target's IP changes | Yes, automatically | Yes, through DNS |
The zone apex point is the classic interview trap: the DNS standard forbids a CNAME at the apex, so to point example.com at a load balancer you must use an alias.
Also mention that failover depends on DNS caching. With a 300-second TTL, some clients keep using the failed endpoint for minutes, so use low TTLs on records you expect to fail over, and pair failover records with real health checks.
Further reading: Choosing a routing policy
A Site-to-Site VPN is an encrypted tunnel over the public internet that you can set up in minutes, while Direct Connect is a dedicated private network link that takes longer to order but gives steady performance.
Site-to-Site VPN: IPsec tunnels between your network and a virtual private gateway or Transit Gateway. It is cheap and quick, but it travels over the internet, so latency and throughput vary, and each tunnel is limited (around 1.25 Gbps). Every VPN connection gives two tunnels for redundancy.
Direct Connect (DX): a physical connection from your location (or a partner's) to an AWS Direct Connect location, with speeds from 50 Mbps (through partners) up to 100 Gbps. It gives consistent low latency and often lower data transfer costs for large volumes. But it can take weeks to provision, it costs more up front, and it is not encrypted by default. If you need encryption, use MACsec on supported ports or run a VPN over the Direct Connect link.
| VPN | Direct Connect | |
|---|---|---|
| Setup time | Minutes | Weeks |
| Path | Public internet | Private dedicated link |
| Performance | Variable | Consistent |
| Encryption | Built in (IPsec) | Not by default |
| Cost | Low | Higher |
Resilient design: a single DX connection is a single point of failure (the cable, the router or the whole location can fail). For critical workloads, use two connections at two different DX locations. A cheaper pattern is one DX connection as primary and a Site-to-Site VPN as a backup path, with BGP preferring the DX route. For many VPCs, terminate the connection on a Direct Connect gateway or Transit Gateway so that one link serves all of them.
The trap: assuming that Direct Connect is "automatically redundant" or "automatically encrypted". It is neither.
Further reading: What is a transit gateway?
They are separate security services that each do one job: WAF blocks bad web requests, Shield absorbs DDoS attacks, GuardDuty detects suspicious activity, Inspector finds vulnerabilities and Security Hub collects the findings in one place.
How to explain the combination: prevent (WAF, Shield, IAM, security groups), detect (GuardDuty, Inspector, Config), respond (EventBridge rules that trigger Lambda to isolate an instance or revoke a key, and notify the team). In a multi-account organization, you typically make a central security account the delegated administrator, so findings from every account flow to one place.
The trap: thinking that a security group or WAF replaces detection. Preventive controls will not tell you that a leaked access key is already being used.
Further reading: What is Amazon GuardDuty?
Use IAM Identity Center for your own workforce, Cognito for the customers of your application, and avoid IAM users unless there is no better option.
A quick way to remember: Identity Center = your staff to AWS. Cognito = your customers to your app. IAM roles = machines and services to AWS.
The trap: creating an IAM user for every developer and every customer. For developers it spreads long-term keys everywhere, and for customers it simply does not scale and mixes application identities with account administration.
Further reading: What is IAM Identity Center?
Use multipart upload to send big files in parallel parts, spread requests across key prefixes for very high request rates, and use Transfer Acceleration or CloudFront when users are far from the bucket's Region.
Large objects:
High request rates: S3 scales per prefix. It supports at least 3,500 write (PUT, COPY, POST, DELETE) and 5,500 read (GET, HEAD) requests per second per prefix in a bucket, and there is no limit to the number of prefixes. So if you need much higher totals, spread data across several prefixes instead of putting everything under one.
Distance:
Other performance options: S3 Express One Zone stores data in a single AZ and gives consistently low (single-digit millisecond) latency for demanding workloads, and the AWS Common Runtime (CRT) in the SDKs improves throughput for big transfers.
The old advice about adding random prefixes to key names to avoid "hot" partitions is outdated for most workloads. S3 now handles sequential key names fine, so interviewers who ask about it want you to know it no longer applies in the same way.
Further reading: Best practices design patterns: optimizing Amazon S3 performance
An EBS snapshot is a point-in-time backup of one volume, while an AMI is a template for launching whole EC2 instances, usually built from snapshots plus launch settings.
EBS snapshots: stored in S3 (managed by AWS). The first snapshot copies all the used blocks, and later ones are incremental, saving only the blocks that changed, yet each snapshot can be restored on its own. Deleting an old snapshot does not break newer ones, because AWS keeps whichever blocks they still need. You can create a volume from a snapshot in any AZ, copy snapshots to other Regions or accounts, and encrypt them. Automate them with Amazon Data Lifecycle Manager or AWS Backup.
AMIs: an Amazon Machine Image bundles the root volume snapshot, any extra volume snapshots, the permissions on who can launch it and a block device mapping. Launching from an AMI gives you an identical server. AMIs are Regional, so to use one in another Region you copy it.
Golden image pattern: bake your operating system, security agents, patches and application dependencies into an AMI. New instances launched by Auto Scaling then start in seconds, already configured, instead of running a long setup script at boot. A pipeline such as EC2 Image Builder (or Packer) builds, tests and publishes a fresh AMI on a schedule, and your launch template points at the latest version. This also helps with patching: rather than patch running servers, you replace them with instances from the new image (immutable infrastructure).
Practical cautions:
Further reading: Amazon EBS snapshots
Use AWS Systems Manager Session Manager, which gives a shell through the AWS API with IAM-based access, no open inbound ports and a full audit trail, instead of running and defending a bastion host.
Bastion host (the old way): a public EC2 instance that engineers SSH into, and then hop to private servers. It works, but you must keep port 22 open, manage SSH keys (rotating, revoking when people leave), patch and monitor the bastion and accept that it is an exposed target.
Session Manager:
AmazonSSMManagedInstanceCore permissions, and a route to the SSM endpoints (through NAT, or VPC interface endpoints for ssm, ssmmessages and ec2messages in a fully private network).Other Systems Manager tools worth a mention: Run Command (run a command on many instances), Patch Manager (patching baselines and schedules), Parameter Store and State Manager.
The trap: forgetting the prerequisites. If a Session Manager connection will not start, the usual causes are a missing instance role, an agent that is not running or no network path to the SSM endpoints.
Further reading: AWS Systems Manager Session Manager
These four features decide how traffic is shared, when a target is removed and how in-flight requests are handled during deployments and scale-in.
/health) or opens a port on each target. After a set number of failures the target is marked unhealthy and receives no new traffic, and after enough successes it is brought back. A good health endpoint checks that the app can really do its job, but not so deeply that a slow dependency makes every target look unhealthy at once and takes the whole site down.Other useful features: slow start mode for new targets, so they warm up gradually, and access logs for debugging.
A frequent real-world trap is a health check that passes while the app is not ready (or the reverse): a new instance joins the pool while still starting up and users see errors. Use a readiness-style health check and warm-up settings.
Further reading: Health checks for your Application Load Balancer targets
You first make costs visible and attributable with tags, then use Cost Explorer to analyze them, Budgets to set limits and alerts, and Cost Anomaly Detection to catch surprises early.
team, environment and project to resources, then activate them as cost allocation tags in the Billing console. Without them, your bill is just a list of services, and nobody knows who is responsible for what. Enforce tagging with tag policies in AWS Organizations or Config rules, because tags that are optional tend to be missing.Practical ways to cut cost once visible: right-size instances, delete unattached EBS volumes and unused Elastic IPs, use Savings Plans for the steady baseline, move to Graviton, add S3 lifecycle rules, use VPC gateway endpoints to avoid NAT charges and schedule non-production environments off outside working hours.
The trap: treating cost control as a once-a-quarter cleanup. It works best as a continuous habit with owners per tag, automatic alerts and regular reviews.
Further reading: What is AWS Cost Management?
A typical AWS pipeline uses CodePipeline to orchestrate stages, CodeBuild to build and test and CodeDeploy or ECS/Lambda deployment features to release, using a strategy such as rolling, blue/green or canary to keep risk low.
The services:
A healthy flow: commit, build once, run unit tests, produce an artifact (a container image in ECR or a zip in S3), deploy to a test stage and run integration tests, then promote the same artifact to production, perhaps after a manual approval.
Deployment strategies:
Good answers also mention infrastructure as code in the pipeline, secrets coming from Secrets Manager or Parameter Store and never from the repository, automatic rollback tied to CloudWatch alarms, and database changes that are backward compatible, so the old code still works during a rollback.
Further reading: AWS CodeDeploy deployment types
AWS Config continuously records the configuration of your resources and evaluates it against rules, so it answers "what does this resource look like, how has it changed and is it compliant?"
The three services answer different questions:
| Service | Question it answers | Example |
|---|---|---|
| CloudWatch | How is it performing right now? | CPU is at 95% |
| CloudTrail | Who made which API call? | User X changed a security group at 10:02 |
| Config | What is the configuration, and did it change or break a rule? | The security group allowed port 22 to 0.0.0.0/0 from Tuesday to Thursday |
How Config works: it keeps a configuration item history for each supported resource, so you can see a timeline of changes and the state of a resource at any past date. Config rules (AWS managed or your own Lambda-based ones) check resources against policy, such as "S3 buckets must not be public", "EBS volumes must be encrypted" or "required tags are present". A resource that breaks a rule is marked non-compliant. Remediation actions (through Systems Manager Automation) can fix it automatically, such as turning on encryption or closing a security group rule. Conformance packs bundle rules for a standard, and an aggregator collects compliance across accounts and Regions.
Typical uses: continuous compliance for audits, detecting drift from your security baseline, impact analysis ("what is attached to this security group?") and investigating an incident together with CloudTrail.
Config is detective by default. It tells you afterwards that something is wrong. To prevent the problem, use Service Control Policies or IAM conditions, and use Config with remediation for the rest. The cost point to mention: Config charges per configuration item recorded and per rule evaluation, so recording every resource type in every Region can get expensive, and you should scope it sensibly.
Further reading: What is AWS Config?
Every request starts as denied, an explicit Deny anywhere always wins, and a request is allowed only if it passes every guardrail that applies and some policy explicitly allows it.
The policy types and what each one does:
| Policy type | Grants permissions? | Role in the decision |
|---|---|---|
| Identity-based (on a user, group or role) | Yes | Says what the identity may do |
| Resource-based (bucket policy, key policy, queue policy) | Yes | Says who may use the resource, and can include other accounts |
| Service control policy (SCP) | No | Sets the maximum for every identity in an account or OU |
| Permissions boundary | No | Sets the maximum for one user or role |
| Session policy | No | Limits a single assumed-role session |
The way to think about it:
Same account versus cross-account: inside one account, an allow in the identity policy or the resource policy is enough. Across accounts, both the caller's identity policy and the resource's policy must allow it.
A worked example: a developer has AdministratorAccess, but their OU's SCP denies every Region except two. A call to create an EC2 instance in a third Region fails, even though the identity policy allows everything, because the guardrail removed it.
The common wrong answer is "I attached an admin policy, so it must work". Whenever someone "has the permission but is still denied", look for an explicit deny, an SCP, a boundary, a session policy or, for encrypted data, the KMS key policy. The IAM Policy Simulator and CloudTrail help you find which one blocked the call.
Further reading: Policy evaluation logic
Keep the bucket private by default, grant the narrowest access you can, encrypt the data, require HTTPS, and turn on versioning and logging so mistakes can be undone and detected.
Work through it as layers, starting with the most important:
"Principal": "*". Use conditions, such as allowing access only from your organization (aws:PrincipalOrgID) or only through a certain VPC endpoint (aws:SourceVpce).{ "Version": "2012-10-17", "Statement": [{ "Sid": "DenyInsecureTransport", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": ["arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*"], "Condition": { "Bool": { "aws:SecureTransport": "false" } } }]}The classic wrong answer is "I added a bucket policy, so the bucket is secure". A policy only describes who is allowed. Block Public Access and monitoring are what protect you when somebody later writes a mistaken policy.
Further reading: Security best practices for Amazon S3
Choose DynamoDB when you need steady, very low latency at any scale for access patterns you know in advance, and choose a relational database when you need flexible queries, joins and strong relationships between data.
| DynamoDB | RDS / Aurora | |
|---|---|---|
| Data model | Key-value and document, flexible schema | Tables with a fixed schema and relations |
| Queries | By key and index, planned up front | Flexible SQL with joins and ad hoc queries |
| Scaling | Almost unlimited, automatic and horizontal | Bigger instances and read replicas (Aurora scales further) |
| Latency | Single-digit milliseconds, steady as it grows | Depends on the query, indexes and instance size |
| Transactions | Supported, with limits | Full ACID across many tables |
| Operations | Serverless, nothing to patch | Managed, but you choose instance sizes |
| Cost model | Per request or provisioned throughput | Per instance hour plus storage |
Good fits for DynamoDB: shopping carts, user sessions and profiles, leaderboards, IoT data, and any service that looks things up by an ID at high scale or with spiky traffic. It also fits serverless apps well, because there are no database connections to manage.
Good fits for a relational database: reporting, financial systems, data with many relationships, queries you cannot predict, and applications already written for SQL. Joins and ad hoc questions are natural in SQL but awkward or impossible in DynamoDB.
The hidden cost of DynamoDB is design effort. You list your access patterns first, then shape the keys and indexes to serve them. If the product later needs a new kind of query, you may need a new index or even a new table design, and answering it with a full Scan is slow and expensive.
Avoid the lazy argument that "NoSQL scales, SQL does not". Many very large systems run on relational databases. A strong answer often combines them: DynamoDB for a high-traffic lookup path, a relational database or a data lake for reporting, and streams to move data between them.
Further reading: Choosing an AWS database service
A user pool signs your app's users in and gives them tokens, while an identity pool exchanges a trusted identity for temporary AWS credentials so the user can call AWS services directly.
User pool (authentication): a managed user directory. It handles sign-up, sign-in, password rules, MFA, account recovery and federation with providers such as Google, Apple, SAML and OIDC. After sign-in it returns JWT tokens (ID, access and refresh). Your backend or API Gateway checks those tokens to know who the caller is. Use a user pool whenever the app needs to answer "who is this user?".
Identity pool (access to AWS): takes a login (from a user pool, a social provider, or an anonymous guest) and swaps it for temporary AWS credentials by assuming an IAM role. You can define one role for guests and another for signed-in users. Use it when the client has to call AWS directly, for example a mobile app that uploads a photo straight to S3.
Many apps need only a user pool, together with an API Gateway authorizer, and never use an identity pool. Add an identity pool only when the front end must reach AWS services itself, and then keep the role tight. For example, limit each user to their own S3 prefix by using their identity ID inside the policy.
The common wrong answer is to treat them as the same thing, or to say that the user pool hands out AWS credentials. It hands out tokens, and the identity pool turns an identity into credentials.
Further reading: What is Amazon Cognito?
For data at rest, turn on encryption for each storage service using KMS keys, and for data in transit, require TLS everywhere with certificates from AWS Certificate Manager.
At rest
In transit
aws:SecureTransport is false, and require TLS on database connections.Which key type
| Key type | Control you have | Typical use |
|---|---|---|
| AWS owned keys | None, invisible to you | Default for some services |
| AWS managed keys | AWS manages them, you can see usage | Easy default |
| Customer managed keys | You set the key policy and rotation and can disable the key | Compliance, cross-account sharing, strict audit |
Use customer managed keys when you must control who can decrypt, share encrypted data with other accounts or prove who used a key. The trap is forgetting the key in your disaster recovery plan: if a key is deleted, or lives only in a Region that is down, the data and backups it protects can become unusable. Consider multi-Region keys for cross-Region designs, and remember that key policies, not only IAM policies, decide who can use a key.
Further reading: AWS KMS overview
Use change sets to preview updates, drift detection to find manual changes, and protection settings to stop stateful resources like databases from being deleted or replaced by accident.
Change sets: before you apply an update, create a change set. CloudFormation compares your new template with the live stack and lists what will be added, modified or removed. The key thing to check is the Replacement column. Some property changes cannot be done in place, so CloudFormation creates a new resource and deletes the old one. For an RDS database or an S3 bucket with data, replacement can mean data loss.
Drift detection: if someone changes a resource by hand in the console, the stack no longer matches reality. Drift detection compares the actual configuration with the template and reports the differences. The danger is that your next stack update may silently overwrite the manual fix, and an emergency change gets lost. The healthy habit is to change things through the template, and feed emergency fixes back into it.
Rollbacks:
UPDATE_ROLLBACK_FAILED. You fix the cause (often a manually changed or deleted resource) and then continue the rollback, skipping resources if needed.Protecting stateful resources:
DeletionPolicy: Retain or Snapshot keeps or snapshots a resource when the stack is deleted.UpdateReplacePolicy does the same when a resource is replaced.For big systems, split into nested stacks or separate stacks (network, data, application) so that a change to the app cannot touch the database, and use StackSets to deploy the same stack to many accounts and Regions.
Further reading: Detecting unmanaged configuration changes (drift)
Put a load balancer in front, run stateless application servers in an Auto Scaling group across at least two AZs, and keep the data in a Multi-AZ database, so that no single component or single AZ is a single point of failure.
Layer by layer:
When an AZ fails: the ALB's health checks fail for the instances in that AZ and traffic flows to the surviving AZs. The Auto Scaling group launches replacement instances in the healthy AZs. RDS Multi-AZ promotes the standby (typically within a minute or two). Users may see a short blip, but the system keeps serving.
The traps interviewers listen for:
Further reading: AWS Well-Architected Reliability Pillar
RPO is how much data you can afford to lose and RTO is how long you can afford to be down, and the four strategies (backup and restore, pilot light, warm standby and multi-site active/active) trade cost against faster recovery.
| Strategy | What runs in the recovery Region | Typical RPO / RTO | Cost |
|---|---|---|---|
| Backup and restore | Nothing. Backups are copied there | Hours / hours or longer | Lowest |
| Pilot light | Data is replicated and always on, core services (like the database) run minimally, app servers are off | Minutes / tens of minutes | Low |
| Warm standby | A scaled-down but fully working copy of the whole stack | Seconds to minutes / minutes | Medium |
| Multi-site active/active | Full capacity in two or more Regions serving users at once | Near zero / near zero | Highest |
How to choose:
The building blocks: S3 cross-Region replication, Aurora Global Database, DynamoDB global tables, RDS cross-Region read replicas or snapshot copies, AWS Backup with cross-Region and cross-account vaults, infrastructure as code (so the whole stack can be created in the recovery Region), Route 53 health checks and failover routing, and AWS Elastic Disaster Recovery for server-based workloads.
The traps that separate strong answers:
Further reading: Disaster recovery options in the cloud
Work outward from the instance along the path its traffic takes: instance, security group, network ACL, route table, NAT gateway, internet gateway, and finally DNS. At each step, confirm that the next hop exists and that nothing blocks it.
curl: could not resolve host), a timeout or a refused connection? Resolution failures point to DNS, and timeouts usually point to routing or filtering.0.0.0.0/0 route to a NAT gateway (nat-xxxx)? A missing route, or a route marked blackhole (the target was deleted), is the most common cause.available? A classic NAT gateway must sit in a public subnet and have an Elastic IP. If you use the newer regional NAT gateway, check that it is available in this AZ and that the route points to it.0.0.0.0/0 pointing to an internet gateway, and the internet gateway must be attached to the VPC. A NAT gateway in a subnet without that route is a surprisingly common mistake.enableDnsSupport and enableDnsHostnames on, and that no custom DHCP option set or private hosted zone is hijacking resolution.Tools that save time:
ErrorPortAllocation (too many connections to one destination) and PacketsDropCount.Alternatives worth mentioning: if the instance only needs AWS services (S3, DynamoDB, SSM), a VPC endpoint removes the need for internet access completely and avoids NAT charges.
The common wrong answer is "add a public IP to the instance". That does not help in a private subnet, because it has no route to an internet gateway, and it would defeat the reason for using a private subnet.
Further reading: Troubleshoot NAT gateways
AWS decides access by combining several layers of policy, so you check each layer in turn: the exact error, the caller's identity, identity policies, the bucket policy, organization-level guardrails, encryption keys and network controls.
The rule of thumb behind it: everything is denied by default, an explicit Deny always wins, and then you need an Allow somewhere.
A checklist, in order:
s3:GetObject) on the right resource ARN? A very common mistake: the bucket ARN is arn:aws:s3:::my-bucket and the object ARN is arn:aws:s3:::my-bucket/*. Object actions need the /* form, and s3:ListBucket needs the bucket form.Deny statements with conditions: required HTTPS (aws:SecureTransport), a specific VPC endpoint (aws:SourceVpce), allowed IP ranges, an organization ID or required encryption headers.kms:Decrypt permission, in both its IAM policy and the key policy. S3 can say AccessDenied when the real problem is the key.A subtle trap: if the key does not exist and the caller lacks s3:ListBucket, S3 returns 403 instead of 404, to avoid revealing which keys exist. So "AccessDenied" sometimes just means "this object is not there".
Tools: the IAM Policy Simulator to test identity policies, IAM Access Analyzer to validate and review policies and CloudTrail to see what really happened. When asked how you work, describe the method: reproduce, identify the caller, list every policy layer that applies and test one at a time.
Further reading: Policy evaluation logic
There are two patterns: have the caller assume an IAM role in the target account, or grant access directly through a resource-based policy on the target resource. Both need permission on both sides.
Pattern 1: cross-account role.
sts:AssumeRole on that role's ARN.AssumeRole and receives temporary credentials, then acts as the role in account B.While using the role's credentials, the caller has only the role's permissions, and not its own original ones. That matters if the app also needs to touch resources in its home account.
Pattern 2: resource-based policy. Services such as S3 (bucket policies), SQS, SNS, Lambda and KMS let the resource name a principal from another account. The caller keeps its own identity and permissions and uses the resource directly. For cross-account access, the identity policy in A and the resource policy in B must both allow it.
Which to use: a resource policy is simpler for one resource and avoids switching identities. A role is better when the caller needs access to many resources in B, or for a clean, auditable boundary (CloudTrail shows the assumed role).
Security details that make an answer strong:
arn:aws:iam::ACCOUNT:root). The root form lets any principal in that account with AssumeRole permission use the role.aws:PrincipalOrgID condition to allow every account in your organization without listing each one.The common mistake is setting up only one side, and then getting AccessDenied, or using long-lived access keys from account B inside account A.
Further reading: Cross-account access using IAM roles
The usual cause is that Lambda concurrency is being limited or the queue's visibility settings do not match the function's behavior, so messages return to the queue and exhaust their retries without ever being truly processed.
How the integration works: Lambda polls the queue, takes a batch of messages and invokes your function. Messages stay hidden by the visibility timeout while the function runs. If the function succeeds, Lambda deletes the batch. If it fails, or is throttled, the messages become visible again after the timeout and each retry increases the message's receive count. When the receive count passes maxReceiveCount, the message moves to the DLQ.
The hidden trap: throttling counts as a failed attempt. If your function is capped by reserved concurrency, or the account concurrency is exhausted by other functions, Lambda cannot invoke it, and messages are returned to the queue. After a few such cycles, perfectly good messages end up in the DLQ.
What to check and fix:
Throttles and ConcurrentExecutions. Raise the account quota, check whether other functions are consuming it and review the function's reserved concurrency.maxReceiveCount. Set it high enough (often 5 or more) to survive transient throttling before a message is declared dead.ReportBatchItemFailures), so one poison message does not make Lambda retry all ten in the batch.ApproximateAgeOfOldestMessage for the main queue, because they tell you the system is falling behind before the users do.If the caller is synchronous (for example API Gateway to Lambda), throttled requests return HTTP 429 to the client. Then the fix options are: raise the concurrency quota, use provisioned concurrency for predictable peaks, or put a queue in front to level the load, so a spike becomes a short delay instead of an error.
Further reading: Using Lambda with Amazon SQS
First decide whether the load balancer generated the error or your target did, then use the specific code to narrow down the cause: 502 means a bad response from the target, 503 means no healthy targets or no capacity, and 504 means the target took too long.
Step 1: who produced it? CloudWatch has separate metrics: HTTPCode_ELB_5XX_Count (errors made by the load balancer) and HTTPCode_Target_5XX_Count (errors returned by your application). If the target returned a 500, 502 or 503 itself, the ALB just passed it along, and the bug is in your app. Access logs show for each request the ALB status code, the target status code and timing fields (request_processing_time, target_processing_time), which tell you where the delay was.
502 Bad Gateway (the ALB could not get a valid response):
503 Service Unavailable:
504 Gateway Timeout:
TargetResponseTime.Also check: health check path and success codes (a health check that passes while the app is broken, or fails while it is fine), target CPU and memory, recent deployments (did errors start with one?) and whether errors affect one AZ or one target only.
The common wrong answer is raising the timeout or adding servers without looking at which code and which side generated the error. The reasoning "ELB-generated or target-generated, then which code" is what interviewers want to hear.
Further reading: Troubleshoot your Application Load Balancers
First find what changed using cost analysis tools, and rule out a security incident, then fix the specific cause and put alerts and guardrails in place so it cannot surprise you again.
1. Identify the change.
2. Rule out compromise. If you see unfamiliar services (such as large GPU instances), unusual Regions, or a user nobody recognizes, treat it as a possible leaked credential, which is a common cause of crypto-mining bills. Check CloudTrail for the identity, rotate or disable the credentials, remove unknown resources, and contact AWS Support.
3. The usual suspects, by where costs hide:
| Symptom | Likely cause |
|---|---|
| EC2 - Other, or NAT | NAT gateway data processing charges (large S3 or internet traffic through NAT) |
| Data transfer | Traffic leaving AWS, cross-AZ traffic or cross-Region replication |
| CloudWatch | Verbose log ingestion, or high-cardinality custom metrics |
| S3 | Request charges from a runaway job, or old versions piling up |
| EC2 and EBS | Forgotten instances, unattached volumes and old snapshots |
| Load balancers | Idle load balancers, Elastic IPs not in use |
| Lambda or DynamoDB | An infinite loop or retry storm driving requests |
4. Fix the cause, then reduce more broadly:
5. Prevent a repeat. Enforce tags for ownership, set Budgets with alerts (including a forecast alert), enable Anomaly Detection, and review costs regularly. In a multi-account setup, use SCPs to block expensive services or unused Regions in sandbox accounts.
Interviewers value the order: analyze before cutting. Randomly shutting things down can break production while the real cause keeps running.
Further reading: Detecting unusual spend with AWS Cost Anomaly Detection
Use AWS Organizations with separate accounts for different environments, teams and security functions, set up through a landing zone (such as AWS Control Tower) with guardrails, central logging and single sign-on.
Why multiple accounts? An account is the strongest isolation boundary in AWS. It limits the blast radius of mistakes and attacks, gives clean billing per team or product, avoids shared service quotas, and makes permissions simpler (production access is separate from development).
A common structure:
How you control it:
Trade-offs and traps: too many accounts bring overhead (cross-account networking, more roles) so scale the structure with the organization. Too few accounts (everything in one) is the more common and more dangerous mistake. Another trap is putting workloads in the management account, which defeats the guardrail model. Automate account creation with infrastructure as code, so each new account gets the same baseline (logging, alarms, roles) automatically.
Further reading: What is AWS Control Tower?
Copy the data to AWS first, keep it in sync with continuous replication, then do a short, rehearsed cutover once the replica has caught up. AWS Database Migration Service (DMS) is the usual tool for this.
1. Assess and choose the target. Decide between a homogeneous migration (same engine, such as PostgreSQL to RDS PostgreSQL or Aurora) and a heterogeneous one (for example Oracle to PostgreSQL). For heterogeneous moves, the AWS Schema Conversion Tool and DMS Schema Conversion convert the schema and code and report what needs manual work. That conversion is often the hardest part, much harder than moving the data.
2. Prepare the connection and the target. Set up a VPN or Direct Connect link with enough bandwidth, create the target (Multi-AZ, right-sized, encrypted) and apply the schema. For very large datasets or poor bandwidth, move the bulk with AWS Snowball and then sync the changes.
3. Full load plus CDC. A DMS task first copies all existing data (full load), while capturing changes made in the meantime, then applies them and continues with change data capture (CDC), so the target stays within seconds of the source. For homogeneous engines, native tools (logical replication, backup and restore with log shipping) can also work well.
4. Validate. Use DMS data validation to compare rows, run application tests against the target, compare performance with realistic load, and rehearse the whole cutover at least once.
5. Cut over. Schedule a window. Then: stop writes at the source (or put the app in read-only mode), wait until replication lag reaches zero, validate counts, switch the application's connection string or DNS to the new database, and confirm the app works. Keep the old database untouched.
6. Have a rollback plan. Decide beforehand what triggers a rollback, and how you would go back (for example, reverse replication from AWS to on-premises, so the old database does not lose the new writes).
Common traps:
Further reading: What is AWS Database Migration Service?
Let clients upload directly to S3, send an event to an SQS queue, process messages with Lambda or containers, record the result durably and make the processing idempotent, because every part of the chain can deliver the same event more than once.
Design choices and why:
PENDING, PROCESSING, DONE, FAILED) lets the user or other systems see progress.Handling duplicates (idempotency): delivery is at-least-once. S3 notifications can occasionally be duplicated, SQS Standard can deliver twice and retries after a timeout repeat work. So build the worker so that running it twice gives the same result. A good pattern: use the object's bucket, key and version ID (or ETag) as an idempotency key, and write the status record with a conditional write (attribute_not_exists) so that only one worker "wins" the right to process it. Write outputs to a deterministic location, so that a repeat simply overwrites the same file.
Handling failures:
FAILED quickly instead of retrying forever).Other considerations: ordering is not guaranteed, so do not depend on it. Use S3 lifecycle rules to delete temporary and raw files. Encrypt with KMS, and give each component a least-privilege role. Monitor queue depth, the age of the oldest message, error rates and DLQ size.
Further reading: Amazon S3 Event Notifications
A hot partition happens when a large share of reads or writes hits a few partition key values, so one physical partition reaches its throughput limit while the rest of the table sits idle.
DynamoDB spreads items across partitions using a hash of the partition key. Each partition can serve only a limited amount of throughput (about 3,000 read units and 1,000 write units per second). Total table capacity helps only if traffic is spread evenly. If most requests use the same key, such as a popular product, a single tenantId or today's date, they all land on one partition and get throttled, even when the table as a whole has plenty of spare capacity.
DynamoDB's adaptive capacity and automatic partition splitting help with moderate imbalance, but they cannot split a single very hot key. On-demand mode does not remove the per-partition limit either, so "just switch to on-demand" is the common wrong answer.
How to confirm: use CloudWatch Contributor Insights for DynamoDB, which shows the most accessed and most throttled keys, and check the throttle metrics (ReadThrottleEvents, WriteThrottleEvents) against consumed capacity.
Fixes:
userId or orderId instead of status, country or date.product#123#0 to product#123#9, spread writes randomly (or by a hash) over the suffixes, and read by querying all the shards and merging the results. This trades read complexity for write throughput.tenantId#date) to spread a hot tenant's traffic across more partitions.Design lesson: model the table around your access patterns and the distribution of traffic. A key that looks fine in a schema diagram can still fail under real load, so load test with realistic skew and not only with random keys.
Further reading: Designing partition keys to distribute your workload evenly
Choose based on the workload's shape (how long it runs, how steady the traffic is), how much operational work your team can handle, runtime constraints and cost at your expected scale. There is no universal winner.
| Lambda | Containers (Fargate / ECS / EKS) | EC2 | |
|---|---|---|---|
| Management effort | Lowest | Medium | Highest |
| Scaling | Automatic, fast, down to zero | Automatic, but with tasks or pods to define | You configure Auto Scaling |
| Max run time | 15 minutes per invocation | Unlimited | Unlimited |
| Pricing | Per request and millisecond | Per second of provisioned CPU and memory | Per second of the instance |
| Best traffic pattern | Spiky, unpredictable, low or bursty | Steady or moderate, many services | Steady and high, long-running |
| Constraints | Limits on time, memory, payload, no persistent connections | Image-based, more control | Full control (OS, GPU, special hardware) |
Questions that drive the decision:
Typical answers: event-driven glue, scheduled jobs and low-traffic APIs go to Lambda. A set of microservices with steady traffic goes to ECS on Fargate. A platform team standardizing on Kubernetes uses EKS. GPU, high-performance or legacy lift-and-shift workloads use EC2.
Mixing is normal. Many real systems use all three: an API on Fargate, Lambda for event handlers and file processing, and EC2 for a legacy component. The strong interview answer shows that you pick per component and can explain the trade-offs, instead of declaring one the best.
Further reading: Choosing an AWS compute service
Use Cognito for authentication, API Gateway with Lambda for the API, DynamoDB for data and S3 with presigned URLs for files, all behind CloudFront and WAF, and design around Lambda and DynamoDB limits from the start.
The pieces:
Where it can hurt:
Security checklist: tokens validated at the gateway, per-user authorization in the code (checking that the user owns the record, not just that they are logged in), encryption with KMS, no public buckets and secrets in Secrets Manager.
Further reading: What is Amazon Cognito?
The 6 Rs are the main strategies for moving each application to the cloud: rehost, replatform, repurchase, refactor, retire and retain. A good migration plan chooses the right R per application, based on business value, effort and risk.
| Strategy | Meaning | Example |
|---|---|---|
| Rehost ("lift and shift") | Move as-is to EC2 | Moving a VM using AWS Application Migration Service |
| Replatform ("lift, tinker and shift") | Small changes to use managed services | Moving a self-run database to RDS, or an app to Elastic Beanstalk |
| Repurchase | Replace with a SaaS product | Moving from a self-hosted CRM to a SaaS CRM |
| Refactor / re-architect | Redesign to be cloud-native | Splitting a monolith into services and Lambda |
| Retire | Switch off what is not needed | Decommissioning duplicate or unused applications |
| Retain | Keep on-premises for now | A system with licensing, latency or compliance constraints |
(Some frameworks also list relocate for moving VMware workloads as-is.)
A practical plan:
Traps interviewers like:
Further reading: AWS Prescriptive Guidance: migration strategy
Assume the key is already stolen: disable it right away, find out what it was used for, remove anything the attacker created, rotate anything it could read, and then fix the process. Deleting the commit is not enough.
Bots scan public repositories for AWS keys within minutes, so speed matters. AWS also scans for exposed keys and may attach a quarantine policy to the user, which you should review but never rely on.
1. Contain it (first minutes).
aws iam update-access-key \ --user-name alice \ --access-key-id AKIAEXAMPLE \ --status Inactive2. Investigate. Search CloudTrail for every call made with that access key ID, in every Region (event history is shown per Region), from the time it was pushed:
aws cloudtrail lookup-events \ --lookup-attributes AttributeKey=AccessKeyId,AttributeValue=AKIAEXAMPLELook for unfamiliar IP addresses, new IAM users, roles or access keys, policy changes, and new resources such as large EC2 instances in Regions you never use. Check billing and GuardDuty findings too.
3. Clean up. Delete anything the attacker created, rotate every other secret the key could have read (database passwords, other keys), and delete the original key once you are done. If you see abuse, open a case with AWS Support.
4. Fix the cause.
The order to state out loud is: disable first, investigate second. A key that is still active while you read logs is still being used against you.
Further reading: Managing access keys for IAM users
First decide which layer is broken, the AWS host, the operating system or the network path to the instance, because the two status checks and the exact connection error point to different places.
Step 1: read the two status checks.
Step 2: the instance runs, but you cannot connect. Follow the path and use the error message as a clue:
| Error | Usually means |
|---|---|
| Connection timed out | Network problem: security group, NACL, route, or no public IP |
| Connection refused | The network works, but nothing is listening on that port (SSH service down, OS firewall) |
| Permission denied | Authentication problem: wrong key pair, wrong username or wrong key permissions |
Then check, in order: the security group allows port 22 (or 3389 for RDP) from your current IP, which may have changed; the NACL allows both directions; the subnet routes to an internet gateway and the instance has a public or Elastic IP (it changes after stop and start); you are using the right key and username for the AMI (ec2-user, ubuntu, Administrator); and the key file permissions are strict (chmod 400).
Step 3: get in another way. Try Session Manager (needs the SSM Agent and an instance role), EC2 Instance Connect or the EC2 serial console. Look at Get system log and Get instance screenshot in the console for boot errors.
Step 4: the OS is broken. Take a snapshot first, then stop the instance, detach its root volume, attach it to a healthy helper instance as a second disk, fix the files (for example a bad /etc/fstab or network config), and reattach it. The AWSSupport-ExecuteEC2Rescue runbook automates many of these repairs.
Two tools that save time: VPC Reachability Analyzer shows which component blocks a path, and VPC Flow Logs show whether traffic was accepted or rejected. The main message is to work layer by layer and avoid random changes.
Further reading: Troubleshoot EC2 instances
Measure each layer of the request path to see where the time is going, working from the user's view inward, and change nothing until the evidence points to a cause.
1. Define the problem. Is it every user or some? Every page or one? Since when? What changed (a release, a config change, a traffic spike)? Compare against a normal baseline from your dashboards.
2. Start at the load balancer. The ALB metric TargetResponseTime tells you how long your targets take. If it is high, the delay is inside your system and not in the network to the user. If you use CloudFront, check the cache hit ratio, because a drop sends more traffic to your origin.
3. Look at the compute layer.
4. Check the database. It is the most common bottleneck.
DatabaseConnections, read and write latency, IOPS and free memory. On gp2 storage, also check the burst balance.5. Trace across services. AWS X-Ray (or OpenTelemetry) shows the time spent in each hop, including caches and external APIs. CloudWatch Logs Insights can query logs for the slowest requests.
6. Check limits. DynamoDB or API throttling, NAT gateway bandwidth, EBS volume limits and Lambda concurrency limits can all cause slowness that looks like an application problem.
7. Fix, then verify. Choose the fix that matches the evidence: add an index, cache hot reads, scale out, tune a pool, or push slow work to a queue. Then confirm with the same metrics.
Interviewers like a calm, structured approach and the habit of building dashboards and alarms before the incident, so the next investigation is faster.
Further reading: Amazon RDS Performance Insights
Run the whole application in two or more Regions, send each user to the closest healthy Region, and use a database that replicates between Regions. The hard part is data consistency, and the cost is roughly doubled.
The pieces
Trade-offs to discuss
| Topic | Question to ask |
|---|---|
| Consistency | Can the app tolerate slightly stale reads, or conflicting writes in two Regions? |
| Write model | Multi-writer gives the lowest latency but needs conflict handling. Single-writer is simpler, but remote users write more slowly |
| Failover | Automatic or manual? How do you avoid two Regions both believing they are the primary (split brain)? |
| Capacity | Each Region must absorb the other's traffic when it fails |
| Cost | About double the infrastructure, plus cross-Region data transfer |
| Complexity | Deployments, testing and debugging across Regions |
A strong answer ties the design to a real requirement. If the business can accept a few minutes of recovery time, warm standby is much cheaper and simpler. Choose active-active only when users on several continents need low latency, or when a near-zero recovery time and data loss target justifies the cost. Also note that you need to test failover regularly, because an untested failover path often fails when you need it.
Further reading: DynamoDB global tables and Aurora Global Database
Build the controls into the platform so they are enforced and produce evidence automatically: strong identity, encryption, logging, network segmentation, change control and continuous compliance checks, each with a clear owner.
First, understand the split of duties. AWS gives you compliant infrastructure and its own audit reports through AWS Artifact. Under the shared responsibility model, you still have to configure and operate your side. Compliance is about showing that controls exist and keep working over a period, not about a one-day clean-up.
| Control area | What to put in place |
|---|---|
| Identity and access | Central sign-in with IAM Identity Center, MFA everywhere, no long-lived keys, least-privilege roles, regular access reviews, a locked-down root user |
| Encryption | KMS encryption at rest by default for S3, EBS and databases, TLS in transit, key policies and rotation |
| Logging and audit | Organization-wide CloudTrail (with data events where needed) into a protected log-archive account, VPC Flow Logs, AWS Config, Object Lock for tamper-proof logs |
| Network security | Private subnets for data, least-privilege security groups, WAF, no public databases, separate accounts or networks for regulated data (for example cardholder data) |
| Monitoring and response | GuardDuty, Security Hub, alarms and an incident response plan that has actually been practiced |
| Change management | Infrastructure as code, pull request reviews, pipeline deployments, no manual production changes |
| Data protection | Backups with tested restores, retention rules, Macie to find sensitive data, a data classification scheme |
| Vulnerability management | Inspector scans, patching through Systems Manager, a defined time to fix |
Make it continuous.
Process matters as much as tools. Auditors ask for written policies and for proof that people followed them over time, such as access review records, change approvals, restore tests and incident drills.
Two traps: saying "AWS is compliant, so we are compliant", and switching on every security service without anyone owning the findings. A control that nobody reviews does not satisfy an auditor.
Further reading: What is AWS Artifact?
Ingest events into a stream, process them in near real time, land everything in an S3 data lake for history, serve analytics through Athena or Redshift, and protect the data at every step with encryption, tight access and auditing.
The design, step by step
Security and compliance
Resilience and cost. Streams and S3 already span several AZs. Send bad records to a dead-letter location, monitor iterator age and consumer lag, and use on-demand capacity or auto scaling so spikes do not lose data. The main cost drivers are shard hours, the data Athena scans, and keeping old data in hot storage.
The trade-off to name: true real time (seconds) costs more and is harder to run than near real time (minutes). Ask which decisions really need seconds. A simpler Firehose-to-S3 design with Athena may meet the requirement at a fraction of the effort.
Further reading: What is Amazon Data Firehose?
They are based on the questions and topics that come up again and again in AWS interviews and in the objectives of AWS certifications such as Solutions Architect and Developer. Each answer is written from scratch to explain the reasoning interviewers look for, not just the facts.
Limits and recent changes were checked against AWS documentation and announcements in October 2026, including the 50 TB S3 object size, the 1 MiB SQS message size and regional NAT gateways. AWS changes services often, so confirm exact quotas in the Service Quotas console or the current documentation before relying on a number.
Hands-on practice helps a lot, because interviewers often ask follow-up questions based on real experience. Use the AWS Free Tier or a personal sandbox account to try the examples, such as building a VPC with a NAT gateway or an S3 event pipeline.
Start with the easy questions to cover the vocabulary, then spend most of your time on the medium and hard ones, where the reasoning and trade-offs matter. Try answering each question out loud in your own words before reading the answer, and practice sketching the architecture diagrams on paper.