Skip to content

AWS_Practical_Interview_1 100

What it is: run-instances creates an EC2 instance from an AMI with instance type, subnet, security group, key pair and tags.

Why it is used: To start compute on demand and tag instances for tracking and cost attribution.

Terminal window
# AWS CLI
aws ec2 run-instances \
--image-id ami-0c55b159cbfafe1f0 \
--instance-type t2.micro \
--key-name my-key-pair \
--security-group-ids sg-1234567890abcdef0 \
--subnet-id subnet-1234567890abcdef0 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=MyInstance}]'

Key Points:

  • Choose appropriate AMI (Amazon Machine Image)
  • Select instance type based on workload
  • Key pair for SSH access
  • Security group for network access

Interview talking point: “Launching an instance is run-instances with an AMI, instance type, subnet and security group, and always a Name tag, because untagged instances are impossible to track down.”

What it is: SSH into the instance public IP with the private key matching the key pair attached at launch.

Why it is used: To get shell access for administration or debugging; use SSM Session Manager on private instances.

Terminal window
# Linux/Mac
ssh -i "my-key.pem" ec2-user@<public-ip>
# Windows (PuTTY)
# Convert .pem to .ppk using PuTTYgen, then connect
# With verbose for debugging
ssh -vvv -i "my-key.pem" ec2-user@<public-ip>

Key Points:

  • Use correct username (ec2-user, ubuntu, centos, etc.)
  • Ensure security group allows SSH (port 22)
  • Key file must have correct permissions: chmod 400 my-key.pem

Interview talking point: “Plain SSH with -i pointing at the .pem, but the file must be chmod 400 and the username is AMI-specific: ec2-user on Amazon Linux, ubuntu on Ubuntu.”

Q3: Can you attach multiple security groups to an EC2 instance?

Section titled “Q3: Can you attach multiple security groups to an EC2 instance?”

What it is: An instance can have up to five security groups on its ENI; rules from all attached groups combine as a union.

Why it is used: To layer access control, like separate database, app and monitoring groups, instead of one sprawling rule set.

Terminal window
# AWS CLI to add security groups
aws ec2 modify-instance-attribute \
--instance-id i-1234567890abcdef0 \
--groups sg-12345 sg-67890

Interview talking point: “Security groups are additive and allow-only, up to five per ENI. Because the ruleset is a union, a permissive rule in any attached group wins, so sprawl across groups is the real risk.”

What it is: describe-instances and describe-instance-status return lifecycle state plus separate instance and system health checks.

Why it is used: To confirm an instance is actually up and passing reachability, not merely in the running state.

Terminal window
# Describe instance status
aws ec2 describe-instance-status --instance-id i-1234567890abcdef0
# List all instances
aws ec2 describe-instances --filters "Name=instance-state-name,Values=running"
# Check system status and instance status
aws ec2 describe-instance-status \
--instance-id i-1234567890abcdef0 \
--include-all-instances

Interview talking point: “Running only means the VM is powered on. describe-instance-status returns SystemStatus and InstanceStatus separately: system covers network and EBS, instance covers the OS-level agent.”

Q5: How do you stop and start an EC2 instance?

Section titled “Q5: How do you stop and start an EC2 instance?”

What it is: stop-instances shuts an instance down while keeping its EBS volumes and instance ID, so it can start again with data intact.

Why it is used: To save cost on non-production instances during off-hours without losing state or re-provisioning.

Terminal window
# Stop instance
aws ec2 stop-instances --instance-id i-1234567890abcdef0
# Start instance
aws ec2 start-instances --instance-id i-1234567890abcdef0
# Reboot instance
aws ec2 reboot-instances --instance-id i-1234567890abcdef0

Interview talking point: “Stop is not terminate: stop keeps EBS volumes and the instance ID, terminate deletes volumes permanently. After start-instances, re-check the instance type, since it may not honour the original in constrained regions.”

Q6: How do you create an AMI from an EC2 instance?

Section titled “Q6: How do you create an AMI from an EC2 instance?”

What it is: create-image turns a running or stopped instance into an AMI you can launch repeatedly.

Why it is used: To bake tooling, hardening and agents into a golden image so instances start pre-configured.

Terminal window
# Create AMI
aws ec2 create-image \
--instance-id i-1234567890abcdef0 \
--name "My-AMI-$(date +%Y%m%d)" \
--description "Custom AMI with Apache" \
--no-reboot
# List AMIs
aws ec2 describe-images --owners self

Interview talking point: “Use create-image with —no-reboot so a failed package update does not leave a silently broken image, and remember only an AMI you own yourself can be deleted.”

Q7: How do you launch an EC2 instance with user data (bootstrap script)?

Section titled “Q7: How do you launch an EC2 instance with user data (bootstrap script)?”

What it is: User data is a script passed at launch that the instance runs as root, once, on first boot.

Why it is used: To bootstrap a server by installing packages and config without SSH-ing in or baking a custom AMI.

Terminal window
# Launch with user data
aws ec2 run-instances \
--image-id ami-0c55b159cbfafe1f0 \
--instance-type t2.micro \
--key-name my-key \
--security-group-ids sg-12345 \
--subnet-id subnet-12345 \
--user-data file://install-httpd.sh
# Example install-httpd.sh:
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Hello from EC2</h1>" > /var/www/html/index.html

Interview talking point: “—user-data file://script.sh runs once at first boot as root, so it is for idempotent setup only; later runs belong in systemd or SSM. User data is capped at 16 KB, then use an S3 pointer.”

Q8: What is EC2 instance metadata and how do you access it?

Section titled “Q8: What is EC2 instance metadata and how do you access it?”

What it is: IMDS is a link-local service at 169.254.169.254 returning instance ID, AZ, IAM role credentials and user data.

Why it is used: So apps discover their zone and region and fetch role credentials instead of storing keys on disk.

Terminal window
# Get instance metadata
curl http://169.254.169.254/latest/meta-data/
# Get specific metadata
curl http://169.254.169.254/latest/meta-data/instance-id
curl http://169.254.169.254/latest/meta-data/public-ipv4
curl http://169.254.169.254/latest/meta-data/ami-id
# Get user data
curl http://169.254.169.254/latest/user-data/

Interview talking point: “IMDS hands out IAM role credentials, the classic SSRF target. IMDSv2 exists for this: set httpTokens=required and hop limit 1 to break the pivot from an app vulnerability to full role access.”

What it is: Growing an EBS volume is two operations: modify-volume resizes it, then you extend the partition and filesystem inside the guest OS.

Why it is used: To add disk space without downtime or a snapshot-and-copy migration.

Terminal window
# Step 1: Modify volume
aws ec2 modify-volume \
--volume-id vol-1234567890abcdef0 \
--size 50
# Step 2: Check status
aws ec2 describe-volumes-modifications \
--volume-ids vol-1234567890abcdef0
# Step 3: Extend file system (Linux)
sudo growpart /dev/xvda 1
sudo resize2fs /dev/xvda1

Interview talking point: “modify-volume only changes the device size; until you run growpart and resize2fs inside the instance, the filesystem still sees the old size. Shrinking is impossible, and only gp2, gp3 and some storage types grow online.”

Q10: Can you encrypt an existing EBS volume?

Section titled “Q10: Can you encrypt an existing EBS volume?”

What it is: Encryption cannot be added in place; snapshot the volume, copy the snapshot with —encrypted, then create a new volume from the copy.

Why it is used: To bring a legacy volume into compliance with an encryption-at-rest policy.

Method 1: Create encrypted snapshot

Terminal window
# Create snapshot
aws ec2 create-snapshot --volume-id vol-1234567890abcdef0 --description "Backup"
# Copy with encryption
aws ec2 copy-snapshot \
--source-snapshot-id snap-1234567890abcdef0 \
--encrypted \
--description "Encrypted snapshot"
# Create volume from encrypted snapshot
aws ec2 create-volume \
--snapshot-id snap-newencrypted \
--availability-zone us-east-1a \
--encrypted

Method 2: Replace instance with encrypted volume

  1. Stop instance
  2. Create snapshot
  3. Create encrypted snapshot
  4. Create new volume from encrypted snapshot
  5. Attach to instance

Interview talking point: “Encryption cannot be toggled on an existing volume, so the path is snapshot, copy-snapshot —encrypted, then a new volume and reattach. Copy-snapshot creates a new snapshot, so delete the unencrypted original or the compliance finding just moves.”


Q11: What is the difference between Security Group and NACL?

Section titled “Q11: What is the difference between Security Group and NACL?”

What it is: A security group filters traffic at the instance ENI; a network ACL filters at the subnet boundary. SG is stateful and allow-only; NACL is stateless and can deny.

Why it is used: SG for steady-state instance access; NACL for coarse subnet guards like blocking an entire CIDR from a port.

AspectSecurity GroupNACL
LevelInstance/ENISubnet
StatefulYes (return traffic auto-allowed)No (stateless)
RulesAllow onlyAllow and Deny
EvaluationAll rules evaluatedProcessed in order
DefaultDeny all inbound, Allow all outboundAllow all by default

Interview talking point: “Security groups are stateful, so return traffic for an allowed connection is automatically permitted. NACLs are stateless and require explicit inbound and outbound rules, evaluated in rule-number order, and only a NACL can deny.”

Q12: How do you allow HTTP traffic to EC2?

Section titled “Q12: How do you allow HTTP traffic to EC2?”

What it is: Create a security group, then add explicit inbound rules for each port you want to accept.

Why it is used: To open only the ports your service actually needs, rather than everything.

Terminal window
# Create security group
aws ec2 create-security-group \
--group-name web-sg \
--description "Security group for web servers" \
--vpc-id vpc-1234567890abcdef0
# Add inbound rule for HTTP
aws ec2 authorize-security-group-ingress \
--group-id sg-1234567890abcdef0 \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0
# Add HTTPS
aws ec2 authorize-security-group-ingress \
--group-id sg-1234567890abcdef0 \
--protocol tcp \
--port 443 \
--cidr 0.0.0.0/0

Interview talking point: “Create the group, then authorize-security-group-ingress per port; there is no add-all-rules call. Security group rules have no description field, so naming conventions matter once you have more than a handful.”

Q13: How do you allow specific IP access to EC2?

Section titled “Q13: How do you allow specific IP access to EC2?”

What it is: An ingress rule CIDR narrows the source to a specific range instead of the whole internet.

Why it is used: To expose SSH only from your office or bastion range, the highest-value hardening step for an instance.

Terminal window
# Allow specific IP
aws ec2 authorize-security-group-ingress \
--group-id sg-1234567890abcdef0 \
--protocol tcp \
--port 22 \
--cidr 203.0.113.0/24

Interview talking point: “Scoping SSH to a CIDR instead of 0.0.0.0/0 is the most important security group rule you will write. Better still, remove SSH entirely and use SSM Session Manager, so there is no ingress rule to get wrong.”

Q14: How do you allow another security group in security group?

Section titled “Q14: How do you allow another security group in security group?”

What it is: —source-group lets one security group be the allowed source instead of a CIDR, so the rule tracks the group rather than an IP range.

Why it is used: To let a load balancer or app tier reach a database tier without exposing it to the internet.

Terminal window
# Allow traffic from another security group
aws ec2 authorize-security-group-ingress \
--group-id sg-1234567890abcdef0 \
--protocol all \
--source-group sg-othergroup

Interview talking point: “Referencing another security group instead of a CIDR is how you build tiered architectures, since the rule follows the group as the tier scales. It is one-directional, and both groups must be in the same VPC.”

Q15: What is VPC and how do you create one?

Section titled “Q15: What is VPC and how do you create one?”

What it is: A VPC is your own private address space in AWS defined by a CIDR block, containing subnets, route tables and gateways.

Why it is used: As the network boundary for everything you run, where isolation, routing and egress control start.

Terminal window
# Create VPC
aws ec2 create-vpc --cidr-block 10.0.0.0/16
# Enable DNS hostnames
aws ec2 modify-vpc-attribute \
--vpc-id vpc-1234567890abcdef0 \
--enable-dns-hostnames "{\"Value\":true}"
# Enable DNS support
aws ec2 modify-vpc-attribute \
--vpc-id vpc-1234567890abcdef0 \
--enable-dns-support "{\"Value\":true}"

Interview talking point: “create-vpc —cidr-block is the whole call, but do not forget DNS: without enable-dns-hostnames and enable-dns-support you cannot use Route 53 private hosted zones or resolve ELB DNS names.”

What it is: A public subnet is a subnet whose route table sends 0.0.0.0/0 to an Internet Gateway, with map-public-ip-on-launch assigning public IPs.

Why it is used: To host anything directly internet-facing, such as a load balancer, bastion host or NAT gateway.

Terminal window
# Create subnet
aws ec2 create-subnet \
--vpc-id vpc-1234567890abcdef0 \
--cidr-block 10.0.1.0/24 \
--availability-zone us-east-1a
# Enable auto-assign public IP
aws ec2 modify-subnet-attribute \
--subnet-id subnet-1234567890abcdef0 \
--map-public-ip-on-launch
# Create and attach Internet Gateway
aws ec2 create-internet-gateway
aws ec2 attach-internet-gateway \
--internet-gateway-id igw-1234567890abcdef0 \
--vpc-id vpc-1234567890abcdef0
# Create route table and add route
aws ec2 create-route-table --vpc-id vpc-1234567890abcdef0
aws ec2 create-route \
--route-table-id rtb-1234567890abcdef0 \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id igw-1234567890abcdef0

Interview talking point: “Public is not a subnet property but a routing property: the subnet is public because its route table points 0.0.0.0/0 at an Internet Gateway. map-public-ip-on-launch only affects instances launched after you set it.”

What it is: A NAT Gateway is a managed AWS appliance that translates outbound traffic from private subnets, priced per hour plus per GB processed.

Why it is used: To let private subnet instances reach the internet for installs and API calls without being reachable themselves.

Terminal window
# Create Elastic IP
aws ec2 allocate-address --domain vpc
# Create NAT Gateway
aws ec2 create-nat-gateway \
--subnet-id subnet-public-id \
--allocation-id eipalloc-id
# Create route table for private subnet
aws ec2 create-route-table --vpc-id vpc-1234567890abcdef0
aws ec2 create-route \
--route-table-id rtb-private \
--destination-cidr-block 0.0.0.0/0 \
--nat-gateway-id nat-1234567890abcdef0
# Associate route table with private subnet
aws ec2 associate-route-table \
--route-table-id rtb-private \
--subnet-id subnet-private-id

Interview talking point: “A NAT gateway needs an Elastic IP, lives in a public subnet, and the private subnet route table points 0.0.0.0/0 at it; it cannot sit in the private subnet. It bills per GB, so a chatty workload can dominate your spend.”

What it is: A VPC peering connection is a private, non-transitive link between two VPCs that allows private-IP traffic between them.

Why it is used: To connect VPCs across accounts or environments without touching the public internet or routing through NAT.

Terminal window
# Create peering connection
aws ec2 create-vpc-peering-connection \
--vpc-id vpc-1234567890abcdef0 \
--peer-vpc-id vpc-0987654321fedcba0
# Accept peering connection (in peer account)
aws ec2 accept-vpc-peering-connection \
--vpc-peering-connection-id pcx-1234567890abcdef0
# Update route tables (in both VPCs)
aws ec2 create-route \
--route-table-id rtb-1234567890abcdef0 \
--destination-cidr-block 10.1.0.0/16 \
--vpc-peering-connection-id pcx-1234567890abcdef0

Interview talking point: “Peering is private but not transitive, so if A peers with B and B with C, A still cannot reach C, and no routes are added for you. Peered VPCs also cannot have overlapping CIDR ranges.”

Q19: How do you connect to private EC2 without bastion?

Section titled “Q19: How do you connect to private EC2 without bastion?”

What it is: SSM Session Manager gives a shell over the AWS API using the SSM agent, with no SSH key and no inbound port.

Why it is used: To reach private instances without a bastion or port 22, with every session logged for audit.

Terminal window
# Using SSM Session Manager
# Step 1: Install SSM Agent on instance (pre-installed on Amazon Linux 2)
# Step 2: Attach IAM role with SSM permissions
aws ec2 associate-iam-instance-profile \
--instance-id i-1234567890abcdef0 \
--iam-instance-profile Name=SSM-Role
# Step 3: Start session
aws ssm start-session --target i-1234567890abcdef0
# Or use AWS Console → Systems Manager → Session Manager

Interview talking point: “The instance needs the SSM agent running and an IAM role attached; without the role, Session Manager cannot connect. It needs no inbound rule at all and sessions are auditable, which is why it beats SSH in production.”

Q20: What is the difference between NAT Gateway and NAT Instance?

Section titled “Q20: What is the difference between NAT Gateway and NAT Instance?”

What it is: A NAT Gateway is a managed AWS service priced per hour plus per GB; a NAT Instance is an EC2 instance you run yourself.

Why it is used: Both give private subnets outbound internet access; the difference is who patches, scales and operates the appliance.

AspectNAT GatewayNAT Instance
Managed by AWSYesNo (you manage)
AvailabilityHigh availability (multiple AZs)Single instance
PerformanceUp to 45 GbpsDepends on instance type
CostPer hour + data processingPer hour + data processing
MaintenanceAWS handlesYou handle updates

Interview talking point: “NAT Gateway is managed and highly available across AZs up to 45 Gbps, but has a hard 32 Gbps per direction limit and bills per GB. A NAT instance is cheaper small-scale but single-AZ and you patch it yourself.”


What it is: aws s3 cp copies a local file or directory into a bucket; —recursive walks a folder and —sse sets encryption on the way in.

Why it is used: To get data into S3 from a build, a backup job, or a one-off laptop upload.

Terminal window
# Simple upload
aws s3 cp myfile.txt s3://my-bucket/
# Upload with specific permissions
aws s3 cp myfile.txt s3://my-bucket/ --acl private
# Upload recursively
aws s3 cp ./folder s3://my-bucket/ --recursive
# Upload with encryption
aws s3 cp myfile.txt s3://my-bucket/ --sse AES256

Interview talking point: “aws s3 cp local s3://bucket/key is the whole story, with —recursive for folders and —sse AES256 for encryption at rest. For automation, prefer aws s3 sync so re-runs skip unchanged files.”

What it is: Making a bucket public requires turning off all Block Public Access settings and adding a bucket policy allowing s3:GetObject to any principal. Both are required.

Why it is used: Only for genuinely public assets; use presigned URLs or CloudFront with Origin Access Control for private content.

Terminal window
# Disable block public access
aws s3api put-public-access-block \
--bucket my-bucket \
--public-access-block-configuration "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false"
# Add bucket policy for public read
aws s3api put-bucket-policy \
--bucket my-bucket \
--policy '{
"Version": "2012-10-17",
"Statement": [{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}]
}'

Interview talking point: “Public access needs two changes, not one: the four put-public-access-block flags and a bucket policy. An ACL-enabled bucket can still grant public access, so set ObjectOwnership=BucketOwnerEnforced to close that second path.”

What it is: Versioning keeps every version of an object with a version ID, so an accidental overwrite or delete can be rolled back.

Why it is used: To recover from accidental deletion or corruption, and as a prerequisite for replication and object-lock compliance.

Terminal window
# Enable versioning
aws s3api put-bucket-versioning \
--bucket my-bucket \
--versioning-configuration Status=Enabled
# Enable MFA delete (requires MFA)
aws s3api put-bucket-versioning \
--bucket my-bucket \
--versioning-configuration Status=Enabled,MFADelete=Enabled \
--mfa "ARN-OF-MFA-DELETE count-of-mfa-code"

Interview talking point: “Enabling versioning is one-way; you can suspend it but never return to unversioned. While it is on, deletes only insert a marker, so every version is billed until a lifecycle rule expires noncurrent versions.”

Q24: How do you set up S3 lifecycle policy?

Section titled “Q24: How do you set up S3 lifecycle policy?”

What it is: A lifecycle configuration moves objects between storage classes and eventually expires them, based on age or object size.

Why it is used: To cut S3 cost and satisfy retention rules automatically instead of writing scheduled scripts.

Terminal window
# Create lifecycle configuration
aws s3api put-bucket-lifecycle-configuration \
--bucket my-bucket \
--lifecycle-configuration '{
"Rules": [
{
"ID": "Move to IA after 30 days",
"Status": "Enabled",
"Transitions": [
{
"Days": 30,
"StorageClass": "STANDARD_IA"
},
{
"Days": 90,
"StorageClass": "GLACIER"
},
{
"Days": 365,
"StorageClass": "DEEP_ARCHIVE"
}
]
},
{
"ID": "Delete after 7 years",
"Status": "Enabled",
"Expiration": {
"Days": 2555
}
}
]
}'

Interview talking point: “Transitioning to STANDARD_IA after 30 days only pays off if objects are read often enough, since IA has a per-object minimum and a retrieval fee. The classic mistake is forgetting to expire noncurrent versions behind versioning.”

What it is: S3 Replication copies objects to another bucket, typically in a different region, asynchronously in the background.

Why it is used: For cross-region disaster recovery, data-residency compliance, or a copy outside one region blast radius.

Terminal window
# Enable versioning on both buckets
aws s3api put-bucket-versioning --bucket source-bucket --versioning-configuration Status=Enabled
aws s3api put-bucket-versioning --bucket dest-bucket --versioning-configuration Status=Enabled
# Create IAM role for replication
aws iam create-role --role-name S3-Replication-Role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "s3.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
# Add replication policy to role (attach policy)
aws iam put-role-policy --role-name S3-Replication-Role \
--policy-name Replication-Policy \
--policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:GetObjectVersion", "s3:GetObjectVersionAcl"],
"Resource": "arn:aws:s3:::source-bucket/*"
},
{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:PutObjectAcl"],
"Resource": "arn:aws:s3:::dest-bucket/*"
}]
}'
# Enable replication on source bucket
aws s3api put-bucket-replication \
--bucket source-bucket \
--replication-configuration '{
"Role": "arn:aws:iam::123456789012:role/S3-Replication-Role",
"Rules": [{
"ID": "ReplicateAll",
"Status": "Enabled",
"Destination": {
"Bucket": "arn:aws:s3:::dest-bucket"
}
}]
}'

Interview talking point: “Replication is asynchronous and needs versioning on both buckets plus an IAM role that S3 assumes. Delete markers are not replicated unless you enable DeleteMarkerReplication, and existing source objects are not backfilled without a one-off replication job.”

What it is: aws s3 ls —recursive —summarize totals objects and bytes by walking the bucket; CloudWatch BucketSizeBytes gives a free daily metric.

Why it is used: To check bucket size for cost, capacity planning, or a migration estimate.

Terminal window
# Using S3 CLI
aws s3 ls s3://my-bucket --recursive --summarize
# Output shows:
# Total Objects: 1000
# Total Size: 123.45 GB
# Using CloudWatch
aws cloudwatch get-metric-statistics \
--namespace AWS/S3 \
--metric-name BucketSizeBytes \
--start-time 2024-01-01T00:00:00Z \
--end-time 2024-01-02T00:00:00Z \
--period 86400 \
--statistics Average \
--dimensions Name=BucketName,Value=my-bucket

Interview talking point: “s3 ls —recursive —summarize is a LIST of every object, so on millions of objects it will time out. Use the CloudWatch BucketSizeBytes daily metric instead; it is free but delayed up to 48 hours.”

What it is: put-bucket-encryption sets default server-side encryption for every new object, either SSE-S3 with AES256 or SSE-KMS with aws:kms.

Why it is used: To guarantee data is encrypted at rest even if a client forgets to send an encryption header.

Terminal window
# Enable default encryption with KMS
aws s3api put-bucket-encryption \
--bucket my-bucket \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}]
}'
# Or with KMS key
aws s3api put-bucket-encryption \
--bucket my-bucket \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSKeyId": "arn:aws:kms:us-east-1:123456789012:key/key-id"
}
}]
}'

Interview talking point: “put-bucket-encryption is a bucket default, not enforcement on existing objects, and it does not stop a client sending a different SSE header; that needs a bucket policy. AES256 is free, while aws:kms costs a key API call per object unless you enable a bucket key.”

Q28: How do you set up static website hosting on S3?

Section titled “Q28: How do you set up static website hosting on S3?”

What it is: S3 static website hosting serves a bucket as a site using index and error documents at the s3-website endpoint rather than the REST endpoint.

Why it is used: For cheap static hosting of a frontend or documentation site with no server behind it.

Terminal window
# Enable static website hosting
aws s3 website s3://my-bucket \
--index-document index.html \
--error-document error.html
# Set bucket policy for public access (after unblocking public access)
aws s3api put-bucket-policy \
--bucket my-bucket \
--policy '{
"Version": "2012-10-17",
"Statement": [{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}]
}'
# Website URL format:
# http://my-bucket.s3-website-us-east-1.amazonaws.com

Interview talking point: “aws s3 website configures the site, but the website endpoint only supports GET and PUT with no listing, does not work with ObjectOwnership set to BucketOwnerEnforced, and is HTTP-only, so put CloudFront in front for HTTPS.”

Q29: How do you generate S3 presigned URL?

Section titled “Q29: How do you generate S3 presigned URL?”

What it is: A presigned URL is a temporary signed link granting one operation on one object for a bounded time, without exposing credentials.

Why it is used: To hand a user time-limited access to a file as a download link or upload target without an IAM user.

Terminal window
# Generate presigned URL for download (valid for 1 hour)
aws s3 presign s3://my-bucket/myfile.txt --expires-in 3600
# Using Python boto3
import boto3
s3 = boto3.client('s3')
url = s3.generate_presigned_url(
'get_object',
Params={'Bucket': 'my-bucket', 'Key': 'myfile.txt'},
ExpiresIn=3600
)
# For upload
url = s3.generate_presigned_url(
'put_object',
Params={'Bucket': 'my-bucket', 'Key': 'myfile.txt'},
ExpiresIn=3600
)

Interview talking point: “aws s3 presign s3://bucket/key —expires-in 3600 gives a temporary link, but the embedded credential is the caller’s, so it dies when you revoke that user or rotate the key. Never generate one for ListBucket, which hands over the whole bucket.”

What it is: Server access logging writes every S3 request to objects in a separate logging bucket.

Why it is used: For audit trails and investigating who accessed which object and from where.

Terminal window
# Create logging bucket
aws s3 mb s3://access-logs-bucket
# Grant log delivery permission
aws s3api put-bucket-acl \
--bucket my-bucket \
--grant-write URI=http://acs.amazonaws.com/groups/s3/LogDelivery \
--grant-read-acp URI=http://acs.amazonaws.com/groups/s3/LogDelivery
# Enable logging
aws s3api put-bucket-logging \
--bucket my-bucket \
--bucket-logging-status '{
"LoggingEnabled": {
"TargetBucket": "access-logs-bucket",
"TargetPrefix": "logs/"
}
}'

Interview talking point: “Access logging gives object-level GETs, while CloudTrail gives API calls; they are not interchangeable. The logs land in a different bucket that needs its own lifecycle, or you have moved the storage cost rather than solved it.”


What it is: An IAM user is a long-term identity with its own credentials, made of a user, optional access keys and attached policies.

Why it is used: Historically for people and CI with fixed credentials, though roles with temporary credentials are now preferred.

Terminal window
# Create IAM user
aws iam create-user --user-name john
# Create access key
aws iam create-access-key --user-name john
# Attach policy
aws iam attach-user-policy \
--user-name john \
--policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

Interview talking point: “The three steps are create-user, create-access-key, then attach-user-policy. The real point is that IAM users are long-lived credentials you rotate forever, which is why the modern answer is a role with temporary STS credentials.”

What it is: An IAM role is an identity with no stored credentials; principals assume it for temporary credentials, and its trust policy decides who may assume it.

Why it is used: To give EC2, Lambda or ECS tasks permissions to call AWS APIs with credentials that expire automatically.

Terminal window
# Create role with trust policy
aws iam create-role \
--role-name EC2-S3-Role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
# Attach policy
aws iam attach-role-policy \
--role-name EC2-S3-Role \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
# Create instance profile
aws iam create-instance-profile --instance-profile-name EC2-S3-Role
# Add role to instance profile
aws iam add-role-to-instance-profile \
--instance-profile-name EC2-S3-Role \
--role-name EC2-S3-Role
# Attach to EC2
aws ec2 associate-iam-instance-profile \
--instance-id i-1234567890abcdef0 \
--iam-instance-profile Name=EC2-S3-Role

Interview talking point: “The three-part shape is a trust policy for who may assume it, permissions policies for what it may do, and for EC2 an instance profile wrapper that associate-iam-instance-profile attaches. Miss the instance profile and the instance silently has no role.”

Q33: How do you enable MFA on root account?

Section titled “Q33: How do you enable MFA on root account?”

What it is: MFA on root requires enrolling a virtual MFA device with IAM and activating it with two consecutive codes.

Why it is used: Because root cannot be limited by IAM policy or SCP, MFA is the most important account-level control.

Terminal window
# List virtual MFA devices
aws iam list-mfa-devices --user-name root
# Enable MFA (requires ARN of MFA device)
aws iam enable-mfa-device \
--user-name root \
--serial-number arn:aws:iam::123456789012:mfa/root \
--authentication-code1 123456 \
--authentication-code2 789012

Interview talking point: “Nothing in IAM can constrain root, so if root credentials leak, MFA is the only thing standing between an attacker and the account. Enrol with list-mfa-devices, then enable-mfa-device using two different consecutive codes.”

What it is: An IAM policy is a JSON document of statements with Effect, Action, Resource and optionally Condition; customer-managed policies are versioned and attachable.

Why it is used: To define exactly what a principal may do, as narrowly as possible, rather than reusing a broad managed policy.

Terminal window
# Create policy
aws iam create-policy \
--policy-name S3-Webapp-Policy \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-webapp-bucket/*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::my-webapp-bucket"
}
]
}'

Interview talking point: “The split people get wrong is s3:ListBucket on the bucket ARN versus s3:GetObject on the bucket ARN plus /*. You need both, and they are different resources.”

Q35: What is the difference between IAM Policy and Resource Policy?

Section titled “Q35: What is the difference between IAM Policy and Resource Policy?”

What it is: An IAM policy attaches to a principal and is evaluated against what that principal does; a resource policy attaches to a resource and evaluates who is accessing it.

Why it is used: Knowing which to write, and that an explicit Deny in either wins over any Allow from the other.

AspectIAM PolicyResource Policy
AttachmentTo users, groups, rolesTo resources (S3, Lambda)
Who definesIAM adminResource owner
PrincipalMust specifyCan use wildcard
EvaluationBoth can allowOnly one can deny

Interview talking point: “IAM policy is identity-side, resource policy is resource-side, and access requires an Allow from both, but an explicit Deny in either wins outright. Cross-account access needs a resource policy naming the other account ARN.”

What it is: The policy simulator evaluates a policy against hypothetical actions, resources and conditions, returning whether each is allowed, including implicit denies.

Why it is used: To debug why a principal is getting AccessDenied, and to test a policy before attaching it.

Terminal window
# Test policy
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/john \
--action-names s3:GetObject \
--resource-arns arn:aws:s3:::my-bucket/myfile.txt

Interview talking point: “simulate-principal-policy explains an AccessDenied and shows the explicit-deny statements responsible, but it ignores SCPs and permission boundaries that also apply at runtime, so a clean simulation can still be denied in practice.”

Q37: How do you set up cross-account access?

Section titled “Q37: How do you set up cross-account access?”

What it is: Cross-account access works by creating a role in the target account whose trust policy names the source account principal, then assuming it.

Why it is used: For a central security or shared-services account to manage member accounts, or CI in one account deploying to another.

Terminal window
# Account A (owner): Create role with trust policy
aws iam create-role \
--name CrossAccount-Role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789012:user/admin"},
"Action": "sts:AssumeRole"
}]
}'
# Account B (user): Assume role
aws sts assume-role \
--role-arn arn:aws:iam::111111111111:role/CrossAccount-Role \
--role-session-name cross-account-session

Interview talking point: “The trust policy lives in the account that owns the role, and you need both halves: the trust naming the caller ARN plus sts:AssumeRole on the caller side. Add ExternalId, or this pattern is a confused-deputy hole.”

What it is: Key rotation is create-new, deploy, deactivate-old, delete-old; access keys are long-lived, so rotation stays manual unless automated.

Why it is used: To limit the damage window if a key leaks and to satisfy credential-age compliance requirements.

Terminal window
# Create new access key
aws iam create-access-key --user-name john
# Update configuration with new key
# List access keys
aws iam list-access-keys --user-name john
# Deactivate old key
aws iam update-access-key \
--access-key-id AKIAIOSFODNN7EXAMPLE \
--status Inactive \
--user-name john
# Delete old key after confirming
aws iam delete-access-key \
--access-key-id AKIAIOSFODNN7EXAMPLE \
--user-name john

Interview talking point: “Rotation is create-access-key, update the consumer, update-access-key —status Inactive, then delete; a key cannot be deleted before deactivation. The real answer for anything in AWS is to drop static keys for a role with temporary credentials.”

Q39: How do you set up AWS Secrets Manager?

Section titled “Q39: How do you set up AWS Secrets Manager?”

What it is: Secrets Manager stores and rotates credentials with envelope encryption using a KMS key, with native rotation for RDS and Redshift.

Why it is used: To stop credentials living in code, CI variables and Terraform state, and to get automatic rotation.

Terminal window
# Create secret
aws secretsmanager create-secret \
--name prod/db_credentials \
--secret-string '{"username":"admin","password":"secret123"}'
# Get secret value
aws secretsmanager get-secret-value \
--secret-id prod/db_credentials
# Rotate secret (rotation lambda supplied with --lambda-function-name)
aws secretsmanager rotate-secret \
--secret-id prod/db_credentials \
--lambda-function-name arn:aws:lambda:us-east-1:123456789012:function:rotation-function
# rotate-secret does NOT accept --rotation-lambda-arn:
# An error occurred (ValidationException): 1 validation error detected:
# Value 'arn:...' at 'rotationLambdaArn' failed to satisfy constraint

Interview talking point: “Rotation uses rotate-secret —lambda-function-name; the flag —rotation-lambda-arn is not accepted and fails ValidationException. You also need a four-step Lambda for create, describe, update and test, and the master secret must be JSON or RDS credentials.”

What it is: KMS manages keys you create and control, while KMS performs envelope encryption of the data itself.

Why it is used: When you need to control, audit or revoke access to the encryption key itself, not just the service default.

Terminal window
# Create KMS key
aws kms create-key \
--description "My encryption key" \
--key-usage ENCRYPT_DECRYPT
# Create alias
aws kms create-alias \
--alias-name alias/my-key \
--target-key-id key-id
# Encrypt data
aws kms encrypt \
--key-id alias/my-key \
--plaintext "Hello World" \
--output text --query CiphertextBlob | base64 -d > encrypted.txt
# Decrypt data
aws kms decrypt \
--ciphertext-blob fileb://encrypted.txt \
--output text --query Plaintext | base64 -d

Interview talking point: “Use create-key then create-alias, and always reference the alias rather than the raw key ID. KMS charges per API call, so millions of objects need bucket keys, and both the key policy and IAM must allow the operation.”


What it is: create-db-instance provisions a managed relational database with engine, instance class, storage, subnet group and security groups.

Why it is used: To get a database AWS patches, backs up and fails over, instead of running one on EC2 yourself.

Terminal window
# Create RDS instance (MySQL)
aws rds create-db-instance \
--db-instance-identifier mydb \
--db-instance-class db.t3.micro \
--engine mysql \
--allocated-storage 20 \
--master-username admin \
--master-user-password mypassword123 \
--vpc-security-group-ids sg-12345 \
--db-subnet-group-name my-subnet-group

Interview talking point: “Two defaults bite: the default subnet group leaves the database unreachable, and omitting —storage-type gives gp2 with no —iops option. The password on the command line lands in shell history, so use —manage-master-user-password.”

What it is: The DB instance endpoint hostname comes from describe-db-instances rather than something you build yourself.

Why it is used: To connect a client to the database and to verify its VPC and security group before trying.

Terminal window
# Get endpoint
aws rds describe-db-instances \
--db-instance-identifier mydb \
--query 'DBInstances[0].Endpoint.Address'
# Connect using MySQL client
mysql -h mydb.xxxx.us-east-1.rds.amazonaws.com \
-u admin -p mydatabase

Interview talking point: “Read the endpoint from describe-db-instances instead of constructing it, since the random middle component of the hostname is unpredictable. If a connection hangs rather than refusing, it is almost always the security group or subnet group, not credentials.”

What it is: Multi-AZ stands up a synchronous standby copy in a second AZ and fails over automatically, typically with an RTO under a minute.

Why it is used: For databases where a few minutes of downtime is unacceptable and AZ failure must not lose data.

Terminal window
# Modify DB instance for Multi-AZ
aws rds modify-db-instance \
--db-instance-identifier mydb \
--multi-az \
--apply-immediately
# Check status
aws rds describe-db-instances \
--db-instance-identifier mydb \
--query 'DBInstances[0].MultiAZ'

Interview talking point: “modify-db-instance —multi-az —apply-immediately is the command, but the standby is not queryable, so it is pure availability insurance rather than read scaling, and you can only enable it on the writer.”

What it is: A read replica is an asynchronously replicated copy of the primary in another AZ or region, readable but never writable.

Why it is used: To offload read traffic from the primary and to have a fast-promotable copy for regional failover.

Terminal window
# Create read replica
aws rds create-db-instance-read-replica \
--db-instance-identifier mydb-replica \
--source-db-instance-identifier mydb \
--db-instance-class db.t3.micro
# Promote to standalone (if needed)
aws rds promote-read-replica \
--db-instance-identifier mydb-replica

Interview talking point: “A read replica is async, so it can lag and promotion loses writes in flight, which makes it read scaling and disaster recovery, not high availability. promote-read-replica is one-way and permanently removes the replica from the chain.”

What it is: Snapshots are manual or automated full backups you restore into a new instance; point-in-time restore replays the transaction log to any second in the window.

Why it is used: For recovery from corruption, bad deploys or accidental deletion, and for compliance retention requirements.

Terminal window
# Create manual snapshot
aws rds create-db-snapshot \
--db-instance-identifier mydb \
--db-snapshot-identifier mydb-backup
# Restore from snapshot
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier mydb-restored \
--db-snapshot-identifier mydb-backup
# Point-in-time restore
aws rds restore-db-instance-to-point-in-time \
--source-db-instance-identifier mydb \
--target-db-instance-identifier mydb-pitr \
--restore-time 2024-01-15T12:00:00Z

Interview talking point: “create-db-snapshot and restore-db-instance-from-db-snapshot cover the manual path, while restore-db-instance-to-point-in-time reaches any second in the window. You always restore into a new instance identifier, so nothing rolls back in place.”

What it is: A DynamoDB table is schemaless; you declare only the attributes used as primary keys, plus optional secondary indexes, and pay for capacity or on-demand.

Why it is used: For key-value and document workloads needing single-digit millisecond latency and predictable cost without a database server.

Terminal window
# Create DynamoDB table
aws dynamodb create-table \
--table-name Users \
--attribute-definitions \
AttributeName=UserID,AttributeType=N \
AttributeName=Email,AttributeType=S \
--key-schema \
AttributeName=UserID,KeyType=HASH \
--global-secondary-indexes '[{
"IndexName": "EmailIndex",
"KeySchema": [{"AttributeName":"Email","KeyType":"HASH"}],
"Projection":{"ProjectionType":"ALL"},
"ProvisionedThroughput":{"ReadCapacityUnits":5,"WriteCapacityUnits":5}
}]' \
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5

Interview talking point: “Only attributes in key schemas belong in —attribute-definitions; declaring a non-key attribute there fails the call. Provisioned throughput must also be set on the table and every GSI, which breaks most first attempts.”

What it is: get-item reads by primary key, query reads by partition key with optional sort-key conditions, and scan reads the whole table.

Why it is used: query and get-item for application traffic; scan only for admin tasks on small tables.

Terminal window
# Get item by key
aws dynamodb get-item \
--table-name Users \
--key '{"UserID": {"N": "1"}}'
# Query with key condition
aws dynamodb query \
--table-name Users \
--key-condition-expression "UserID = :uid" \
--expression-attribute-values '{":uid": {"N": "1"}}'
# Scan (not recommended for large tables)
aws dynamodb scan \
--table-name Users \
--filter-expression "Age > :age" \
--expression-attribute-values '{":age": {"N": "25"}}'

Interview talking point: “scan walks every item and burns read capacity, so anything landing in production code is a bug. Use an index to query a different attribute, but GSIs do not support consistent reads, so read-after-write on an index is not guaranteed.”

Q48: How do you enable DynamoDB auto scaling?

Section titled “Q48: How do you enable DynamoDB auto scaling?”

What it is: Application Auto Scaling is the separate service that adjusts DynamoDB provisioned read and write capacity to hold utilisation at a target.

Why it is used: To avoid hand-tuning capacity without paying full on-demand price for unpredictable traffic.

Terminal window
# Create scaling target
aws application-autoscaling put-scaling-target \
--resource-id table/Users \
--scalable-dimension dynamodb:table:WriteCapacityUnits \
--min-capacity 1 \
--max-capacity 10
# Create scaling policy
aws application-autoscaling put-scaling-policy \
--policy-name users-write-scaling \
--resource-id table/Users \
--scalable-dimension dynamodb:table:WriteCapacityUnits \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration '{
"PredefinedMetricSpecification": {
"PredefinedMetricType": "DynamoDBWriteCapacityUtilization"
},
"TargetValue": 70.0
}'

Interview talking point: “The two-step shape is put-scaling-target then put-scaling-policy with TargetTrackingScaling, using a table/ resource id. The console has a toggle, but through the API you must register the scalable dimension explicitly first.”


What it is: create-function deploys a zipped package with a runtime, execution role, handler, and its memory and timeout limits.

Why it is used: To run a small piece of code in response to events without managing any servers.

Terminal window
# Create function
aws lambda create-function \
--function-name my-function \
--runtime python3.9 \
--role arn:aws:iam::123456789012:role/lambda-role \
--handler index.lambda_handler \
--zip-file fileb://function.zip \
--timeout 30 \
--memory-size 128

Interview talking point: “The zip, the handler matching your file and function name, the role and the runtime must all be right. —zip-file fileb:// must point at the zip, not the folder, and binary payloads on older CLIs need —cli-binary-format.”

What it is: lambda invoke sends an event payload and writes the function return value to a file you name.

Why it is used: To test a function and inspect its output, or to wire CLI-driven automation to it.

Terminal window
# Invoke directly
aws lambda invoke \
--function-name my-function \
--payload '{"key": "value"}' \
response.json
# Invoke with CLI (using --cli-binary-format)
aws lambda invoke \
--function-name my-function \
--payload '{"name": "World"}' \
--log-type Tail \
response.json
# Check logs
cat response.json

Interview talking point: “aws lambda invoke requires the output file as a positional argument, which people forget, and —log-type Tail returns the last 4 KB of logs. The CLI validates the payload as JSON unless you pass —cli-binary-format raw-in-base64-out, so binary events get rejected.”

Q51: How do you set up Lambda trigger from S3?

Section titled “Q51: How do you set up Lambda trigger from S3?”

What it is: S3 event notification that makes S3 invoke a Lambda whenever a matching object is created or removed.

Why it is used: Builds event-driven pipelines like thumbnailing or ETL on upload, with no polling.

Terminal window
# Add S3 event notification
aws s3api put-bucket-notification-configuration \
--bucket my-bucket \
--notification-configuration '{
"LambdaFunctionConfigurations": [{
"Id": "my-trigger",
"LambdaFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
"Events": ["s3:ObjectCreated:*"]
}]
}'

Interview talking point: “put-bucket-notification-configuration also needs a Lambda resource permission, or S3 silently refuses to save the config. The trigger fires on PUT and multipart copy, but a Glacier restore or replication copy does not fire it.”

Q52: How do you configure Lambda VPC access?

Section titled “Q52: How do you configure Lambda VPC access?”

What it is: VPC configuration that places the Lambda execution environment inside your VPC, with ENIs in your chosen subnets.

Why it is used: Lets the function reach private resources like RDS, Redis or an internal API.

Terminal window
# Update function VPC config
aws lambda update-function-configuration \
--function-name my-function \
--vpc-config SubnetIds=subnet-12345,subnet-67890 \
--security-group-ids sg-12345

Interview talking point: “The flag is —vpc-config SubnetIds=…,SecurityGroupIds=… with commas, since both lists live in one string. The function loses internet access without NAT or VPC endpoints, and DNS needs enableDnsHostnames and enableDnsSupport on the VPC.”

What it is: A zip of shared dependencies published as an immutable numbered version and attached to functions by ARN.

Why it is used: Stops every function bundling its own library copy and lets you update it across functions at once.

Terminal window
# Create layer
aws lambda publish-layer-version \
--layer-name my-layer \
--description "My Python dependencies" \
--zip-file fileb://layer.zip \
--compatible-runtimes python3.9
# Add to function
aws lambda update-function-configuration \
--function-name my-function \
--layers arn:aws:lambda:us-east-1:123456789012:layer:my-layer:1

Interview talking point: “Layers are immutable and versioned: publish-layer-version creates version 2, 3, 4, so you must publish a new version and repoint the function. Layers only affect the runtime path, not container images, and packaging paths like python/lib must match exactly or imports fail.”

Q54: How do you set up API Gateway with Lambda?

Section titled “Q54: How do you set up API Gateway with Lambda?”

What it is: Imperatively built REST API: create resources, methods and integrations, then deploy everything to a stage.

Why it is used: Fronts a Lambda as an HTTP endpoint with throttling, authentication and logging handled for you.

Terminal window
# Create REST API
aws apigateway create-rest-api \
--name my-api
# Get resources and root ID
aws apigateway get-resources --rest-api-id api-id
# Create resource
aws apigateway create-resource \
--rest-api-id api-id \
--parent-id root-id \
--path-part hello
# Create method
aws apigateway put-method \
--rest-api-id api-id \
--resource-id resource-id \
--http-method GET \
--authorization-type NONE
# Create integration with Lambda
aws apigateway put-integration \
--rest-api-id api-id \
--resource-id resource-id \
--http-method GET \
--type AWS \
--integration-http-method POST \
--uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:my-function/invocations
# Deploy API
aws apigateway create-deployment \
--rest-api-id api-id \
--stage-name prod

Interview talking point: “The order is create-rest-api, create-resource (root ID comes from get-resources), put-method, put-integration, create-deployment. Nothing is live until you deploy, and edits are not live until you deploy again, which is why people think their change failed.”

Q55: How do you configure Lambda environment variables?

Section titled “Q55: How do you configure Lambda environment variables?”

What it is: Key-value pairs injected into the function’s execution environment and read by the code at runtime.

Why it is used: Passes configuration that changes without a code deploy, but never secrets, which belong in Secrets Manager.

Terminal window
# Set environment variables
aws lambda update-function-configuration \
--function-name my-function \
--environment Variables='{DB_HOST="mydb.xxx.rds.amazonaws.com","DB_NAME":"mydb"}'
# View environment variables
aws lambda get-function-configuration \
--function-name my-function \
--query Environment

Interview talking point: “update-function-configuration —environment Variables=’{…}’ replaces the whole map rather than merging it, so an omitted key is deleted. Values are plaintext to anyone with lambda:GetFunctionConfiguration, which is exactly why secrets are referenced from Secrets Manager at runtime.”

Q56: How do you set up Lambda dead letter queue?

Section titled “Q56: How do you set up Lambda dead letter queue?”

What it is: A queue that captures the original event of any invocation failing after Lambda has exhausted its retries.

Why it is used: Stops failed events being silently lost so they can be inspected, replayed or rerouted.

Terminal window
# Configure DLQ
aws lambda update-function-configuration \
--function-name my-function \
--dead-letter-config TargetArn=arn:aws:sqs:us-east-1:123456789012:my-dlq

Interview talking point: “—dead-letter-config TargetArn=… points at SQS or SNS. Lambda retries twice with exponential backoff first, so events arrive seconds later, not instantly, and recurring failures make DLQ queue depth a good alert signal.”


What it is: Evaluates a metric statistic over a period and, after N breaching evaluation periods, moves to ALARM and runs actions.

Why it is used: Turns raw metrics into paging notifications and Auto Scaling triggers.

Terminal window
# Create alarm
aws cloudwatch put-metric-alarm \
--alarm-name cpu-high-alarm \
--alarm-description "Alarm when CPU exceeds 80%" \
--metric-name CPUUtilization \
--namespace AWS/EC2 \
--statistic Average \
--period 300 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:us-east-1:123456789012:my-topic

Interview talking point: “Period times evaluation-periods is your detection window, and that interaction is the most misunderstood part. Also set treat-missing-data to notBreaching, or an idle fleet pages you at 3am.”

Q58: How do you create CloudWatch dashboard?

Section titled “Q58: How do you create CloudWatch dashboard?”

What it is: A saved JSON layout of metric widgets, viewable in the console and usable as an on-call front page.

Why it is used: Gives a team one shared screen of the metrics that matter instead of personal graphs.

Terminal window
# Create dashboard
aws cloudwatch put-dashboard \
--dashboard-name my-dashboard \
--dashboard-body '{
"widgets": [{
"type": "metric",
"properties": {
"title": "EC2 CPU",
"metrics": [
["AWS/EC2", "CPUUtilization", "InstanceId", "i-1234567890abcdef0"]
],
"period": 300,
"stat": "Average"
}
}]
}'

Interview talking point: “put-dashboard takes a —dashboard-body JSON of widgets, with metric tuples like [namespace, metricName, key1, val1]. You can only put, so changing a dashboard means replacing the entire body.”

Q59: How do you create CloudWatch log subscription?

Section titled “Q59: How do you create CloudWatch log subscription?”

What it is: A filter that streams matching log events from a log group to a Lambda, Kinesis stream or another log group.

Why it is used: Builds real-time alerting or parsing over log data that is expensive to query later.

Terminal window
# Create log group
aws logs create-log-group --log-group-name /aws/lambda/my-function
# Create filter
aws logs put-subscription-filter \
--log-group-name /aws/lambda/my-function \
--filter-name my-filter \
--filter-pattern "{ $.level = \"Error\" }" \
--destination-arn arn:aws:lambda:us-east-1:123456789012:function:my-processor

Interview talking point: “put-subscription-filter needs a filter pattern and a destination ARN, and a Lambda destination requires a resource policy granting logs.amazonaws.com or events are dropped silently. Filter patterns are a limited JSON-aware language, not JMESPath.”

What it is: A trail that writes API calls to S3; Event History needs no setup but retains only 90 days.

Why it is used: Provides audit, forensics and compliance evidence of who changed what, from where and when.

Terminal window
# Create trail
aws cloudtrail create-trail \
--name my-trail \
--s3-bucket-name my-cloudtrail-bucket \
--is-multi-region-trail
# Start logging
aws cloudtrail start-logging --name my-trail
# Look up events
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventSource,AttributeValue=ec2.amazonaws.com

Interview talking point: “Two enablement steps: create the trail and call start-logging, since creating alone does nothing. lookup-events reaches only 90 days and cannot filter by resource name, so use Logs Insights or Athena over the S3 objects.”


Q61: How do you create Auto Scaling group?

Section titled “Q61: How do you create Auto Scaling group?”

What it is: Defines a launch template, min, max and desired capacity plus subnets, then launches and terminates instances to hold capacity.

Why it is used: Keeps a fleet at a target size and does the actual scaling on load or health.

Terminal window
# Create launch template
aws ec2 create-launch-template \
--launch-template-name my-template \
--launch-template-data '{
"ImageId": "ami-0c55b159cbfafe1f0",
"InstanceType": "t3.micro",
"KeyName": "my-key",
"SecurityGroupIds": ["sg-12345"]
}'
# Create ASG
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name my-asg \
--launch-template LaunchTemplateId=lt-12345 \
--min-size 2 \
--max-size 10 \
--desired-capacity 2 \
--vpc-zone-identifier "subnet-12345,subnet-67890"

Interview talking point: “—vpc-zone-identifier takes comma-separated subnets, not space-separated, and the launch template carries the instance config because the ASG stores none itself. Omit the flag and the group inherits the VPC main route table subnets.”

Q62: How do you set up Auto Scaling policy?

Section titled “Q62: How do you set up Auto Scaling policy?”

What it is: Tells the ASG how to change capacity: simple step scaling, or target tracking holding a metric at a set value.

Why it is used: Automates capacity on demand instead of fixed schedules or manual intervention.

Terminal window
# Scale out policy
aws autoscaling put-scaling-policy \
--auto-scaling-group-name my-asg \
--policy-name scale-out \
--policy-type SimpleScaling \
--adjustment-type PercentChangeInCapacity \
--scaling-adjustment 50 \
--cooldown 300
# Scale in policy
aws autoscaling put-scaling-policy \
--auto-scaling-group-name my-asg \
--policy-name scale-in \
--policy-type SimpleScaling \
--adjustment-type ChangeInCapacity \
--scaling-adjustment -1
# Target tracking policy
aws autoscaling put-scaling-policy \
--auto-scaling-group-name my-asg \
--policy-name target-tracking-cpu \
--policy-type TargetTrackingScaling \
--target-tracking-configuration '{
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ASGAverageCPUUtilization"
},
"TargetValue": 70.0
}'

Interview talking point: “Prefer TargetTrackingScaling over simple scaling because it self-corrects as traffic shifts. Target tracking reacts to load, not instance health, so health-driven replacement comes from the health check grace period and ReplaceUnhealthy, not a policy.”

What it is: Routes HTTP and HTTPS across VPC subnets by path, host or header through listener rules, with target groups running health checks.

Why it is used: Distributes traffic, terminates TLS and replaces unhealthy targets automatically.

Terminal window
# Create target group
aws elbv2 create-target-group \
--name my-targets \
--protocol HTTP \
--port 80 \
--vpc-id vpc-1234567890abcdef0
# Register targets
aws elbv2 register-targets \
--target-group-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-targets/1234567890abcdef0 \
--targets Id=i-1234567890abcdef0 Id=i-0987654321fedcba0
# Create ALB
aws elbv2 create-load-balancer \
--name my-alb \
--subnets subnet-12345 subnet-67890 \
--security-groups sg-12345
# Create listener
aws elbv2 create-listener \
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-alb/1234567890abcdef0 \
--protocol HTTP \
--port 80 \
--default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-targets/1234567890abcdef0

Interview talking point: “Order matters: create the target group first, register targets, create the load balancer, then the listener. Targets only go healthy when the health check returns 200, so a /health path answering 404 is the classic cause.”


Q64: How do you create CloudFormation stack?

Section titled “Q64: How do you create CloudFormation stack?”

What it is: Applies a template as one atomic operation, creating all resources together and rolling them back together on failure.

Why it is used: Provisions infrastructure declaratively and reproducibly, so environments are built from code rather than clicked together.

Terminal window
# Create stack
aws cloudformation create-stack \
--stack-name my-stack \
--template-body file://template.yaml \
--parameters ParameterKey=KeyName,ParameterValue=my-key \
--timeout-in-minutes 30
# Update stack
aws cloudformation update-stack \
--stack-name my-stack \
--template-body file://template.yaml \
--parameters ParameterKey=KeyName,ParameterValue=my-new-key
# Delete stack
aws cloudformation delete-stack --stack-name my-stack
# List stacks
aws cloudformation list-stacks
# Describe stack
aws cloudformation describe-stacks --stack-name my-stack

Interview talking point: “create-stack with —template-body, update-stack for changes, delete-stack to tear down. Atomicity means a failure rolls back rather than leaving half an environment, but CloudFormation does not notice console edits, so run drift detection if anyone has console access.”

Q65: How do you use CloudFormation parameters?

Section titled “Q65: How do you use CloudFormation parameters?”

What it is: Typed, validated template inputs with Default and AllowedValues, so one template can serve many environments.

Why it is used: Makes a template reusable across instance sizes, regions and environments instead of hard-coded values.

template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: EC2 Instance with Parameters
Parameters:
InstanceType:
Type: String
Default: t2.micro
AllowedValues:
- t2.micro
- t2.small
- t3.micro
Description: EC2 instance type
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: Name of an existing key pair
Resources:
MyInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0c55b159cbfafe1f0
InstanceType: !Ref InstanceType
KeyName: !Ref KeyName

Interview talking point: “Parameters are always strings, so numeric conditions compare lexically and 2 sorts above 10. Validation rejects a bad deploy instead of creating something wrong, but coercion on numeric-looking strings still surprises people.”

Q66: How do you use CloudFormation intrinsic functions?

Section titled “Q66: How do you use CloudFormation intrinsic functions?”

What it is: The template’s expression language: !Ref, !GetAtt, !Sub, !Join, !Select, !If and !FindInMap.

Why it is used: Wires values from one resource into another and builds values YAML cannot express declaratively.

# Using Ref
Instance: !Ref MyInstance
# Using GetAtt
AZ: !GetAtt MyInstance.AvailabilityZone
# Using Sub
Name: !Sub '${AWS::StackName}-instance'
# Using Join
Owner: !Join [",", ["admin@example.com", "dev@example.com"]]
# Using If
SecurityGroup: !If [UseDefaultSG, !Ref DefaultSG, !Ref CustomSG]
# Using Equals
Environment: !If [IsProduction, "prod", "dev"]

Interview talking point: ”!Ref on a parameter returns the string you passed, while !Ref on a resource returns its physical ID, same function, very different results. !If requires a named condition to exist first, and !Sub is usually the most readable option.”

Q67: How do you use CloudFormation mappings?

Section titled “Q67: How do you use CloudFormation mappings?”

What it is: Static lookup tables keyed by a literal plus !Ref AWS::Region, holding per-region values such as AMI IDs.

Why it is used: Keeps one template deployable to multiple regions without scattering conditionals everywhere.

Mappings:
RegionMap:
us-east-1:
AMI: ami-0c55b159cbfafe1f0
us-west-2:
AMI: ami-0a12345b67890cdef
Resources:
MyInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", AMI]

Interview talking point: ”!FindInMap takes MapName, TopKey, SecondKey, with TopKey usually !Ref AWS::Region for a regional AMI. The whole thing is plain YAML, so a typo’d key fails template validation rather than surfacing at runtime.”

Q68: How do you use CloudFormation outputs?

Section titled “Q68: How do you use CloudFormation outputs?”

What it is: Exposes resource attributes after deploy, optionally exported by name so other stacks can import them with !ImportValue.

Why it is used: Prints instance IDs, public URLs or VPC IDs and passes values between stacks.

Outputs:
InstanceID:
Description: Instance ID
Value: !Ref MyInstance
Export:
Name: !Sub '${AWS::StackName}-InstanceID'
PublicIP:
Description: Public IP Address
Value: !GetAtt MyInstance.PublicIp
InstanceURL:
Description: URL to access the application
Value: !Sub 'http://${MyInstance.PublicDnsName}'

Interview talking point: “Export names must be unique per account and region, so namespace them with !Sub using the stack name, and an export cannot be updated until it is first removed by its owning stack.”


What it is: A logical grouping of container instances or Fargate capacity that tasks are scheduled onto.

Why it is used: Organises and isolates workloads and defines the capacity providers its services can use.

Terminal window
# Create cluster
aws ecs create-cluster \
--cluster-name my-cluster \
--capacity-providers FARGATE
# List clusters
aws ecs list-clusters
# Describe cluster
aws ecs describe-cluster --cluster my-cluster

Interview talking point: “create-cluster —capacity-providers FARGATE is trivial; the point is what the cluster does not do. It provides no networking, so awsvpc tasks still need subnets and security groups, and it has no built-in scaling.”

Q70: How do you register ECS task definition?

Section titled “Q70: How do you register ECS task definition?”

What it is: A versioned JSON document describing the container image, CPU and memory, network mode, IAM role and commands.

Why it is used: Declares what should run, so a service can then run N copies of it.

Terminal window
# Register task definition
aws ecs register-task-definition \
--family my-app \
--network-mode awsvpc \
--requires-compatibilities FARGATE \
--cpu "256" \
--memory "512" \
--container-definitions '[{
"name": "web",
"image": "nginx:latest",
"essential": true,
"portMappings": [{
"containerPort": 80,
"protocol": "tcp"
}],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/my-app",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "web"
}
}
}]'

Interview talking point: “Every register-task-definition update creates a new revision, which is what enables rollback to an earlier one. On Fargate cpu and memory must be a valid pair with memory above CPU, and awsvpc tasks need a logConfiguration to reach ECR and CloudWatch Logs.”

What it is: Runs and maintains a desired number of tasks from a task definition, replacing any that stop or fail health checks.

Why it is used: Makes container count and version declarative, since the service reconciles reality automatically.

Terminal window
# Create service
aws ecs create-service \
--cluster my-cluster \
--service-name my-service \
--task-definition my-app:1 \
--desired-count 2 \
--launch-type FARGATE \
--network-configuration '{
"awsvpcConfiguration": {
"subnets": ["subnet-12345", "subnet-67890"],
"securityGroups": ["sg-12345"]
}
}' \
--load-balancers '[{
"targetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-targets/1234567890",
"containerName": "web",
"containerPort": 80
}]'

Interview talking point: “create-service needs a task definition, desired count and either —launch-type or a capacity-provider-strategy. In awsvpc mode you must also pass —network-configuration with subnets and security groups, plus containerName and containerPort behind a target group, or tasks never register.”

What it is: update-service changes the task definition, desired count or other settings, and ECS performs a rolling deployment by default.

Why it is used: Rolls out a new revision or scales the service without replacing every task at once.

Terminal window
# Update service
aws ecs update-service \
--cluster my-cluster \
--service my-service \
--task-definition my-app:2 \
--desired-count 3
# View service events
aws ecs describe-services \
--cluster my-cluster \
--services my-service \
--query 'services[0].events'

Interview talking point: “—minimum-healthy-percent and —maximum-percent are the rolling update safety valves. The deployment circuit breaker only reacts to failed deployments, so when it hangs read service.events, where the cause is usually tasks failing on networking rather than the image.”


Q73: How do you create Route 53 hosted zone?

Section titled “Q73: How do you create Route 53 hosted zone?”

What it is: Route 53’s container for a DNS namespace; public zones resolve on the internet, private ones only inside your VPCs.

Why it is used: Owns a domain’s DNS records and gives internal services stable names that never leave the network.

Terminal window
# Create hosted zone
aws route53 create-hosted-zone \
--name example.com \
--caller-reference "my-zone-$(date +%s)"
# List hosted zones
aws route53 list-hosted-zones

Interview talking point: “create-hosted-zone needs a —caller-reference that is unique per call, or you get HostedZoneAlreadyExists, which is why people append the date. A private zone must be associated with the VPC via associate-vpc-with-hosted-zone or nothing resolves it.”

Q74: How do you create DNS record in Route 53?

Section titled “Q74: How do you create DNS record in Route 53?”

What it is: Submits a batch of DNS record creates, deletes or upserts that Route 53 applies atomically.

Why it is used: Manages DNS programmatically, since records are usually owned outside the infrastructure as code.

Terminal window
# Create record
aws route53 change-resource-record-sets \
--hosted-zone-id Z1234567890ABCDEF \
--change-batch '{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "www.example.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [{"Value": "1.2.3.4"}]
}
}]
}'

Interview talking point: “The call needs the hosted zone ID, not the domain name. Use UPSERT instead of CREATE for idempotent scripts, because CREATE on an existing name fails, and allow a couple of minutes for changes to propagate before testing.”

Q75: How do you set up Route 53 health check?

Section titled “Q75: How do you set up Route 53 health check?”

What it is: Pings an endpoint on an interval, reports healthy or unhealthy, and lets recordsets drive failover routing.

Why it is used: Sends traffic to whichever region is actually serving and fails over without long DNS TTLs.

Terminal window
# Create health check
aws route53 create-health-check \
--caller-reference "healthcheck-$(date +%s)" \
--health-check-config '{
"Type": "HTTPS",
"FullyQualifiedDomainName": "example.com",
"Port": 443,
"ResourcePath": "/health",
"RequestInterval": 30,
"FailureThreshold": 3
}'
# Use in failover record
aws route53 change-resource-record-sets ...

Interview talking point: “Health checks run from AWS’s own network, so the resource path must be reachable publicly and a private endpoint needs another mechanism. Failover records then need SetIdentifier plus HealthCheckId with the Failover type to actually switch.”


Q76: How do you check SSL certificate expiration?

Section titled “Q76: How do you check SSL certificate expiration?”

What it is: openssl s_client reads the certificate chain the server presents and x509 -noout -dates prints its validity window.

Why it is used: Checks expiry before it breaks and verifies a certificate really was renewed and reloaded.

Terminal window
# Using OpenSSL
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
# Using AWS CLI
aws acm list-certificates --region us-east-1
# Using SSL Labs
# Visit https://ssllabs.com/ssltest/

Interview talking point: “openssl s_client -connect host:443 -servername host piped to openssl x509 -noout -dates is the check that tells the truth. The classic incident is ACM showing a renewed certificate while the load balancer still serves the old one, so always verify from outside.”

Q77: How do you access EC2 instance through another instance?

Section titled “Q77: How do you access EC2 instance through another instance?”

What it is: ssh -J tunnels through an intermediate host so you can reach a private instance via a bastion.

Why it is used: Gets a shell into a private instance when SSM Session Manager is not available.

Terminal window
# SSH from bastion to private instance
ssh -i key.pem ec2-user@<private-ip-of-private-instance>
# SSH with proxy jump
ssh -J ec2-user@<bastion-ip> ec2-user@<private-ip>
# Using SSM (recommended)
aws ssm start-session --target i-private-instance-id

Interview talking point: “ssh -J user@bastion user@private is ProxyJump and replaces manual port forwarding, but prefer aws ssm start-session with the target instance ID: it needs no inbound port at all and logs every session to CloudTrail, which is what auditors accept.”

Q78: How do you upgrade EC2 with zero downtime?

Section titled “Q78: How do you upgrade EC2 with zero downtime?”

What it is: Creates a new launch template version and points the ASG at it, so old instances are replaced behind the load balancer.

Why it is used: Changes instance type, AMI or instance profile without dropping requests in production.

  1. Using Auto Scaling Group:
Terminal window
# Update launch template with new instance type
aws ec2 create-launch-template-version \
--launch-template-id lt-12345 \
--launch-template-data '{"InstanceType":"t3.small"}'
# Update ASG to use new version
aws autoscaling update-auto-scaling-group \
--auto-scaling-group-name my-asg \
--launch-template LaunchTemplateId=lt-12345,Version="2"
  1. Using Blue-Green:
  • Create new instance with larger type
  • Deploy application
  • Add to load balancer
  • Test
  • Remove old instance

Interview talking point: “Run create-launch-template-version, then update-auto-scaling-group with an explicit Version. Never edit version 1 in place, and if you omit Version the ASG uses $Default and silently reuses the old one, which is why the change appears to do nothing.”

Q79: How do you change IAM role with zero downtime?

Section titled “Q79: How do you change IAM role with zero downtime?”

What it is: associate-iam-instance-profile swaps the role an instance presents and invalidates the credentials cache.

Why it is used: Corrects an instance’s permissions without replacing or restarting the instance.

Terminal window
# Change IAM role
aws ec2 associate-iam-instance-profile \
--instance-id i-1234567890abcdef0 \
--iam-instance-profile Name=NewRole
# Note: Existing connections will continue to work
# New connections will use new role
# Applications should handle credential refresh

Interview talking point: “Attaching a new profile replaces the old one, but cached credentials keep working until they expire, so new permissions apply on the next refresh rather than instantly. Applications need retry logic, and credentials written to disk or environment never update at all.”

What it is: SSL is the deprecated name for TLS, the protocol that encrypts and authenticates traffic between client and server.

Why it is used: Protects data in transit and proves to the browser that the site is who it claims to be.

  • SSL (Secure Sockets Layer) / TLS (Transport Layer Security)
  • Encrypts data in transit between browser and server
  • Authenticates website identity (prevents phishing)
  • Required for HTTPS
  • Improves SEO ranking
  • Builds user trust (padlock icon)
  • Required for PCI compliance

Interview talking point: “Say TLS, not SSL: SSL 2.0 and 3.0 are both broken, and ssl_certificate in Nginx just means TLS certificate. Encryption and server authentication are the reason, PCI-DSS requires it, while SEO and the padlock are side benefits.”


Q81: How do you check EC2 CPU utilization?

Section titled “Q81: How do you check EC2 CPU utilization?”

What it is: CloudWatch’s CPUUtilization metric for AWS/EC2, dimensioned by InstanceId, published at one-minute granularity.

Why it is used: Checks current load and feeds an alarm or a rightsizing decision.

Terminal window
aws cloudwatch get-metric-statistics \
--namespace AWS/EC2 \
--metric-name CPUUtilization \
--start-time 2024-01-01T00:00:00Z \
--end-time 2024-01-01T01:00:00Z \
--period 3600 \
--statistics Average \
--dimensions Name=InstanceId,Value=i-1234567890abcdef0

Interview talking point: “get-metric-statistics needs start-time, end-time, period and statistics together or the call is rejected. Basic monitoring is five-minute averages, so a 60-second period returns sparse data unless you enable detailed monitoring with monitor-instances first.”

Q82: How do you find underutilized EC2 instances?

Section titled “Q82: How do you find underutilized EC2 instances?”

What it is: Cost Explorer rightsizing recommendations that read CloudWatch utilisation history and suggest smaller instance types or termination.

Why it is used: Finds idle or over-provisioned instances during a cost review using real utilisation, not guesses.

Terminal window
aws ce get-rightsizing-recommendations \
--service AmazonEC2 \
--recommendation-target-type COVERAGE

Interview talking point: “ce get-rightsizing-recommendations needs Cost Explorer enabled and typically 14 days of data before it returns anything. It optimises average utilisation, so check the suggestion against p95 before acting or you may size for a peak it ignores.”

Q83: How do you enable detailed monitoring on EC2?

Section titled “Q83: How do you enable detailed monitoring on EC2?”

What it is: monitor-instances switches an instance from free five-minute basic monitoring to paid one-minute detailed monitoring.

Why it is used: Needed to see short bursts such as deploy CPU spikes or leak-driven memory climbs.

Terminal window
aws ec2 monitor-instances --instance-ids i-1234567890abcdef0

Interview talking point: “Detailed monitoring costs extra per instance and cannot be disabled for 24 hours, so enable it before a load test. CPUUtilization is the only metric EC2 publishes, so memory, disk and network require the CloudWatch agent.”

What it is: create-topic makes a topic and subscribe registers an endpoint that receives every message published to it.

Why it is used: Enables fan-out, one event reaching many subscribers by email, SMS, Lambda or SQS.

Terminal window
aws sns create-topic --name my-topic
# Subscribe
aws sns subscribe \
--topic-arn arn:aws:sns:us-east-1:123456789012:my-topic \
--protocol email \
--notification-endpoint admin@example.com

Interview talking point: “Email subscriptions stay PendingConfirmation until the recipient clicks, and Lambda or SQS endpoints also need a resource policy allowing sns.amazonaws.com to publish. Without it the subscription saves but nothing ever arrives.”

What it is: publish sends a message to a topic, which SNS fans out to every confirmed subscriber; —subject works only for email and SMS.

Why it is used: Notifies subscribers about an event, but processing or guaranteed delivery belongs in SQS.

Terminal window
aws sns publish \
--topic-arn arn:aws:sns:us-east-1:123456789012:my-topic \
--message "Alert: High CPU usage" \
--subject "CPU Alert"

Interview talking point: “publish returns a message ID, not a delivery status. SNS is best-effort push for humans and SQS is durable queueing for workloads, so per-consumer copies with retries means an SNS-to-SQS fan-out rather than SNS alone.”

What it is: create-queue makes a queue, with attributes deciding standard versus FIFO plus retention and encryption.

Why it is used: Buffers producers from consumers so load spikes do not overwhelm a downstream service.

Terminal window
aws sqs create-queue \
--queue-name my-queue \
--attributes '{"FifoQueue":"true","ContentBasedDeduplication":"true"}'

Interview talking point: “FifoQueue can only be set at creation and buys ordering and exactly-once delivery. Content-based deduplication hashes the body, so two genuinely different messages with identical bodies get dropped together.”

What it is: send-message enqueues a message body of up to 256 KB, addressed by the queue URL.

Why it is used: Decouples producer from consumer, so the API stays fast under load.

Terminal window
aws sqs send-message \
--queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-queue \
--message-body '{"orderId": "123", "amount": 100}'

Interview talking point: “The queue URL, not the name, is the identifier, so call get-queue-url first or store the URL. For volume use send-message-batch, up to ten messages, because per-message API charges make single sends expensive.”

What it is: receive-message returns up to ten messages and hides them for the visibility timeout; they reappear if never deleted.

Why it is used: Lets many consumers share one queue safely, providing at-least-once delivery.

Terminal window
aws sqs receive-message \
--queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-queue \
--max-number-of-messages 10

Interview talking point: “Your handler must be idempotent, because a crash before delete-message means redelivery, and if processing outlasts VisibilityTimeout a second consumer picks up the same message concurrently. That timeout is the whole concurrency control mechanism.”

What it is: A secondary index with its own key schema and throughput, letting you query on a non-key attribute.

Why it is used: Serves access patterns the primary key cannot, like looking a user up by email.

Terminal window
aws dynamodb update-table \
--table-name Users \
--global-secondary-index-updates '[{
"Create": {
"IndexName": "EmailIndex",
"KeySchema": [{"AttributeName":"Email","KeyType":"HASH"}],
"Projection":{"ProjectionType":"ALL"},
"ProvisionedThroughput":{"ReadCapacityUnits":5,"WriteCapacityUnits":5}
}
}]'

Interview talking point: “GSIs are created through update-table with —global-secondary-index-updates, one index at a time, or you get a ValidationException. They do not support consistent reads, and you pay for their throughput separately from the table.”

What it is: Marks an item for deletion once its numeric timestamp attribute passes, with DynamoDB removing it within about 48 hours.

Why it is used: Auto-expires sessions, tokens and event records without a scheduled cleanup job.

Terminal window
aws dynamodb update-time-to-live \
--table-name Orders \
--time-to-live-specification Enabled=true,AttributeName=ExpiresAt

Interview talking point: “update-time-to-live takes Enabled=true and an attribute name, and the value must be epoch seconds as a number, since a string date is silently ignored. Deletion is lazy up to 48 hours, so TTL is not a compliance deletion tool.”

What it is: A stable name pointing at a specific published function version, which is what event sources should invoke.

Why it is used: Lets you deploy $LATEST in dev and repoint PROD between versions for instant rollback.

Terminal window
aws lambda create-alias \
--function-name my-function \
--name PROD \
--function-version 3

Interview talking point: “Integrations must target the alias, never $LATEST, or a rollback only changes what you are testing rather than what production runs. update-alias with a new version is the rollback, and weighted traffic shifting gives you a canary.”

What it is: publish-version snapshots the current $LATEST code and configuration into an immutable numbered version.

Why it is used: Makes a deployment reproducible and revertible, since $LATEST is always moving.

Terminal window
aws lambda publish-version --function-name my-function

Interview talking point: “You cannot alias a version that was never published, so publishing is what makes rollback possible. The snapshot includes configuration, and published versions cannot be deleted, so publishing on every deploy bloats the account’s version list.”

What it is: An event pattern plus targets: when a matching event arrives, every target is invoked.

Why it is used: Wires event-driven automation for state changes, schedules or AWS service events with no polling.

Terminal window
aws events put-rule \
--name ec2-state-change \
--event-pattern '{"source":["aws.ec2"],"detail-type":["EC2 Instance State-change Notification"]}'
# Add target
aws events put-targets \
--rule ec2-state-change \
--targets '[{"Id":"my-target","Arn":"arn:aws:lambda:us-east-1:123456789012:function:my-function"}]'

Interview talking point: “put-rule with —event-pattern, then put-targets. API call triggers use detail-type AWS API Call via CloudTrail with a nested detail.eventName, while schedules use ScheduleExpression like rate(5 minutes), and a rule cannot carry both.”

What it is: Captures metadata about every accepted or rejected IP flow in a VPC, delivered to CloudWatch Logs or S3.

Why it is used: Investigates connectivity problems and provides a network audit trail of who talked to what.

Terminal window
aws ec2 create-flow-logs \
--resource-type VPC \
--resource-ids vpc-1234567890abcdef0 \
--traffic-type ALL \
--log-destination-type cloud-watch-logs \
--log-group-name /aws/vpc/flowlogs

Interview talking point: “create-flow-logs needs the log group to already exist and a role that can write to it. Flow logs carry metadata only, never payload, so the fields you query are srcaddr, dstaddr, dstport, action and rejectreason.”

Q95: How do you create CloudWatch logs group?

Section titled “Q95: How do you create CloudWatch logs group?”

What it is: The container that log streams live in, owning the retention policy for everything beneath it.

Why it is used: Organises logs by application so they expire automatically instead of accumulating forever.

Terminal window
aws logs create-log-group --log-group-name /my-app/logs

Interview talking point: “create-log-group creates only the container; retention is set separately with put-retention-policy, and leaving it unset means logs are kept forever, the usual cause of a surprise bill. Names beginning /aws/ are created automatically by services, so you cannot pre-create them.”

Q96: How do you create Secret with rotation?

Section titled “Q96: How do you create Secret with rotation?”

What it is: create-secret stores the value, while rotation is configured separately with rotate-secret, which needs a Lambda implementing the four rotation steps.

Why it is used: Rotates credentials on a schedule so applications pick up the new value without a redeploy.

Terminal window
aws secretsmanager create-secret \
--name prod/db-creds \
--secret-string '{"username":"admin","password":"pass"}'
# create-secret takes NO rotation parameters; configure rotation separately
aws secretsmanager rotate-secret \
--secret-id prod/db-creds \
--lambda-function-name arn:aws:lambda:us-east-1:123456789012:function:rotation-fn \
--rotation-rules AutomaticallyAfterDays=30
# Passing --rotation-lambda-arn to create-secret is rejected:
# An error occurred (ValidationException): 1 validation error detected:
# Value 'arn:...' at 'rotationLambdaArn' failed to satisfy constraint

Interview talking point: “create-secret does not accept rotation parameters; passing —rotation-lambda-arn to it fails with ValidationException. Create the secret first, then call rotate-secret with the Lambda ARN and AutomaticallyAfterDays, and the Lambda must finish with FinishSecretRotation or rotation is marked failed.”

Q97: How do you check EBS volume available IOPS?

Section titled “Q97: How do you check EBS volume available IOPS?”

What it is: describe-volume-attribute with —attribute iops reports a volume’s provisioned IOPS; the same shape reports throughput.

Why it is used: Checks what a volume is actually provisioned with before assuming its type’s limits.

Terminal window
aws ec2 describe-volume-attribute \
--volume-id vol-1234567890abcdef0 \
--attribute iops

Interview talking point: “Limits are per type: gp3 scales IOPS and throughput independently above its baseline, gp2 fixes IOPS at 100 per GiB, and io1 needs 50 IOPS per GiB while io2 needs 100, which surfaces as a creation-time validation error.”

What it is: create-volume provisions EBS storage in a specific availability zone and type, optionally encrypted with KMS.

Why it is used: Adds persistent block storage separate from an instance, or grows an existing workload.

Terminal window
aws ec2 create-volume \
--size 50 \
--availability-zone us-east-1a \
--volume-type gp3 \
--encrypted

Interview talking point: “The availability zone is required because EBS is zonal, so the volume must sit in the same AZ as the instance you attach it to. gp3 accepts —iops and —throughput above baseline, but those flags are rejected outright on gp2.”

What it is: attach-volume connects a volume to an instance’s ENI at a device name the guest sees as a block device.

Why it is used: Gives an instance extra or higher-performance storage without recreating the instance.

Terminal window
aws ec2 attach-volume \
--volume-id vol-1234567890abcdef0 \
--instance-id i-1234567890abcdef0 \
--device /dev/sdf

Interview talking point: “The volume must be in the instance’s AZ, and Linux typically surfaces /dev/sdf as /dev/xvdf, after which you still have to mount it. The state passes through attaching before in-use, so scripts that assume immediate availability race.”

Q100: How do you detach and delete EBS volume?

Section titled “Q100: How do you detach and delete EBS volume?”

What it is: detach-volume disconnects a volume from its instance and delete-volume permanently destroys it.

Why it is used: Cleans up unattached storage, since unused volumes are billed in full and waste money.

Terminal window
# Detach
aws ec2 detach-volume --volume-id vol-1234567890abcdef0
# Delete
aws ec2 delete-volume --volume-id vol-1234567890abcdef0

Interview talking point: “Order matters: delete-volume fails with InvalidVolume.NotDetachable while the volume is still attached. Deleting destroys the data, so snapshot first if you need anything, because snapshots outlive both the volume and the instance.”


Continue with Questions 101-200 in next file…