AWS has hundreds of services, and almost no project uses more than a handful of them. This is a map of the ones you'll actually run into as a developer, organized by what problem each one solves.
Compute: where your code runs
EC2 (Elastic Compute Cloud) — a virtual machine you fully control: choose the OS, install anything, manage patching yourself. The right choice when you need long-running processes, full OS-level control, or software that doesn't fit a serverless model.
Lambda — run a function in response to an event (an HTTP request, a file upload, a queue message) without managing a server at all. You pay per invocation and per millisecond of execution, and it scales from zero to thousands of concurrent invocations automatically.
ECS / EKS (Elastic Container Service / Elastic Kubernetes Service) — run containers at scale. ECS is AWS's own simpler orchestrator; EKS is managed Kubernetes for teams who want the standard Kubernetes API and ecosystem (Helm charts, kubectl, and tools like Karpenter) rather than an AWS-specific one.
Fargate — a serverless mode for both ECS and EKS: you define container specs, AWS runs them without you provisioning or managing the underlying EC2 instances at all.
| Aspect | EC2 | Lambda |
|---|---|---|
| Control | Full OS access, you patch and manage it | No server access — you only supply code |
| Billing | Per second/hour the instance runs, regardless of load | Per invocation + execution time, scales to zero |
| Best for | Long-running processes, full control needs | Event-driven, bursty, or infrequent workloads |
| Max runtime | Unlimited | 15 minutes per invocation |
Storage: where your data lives at rest
S3 (Simple Storage Service) — object storage for files of any kind: images, backups, static website assets, data lake files. Not a filesystem — no in-place edits, objects are written and replaced wholesale, addressed by key.
EBS (Elastic Block Store) — a virtual hard drive attached to a single EC2 instance at a time. This is what an EC2 instance's root volume actually is, and what you'd attach for a database's data directory.
EFS (Elastic File System) — a network filesystem multiple EC2 instances or containers can mount and read/write concurrently, unlike EBS which is single-instance.
Networking: the foundation everything else sits inside
VPC (Virtual Private Cloud) — your own logically isolated network within AWS. Every EC2 instance, RDS database, and Lambda-with-VPC-access lives inside one. A VPC is subdivided into subnets — public subnets (with a route to the internet via an Internet Gateway) for anything that needs direct inbound/outbound internet access, and private subnets (no direct inbound internet route) for databases and internal services.
Security Groups — a stateful, instance-level firewall: which ports/protocols/sources are allowed in and out of a specific resource.
NAT Gateway — lets resources in a private subnet reach the internet outbound (to pull updates, call an external API) without being reachable inbound from it.
Route 53 — AWS's DNS service, and also supports health-check-based routing and failover.
CloudFront — AWS's CDN: caches content at edge locations close to users, reducing latency and cutting load off the origin (commonly S3 or an ALB) directly.
Data: databases and caching
RDS (Relational Database Service) — managed PostgreSQL, MySQL, and others — AWS handles patching, backups, and failover, you interact with it like a normal relational database.
DynamoDB — a fully managed NoSQL key-value/document database, designed for single-digit-millisecond latency at effectively unlimited scale, at the cost of a much more constrained query model than a relational database (you generally can't run arbitrary ad hoc queries the way you can with SQL).
ElastiCache — managed Redis or Memcached, for caching and low-latency lookups in front of a slower primary datastore.
That layout is the shape almost every real AWS architecture converges on — it's exactly what the 3-tier application deployment tutorial on this site walks through end to end.
Observability: knowing what's actually happening
CloudWatch — metrics, logs, and alarms for almost every AWS service, plus custom metrics your own application can publish. CloudWatch Logs collects log output (from Lambda, ECS, EC2, and more); CloudWatch Metrics tracks numeric time series (CPU utilization, request counts, error rates); CloudWatch Alarms trigger notifications or automated actions when a metric crosses a threshold you define.
X-Ray — distributed tracing across a request that spans multiple services (an API Gateway call to a Lambda function that calls DynamoDB, for instance) — shows exactly where time is spent and where errors originate across the whole chain, not just within one service in isolation.
CloudTrail — an audit log of API calls made against your account (who called what action, when, from where) — distinct from CloudWatch Logs, which captures application/service output. CloudTrail answers "who deleted this bucket," CloudWatch Logs answers "what did the application print while running."
CloudWatch: what your application/service is doing (metrics, logs)
X-Ray: how a request flows across multiple services
CloudTrail: who called which AWS API, and when
Content delivery and DNS, together
Route 53 and CloudFront are frequently used as a pair, but they solve different problems: Route 53 resolves a domain name to an endpoint (DNS); CloudFront caches and serves content close to the requester once they've reached that endpoint. A Route 53 "alias" record pointed at a CloudFront distribution is the standard way to attach a real custom domain to a CDN-fronted site — see the S3 + CloudFront tutorial for the full walkthrough of wiring this together with a free ACM certificate.
Identity and access: IAM
IAM (Identity and Access Management) — controls who (a person, or a service like an EC2 instance or Lambda function) can do what, on which resources. The core building blocks:
- Users — an individual identity, typically a real person with console/CLI access.
- Roles — an identity assumed temporarily, not tied to a specific person — this is what an EC2 instance or Lambda function uses to call other AWS services, and it's the mechanism behind GitHub Actions OIDC federation, avoiding long-lived credentials entirely.
- Policies — JSON documents attached to a user, role, or group, defining exactly which actions are allowed or denied on which resources.
The single most important IAM habit: grant the narrowest policy that actually works, not * on everything "to get unblocked" — broad permissions granted temporarily during development have a strong tendency to never get revisited.
Messaging and events
SQS (Simple Queue Service) — a managed message queue: one service writes messages, another reads and processes them at its own pace, decoupling the two so a slow or failing consumer doesn't block the producer.
SNS (Simple Notification Service) — pub/sub: one message published to a topic can fan out to multiple subscribers (an SQS queue, a Lambda function, an email address) simultaneously.
EventBridge — a managed event bus for routing events (from AWS services or your own applications) to targets based on rules, with richer filtering than SNS — the backbone of most event-driven AWS architectures, covered in depth in the Lambda and EventBridge article.
Common mistakes
- Reaching for EC2 by default because it's the most familiar, when the actual workload (an infrequent, event-driven task) is a much better and cheaper fit for Lambda.
- Putting a database directly in a public subnet "to make it easier to connect to during development" — this exposes it to the internet by default, relying entirely on the security group as the only line of defense instead of network isolation plus a security group together.
- Using long-lived IAM access keys for a service that runs on AWS infrastructure (an EC2 instance, a Lambda function) instead of an IAM role. Roles provide temporary, automatically rotated credentials — a static access key is a permanent secret that has to be manually rotated and can leak.
- Treating Security Groups as the only network control needed and ignoring subnet placement (public vs. private) entirely — the two are complementary layers, not substitutes for each other.
Where to go next
- If you're building a simple, mostly-static site: S3 + CloudFront is the standard, minimal-cost starting point.
- If you're deploying a real application with a database: the 3-tier VPC architecture is the standard shape to learn.
- If your workload is event-driven or infrequent: start with Lambda and EventBridge rather than defaulting to always-on EC2.
- Once something is running, revisit it against the AWS cost optimization playbook — most of that advice only makes sense once there's a real workload to measure.
Related reading
- AWS vs. Azure vs. GCP: Choosing the Right Cloud for Your Project — shares tags: cloud (same category).
- AWS Cost Optimization: A Service-by-Service Playbook — shares tags: cloud, devops.
- Deploying a 3-Tier Application on AWS with Public and Private Subnets — shares tags: cloud, devops.
- Host a Static Website on AWS S3 and CloudFront — shares tags: cloud.
- AWS Lambda and Event-Driven Architecture with EventBridge — shares tags: cloud, devops.