A scannable reference of architectural patterns the SAA-C03 exam tests. Read top-to-bottom, or jump to a section.
Design Secure Architectures
Three-tier app: web, app, DB. DB must be unreachable from the internet under any circumstance.
Public subnets for web tier (ALB). Private subnets for app and DB tiers. DB security group allows traffic only from the app-tier security group (not from CIDR ranges).
Why: Subnet routing tables enforce reachability; security-group-to-security-group references encode least-privilege at the SG layer and survive IP changes.
Service A in Account A invokes Lambda in Account B. Least privilege.
Resource-based policy on the target Lambda granting `lambda:InvokeFunction` to Account A's role principal. Caller assumes its own role and invokes directly - no role chaining needed.
Why: Resource policies are the simplest cross-account pattern for service-fronted resources (Lambda, S3, SNS, SQS, KMS).
Other AWS accounts need to upload to a central S3 bucket.
Bucket policy granting `s3:PutObject` to external account principals. Add `bucket-owner-full-control` ACL requirement so the bucket owner retains control of objects.
Why: Without `bucket-owner-full-control` (or `BucketOwnerEnforced` Object Ownership), uploaded objects are owned by the writer account.
User Pool = sign-up / sign-in / JWT issuance for app users. Identity Pool = exchange tokens for temporary AWS credentials. Most apps use both: User Pool authenticates, Identity Pool authorizes AWS access.
Need full control over key rotation, deletion, and per-key audit trail.
Customer-managed KMS key (CMK). AWS-managed keys (`aws/<service>`) are simpler but offer no key-policy control or visibility into individual key usage.
Why: CMKs let you scope access per key in CloudTrail, set key policies for cross-account use, and disable/schedule deletion.
Encrypt large objects without per-object KMS API calls dominating cost.
Envelope encryption. KMS generates a data key (one API call); use the data key to encrypt the payload locally; store encrypted-data-key alongside the ciphertext.
Why: KMS is rate-limited and priced per request. Envelope pattern is the canonical way to encrypt data > a few KB.
Pick Secrets Manager vs SSM Parameter Store SecureString.
DB credentials with automatic rotation, cross-account share, large secrets β Secrets Manager. Config flags, app settings, simple secrets, lowest cost β SSM Parameter Store.
Why: Secrets Manager has built-in rotation Lambdas for RDS/Aurora/DocumentDB/Redshift; Parameter Store has no native rotation but is free for Standard tier.
Secrets Manager with managed rotation. Built-in Lambda template handles single-user rotation against the RDS endpoint. Apps fetch the secret at connect time (cached) - no app redeploy.
Mission-critical app needs DDoS cost-protection and 24Γ7 SRT support.
AWS Shield Advanced on CloudFront / ALB / NLB / Global Accelerator. Includes cost protection (refunds for scaling spend during attack) + Shield Response Team access.
Why: Shield Standard is automatic and free; Advanced adds protections and SLA. CloudFront is always the recommended front door.
Stateful, attach to ENI, allow-only β security group (default). Stateless, subnet-level, allow + explicit deny β NACL. Use NACLs for blanket deny rules (block IP ranges); SGs for everything else.
PCI DSS workload - strict isolation from non-PCI accounts.
Dedicated AWS account inside an Organizations OU with SCPs restricting service / region access. Separate VPC, KMS keys, IAM roles. Network Firewall or GWLB for egress inspection.
Why: Account boundary is the strongest blast-radius isolation in AWS.
Pick Aurora vs RDS for a new MySQL/PostgreSQL workload.
Aurora for higher throughput, faster failover, up to 15 read replicas, Global Database, Serverless v2. RDS for older engines (MariaDB, Oracle, SQL Server) or simpler/cheaper deployments.
Why: Aurora storage is shared across replicas (no replica lag from storage). Failover < 30s typical.
HTTP/HTTPS, path/host routing, WAF integration, OIDC auth β ALB. TCP/UDP/TLS at extreme scale, static IP per AZ, lowest latency, preserve client source IP β NLB.
Multi-step workflow needs per-task retry with exponential backoff and error catch.
AWS Step Functions Standard workflow. `Retry` block with `IntervalSeconds`, `MaxAttempts`, `BackoffRate`. `Catch` block routes specific errors to a recovery state.
Global app needs zero-RTO failover across two Regions.
Active-active across Regions: Global Accelerator or Route 53 latency routing for ingress; DynamoDB Global Tables / Aurora Global Database for data; cross-Region replication for object stores.
Multiple EC2 instances must read+write the same block volume.
EBS Multi-Attach with io2 / io1 (Nitro instances only). Concurrent attach to up to 16 instances in the same AZ.
Why: Application must coordinate writes (cluster filesystem). EFS is the default for shared file access; Multi-Attach is for clustered DBs that need block.
Static assets + API responses with global users; reduce origin load.
CloudFront with appropriate cache policy. Long TTLs for static; cache-key includes only essential headers/query strings. Use Origin Shield for high-cardinality origins.
Why: Cache hit ratio drives both performance and cost. Wrong cache key (e.g. include all headers) destroys hit rate.
Lazy loading (cache miss β fetch + populate): simple, only caches what's requested. Write-through (write to cache + DB on update): cache always fresh, but extra writes. TTL: bound staleness on either pattern.
Provisioned Concurrency. Pre-warmed environments ready to invoke at any throughput. Combine with Application Auto Scaling for scheduled scale-up.
Why: Costs more than on-demand but eliminates cold start. Not needed for steady traffic where provisioned-concurrency utilization stays high naturally.
Pick Kinesis Data Streams vs Firehose vs Managed Service for Apache Flink vs MSK.
Custom consumers, ms latency, replay, multi-consumer fan-out β Data Streams. Just deliver to S3/Redshift/OpenSearch with buffering β Firehose. Stream processing (windows, joins) β Managed Service for Apache Flink. Kafka-compatible β MSK.
Unpredictable / spiky / new workloads β On-demand. Steady, predictable, hot - and cost-sensitive β Provisioned with auto-scaling. Switch modes at most once per 24 hours.
Query DynamoDB by an attribute that isn't the partition key.
Global Secondary Index (GSI) for queries on different partition key. Local Secondary Index (LSI) for alternate sort key on same partition key (LSI must be created at table-create time).
Pick EC2 purchase option for a steady 24Γ7 fleet.
Compute Savings Plan (1y or 3y) - 66% off list, flexible across instance family, size, OS, tenancy, Region. RIs only when you need capacity reservation.
Why: Savings Plans dominate RIs for most cost-only use cases (more flexible, same discount).
Migrate to Graviton (ARM64) instances. ~20% cheaper, ~40% better price-perf for many workloads. Requires multi-arch container images or recompiled binaries.
Increase memory (which scales CPU and network proportionally). Use Lambda Power Tuning (Step Functions tool) to find the sweet spot - often higher memory is faster AND cheaper.
S3 Lifecycle rules: transition to IA after 30d, Glacier Flexible after 90d, Deep Archive after 180d, expire after retention. Combine with Intelligent-Tiering for unknown patterns.
NAT Gateway data-processing fees dominate the bill.
Replace AWS-service traffic with VPC Endpoints (gateway for S3/DynamoDB; interface for everything else). Move workloads needing internet egress to public subnets only when necessary.
Why: NAT Gateway charges per GB processed even for AWS-service traffic. Endpoints eliminate that path.
Same-AZ, same-VPC = free. Cross-AZ = $0.01/GB each way. Cross-Region = expensive. Egress to internet = most expensive but free via CloudFront for cacheable content. Always egress via CloudFront when possible.
Set explicit retention (default is "Never expire"). Export old logs to S3 + Glacier. Use Logs Insights only on warm data. Filter at agent (don't ship debug logs in prod).
Chargeback by team or product without separate accounts.
Cost allocation tags. Activate user-defined tags in Billing console; surface in Cost Explorer + CUR. Combine with `aws:CreatedBy` for identity attribution.
Dev/test EC2 instances run 24Γ7 - only used 9-to-5.
AWS Instance Scheduler (CloudFormation-deployed Lambda). Tag instances with schedule names; runs cron-like start/stop. Or just `aws:autoscaling:scheduledActions` on dev ASGs.
Why: ~70% reduction on dev compute spend with off-hours stop.
Stop the RDS instance (single-AZ; up to 7 days, then auto-starts). Or Aurora Serverless v2 with min ACU = 0.5 (no full stop, but minimal cost when idle).
Steady, high utilization β ECS on EC2 (with Spot/Savings Plans) - cheapest. Spiky / short-lived / no node mgmt β Fargate. Fargate Spot is 70% off Fargate for tolerant workloads.
Front with CloudFront. Origin β edge transfer is free; edge β user is cheaper than direct EC2/S3 egress at scale. Enable compression + appropriate TTLs.
Move > 1 PB from on-prem to AWS; bandwidth too slow for online transfer.
AWS Snow Family. Snowball Edge Storage Optimized (80 TB) for typical; multiple devices in parallel for 100s of TB. Snowmobile is retired - use multi-Snowball for petabyte scale.