AWS Core Services
EC2, S3, RDS, Lambda, IAM — the building blocks behind most modern infrastructure.
AWS Mental Model
AWS has 200+ services. You need maybe 15 to do real work. This lesson covers those.
The mental model that makes AWS click:
1. EVERYTHING is an API. The console is just a website calling the same APIs you can call from CLI, SDK, or Terraform. Anything you can click, you can automate.
2. Services are LOOSELY COUPLED. Compute (EC2) doesn't know about storage (S3) doesn't know about databases (RDS). You stitch them together.
3. IAM is the security layer for EVERYTHING. Every API call is checked against IAM permissions before it executes.
4. Regions are SEPARATE. us-east-1 and eu-west-1 are different AWS deployments. They share IAM and a few global services (CloudFront, Route 53, IAM). Most other services are regional. Choose carefully.
5. Account-scoped — your account has its own resources, billing, IAM users. Multi-account is the norm for serious orgs (separate prod from dev, etc.).
Resource ARN pattern (Amazon Resource Name):
arn:aws:s3:::my-bucket # global service
arn:aws:ec2:us-east-1:123456789012:instance/i-abc1234 # regional, account-scoped
arn:aws:iam::123456789012:user/alice # IAM is global
Once you can read ARNs, you can navigate AWS docs and IAM policies fluently.
EC2 — Virtual Machines
EC2 (Elastic Compute Cloud) is AWS's IaaS — VMs you can launch via API.
Key concepts:
• Instance type — combination of vCPU, RAM, network. e.g. t3.medium (2 vCPU, 4 GB), m5.large (2 vCPU, 8 GB)
• AMI (Amazon Machine Image) — the OS disk template. Amazon Linux, Ubuntu, Windows, custom-built.
• Key pair — SSH key for accessing the instance.
• Security group — virtual firewall (covered in Module 3).
• EBS volume — the disk attached to the instance. Persists when the instance stops.
• Instance store — local disk on the host. Faster but DISAPPEARS when the instance stops/terminates.
Instance families:
• t — burstable, good for low-baseline workloads (web apps, dev)
• m — general purpose, balanced CPU/memory
• c — compute-optimized, more CPU per dollar
• r — memory-optimized, for databases, caches
• g, p — GPU instances for ML/graphics
• i, d — storage-optimized
Naming pattern: <family><generation>.<size> — m5.large is 5th-gen general purpose, large size.
Launching an EC2 instance via CLI:
aws ec2 run-instances \
--image-id ami-0abcdef1234567890 \
--instance-type t3.medium \
--key-name my-key \
--security-group-ids sg-12345 \
--subnet-id subnet-12345 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web-1}]'
In production, you almost never run-instances directly. You use:
• Auto Scaling Groups — for scaling and replacement
• Launch Templates — for instance configuration
• Or skip EC2 entirely for ECS, EKS, Lambda
EC2 Pricing:
• On-demand — pay per second (with 60-second minimum on Linux)
• Reserved (1- or 3-year) — discount for commitment
• Spot — up to 90% off but can be reclaimed with 2-minute notice
• Savings Plans — flexible commitment
For learning: a t3.micro is in the free tier and fine for a personal project. Stop it when not using it.
S3 — Object Storage
S3 (Simple Storage Service) is AWS's object store. It's also become the de facto interface — many tools speak "S3-compatible API" (R2, MinIO, GCS).
S3 organizes data in buckets (top-level containers) holding objects (files). Object keys can have slashes — they LOOK like folders but it's just one flat namespace per bucket.
aws s3 mb s3://my-bucket # make bucket
aws s3 cp file.txt s3://my-bucket/path/ # upload
aws s3 ls s3://my-bucket # list
aws s3 sync ./local-dir s3://my-bucket/dir # sync directory
aws s3 rm s3://my-bucket/file.txt # delete
aws s3 rb s3://my-bucket --force # delete bucket + all contents
Storage classes — different cost/access tradeoffs:
• Standard — frequent access, all the SLAs
• Standard-IA (Infrequent Access) — 40% cheaper, retrieval costs more
• Glacier Instant Retrieval, Flexible, Deep Archive — increasingly cold, increasingly cheap, slower retrieval
S3 Intelligent-Tiering automatically moves objects between tiers based on access patterns. Often the right default for unpredictable workloads.
What S3 is amazing for:
• User uploads, generated content
• Static website hosting (point CloudFront at it)
• Backups
• Data lakes (S3 + Athena/Glue/Spark)
• Anything where "infinite scale + 11-nines durability" matters
Critical security:
• Buckets are PRIVATE by default in 2026. Was a major change after years of leaks.
• Bucket policies + IAM control access
• "Block Public Access" at account level — turn it on unless you specifically need public buckets
• Use presigned URLs (covered in Backend Module 30) for time-limited public access
Cost notes:
• Storage: $0.023/GB/month for Standard
• Requests: $0.0004 per 1000 GET, $0.005 per 1000 PUT
• Egress (out of AWS): $0.05-0.09/GB — this dominates S3 cost for content delivery
• Use CloudFront in front of S3 to reduce egress costs and improve latency
RDS — Managed Databases
RDS (Relational Database Service) runs Postgres, MySQL, MariaDB, Oracle, SQL Server for you. Aurora is AWS's own MySQL/Postgres-compatible engine — faster, more expensive, more cloud-native features.
What RDS handles:
• Provisioning the database server
• Backups (automatic, point-in-time recovery up to 35 days)
• Patching the engine
• Failover to a standby (with Multi-AZ)
• Read replicas
What you still handle:
• Schema design, queries, indexes
• Connection pooling (RDS Proxy helps but isn't free)
• Query optimization
• Application-level concerns
Key RDS concepts:
• Instance class — same families as EC2 (db.t3.medium, db.r5.large)
• Multi-AZ — sync replica in another AZ for HA. Failover in ~60s on primary failure.
• Read Replicas — async replicas, good for read-heavy workloads. Up to 15 per primary in Aurora.
• Storage — gp3 (general SSD) for most workloads; io1/io2 for high-IOPS needs.
• Aurora Serverless — auto-scales capacity. Cool, but cold-start latency.
Connecting:
aws rds describe-db-instances --query 'DBInstances[*].Endpoint.Address'
psql -h myapp.abc123.us-east-1.rds.amazonaws.com -U myapp_user -d myapp
For production:
• Always Multi-AZ
• Always automated backups (default 7 days, 35 max)
• Always restrict access via security group (only your VPC, not 0.0.0.0/0)
• Set up CloudWatch alarms (CPU, connections, replication lag)
• Test backup restoration regularly
DynamoDB — AWS's NoSQL database. Different beast. Single-digit-ms latency, infinite scale, but designed differently from relational DBs. Great for some workloads (high-volume key-value lookups, session stores), terrible for others (anything needing flexible queries). Worth learning when you have a use case for it.
Lambda — Functions as a Service
Lambda runs your code without you managing servers. Trigger from API Gateway, S3 events, scheduled cron, queue messages, and many more.
A Lambda function in Python:
import json
import boto3
s3 = boto3.client('s3')
def handler(event, context):
# Lambda hands you an event dict
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
# Do something
response = s3.get_object(Bucket=bucket, Key=key)
print(f"Processing {key}, size: {response['ContentLength']}")
return {'statusCode': 200, 'body': 'OK'}
Deploy:
zip function.zip handler.py
aws lambda create-function \
--function-name my-function \
--runtime python3.12 \
--handler handler.handler \
--role arn:aws:iam::123:role/lambda-exec \
--zip-file fileb://function.zip \
--memory-size 512 \
--timeout 30
Lambda's pricing: $0.20 per million requests + $0.0000167 per GB-second of compute. A function using 512 MB RAM, running 100ms, costs $0.0000008 per invocation. Genuinely cheap for low-volume work.
When Lambda shines:
• Event handlers (S3 uploads, DynamoDB streams, queue consumers)
• Scheduled jobs (cron replacement)
• Sporadic API endpoints (low traffic)
• Glue code between services
• Webhooks
When Lambda hurts:
• Sustained high-traffic workloads (becomes more expensive than EC2/Fargate)
• Long-running tasks (15-min execution limit)
• Cold-start sensitive workloads (first invocation can take 100ms-3s)
• Workloads needing consistent connection pools (each Lambda is separate)
Patterns:
• Lambda + API Gateway → serverless API
• Lambda + EventBridge schedule → cron jobs
• Lambda + SQS → reliable async processing
• Lambda + S3 → process uploads
• Lambda + DynamoDB Streams → react to data changes
Cold starts: Lambda spins up a new container for the first invocation after idle. Latency varies by language: Node/Python ~100-500ms, Java/.NET 1-3s. Provisioned Concurrency keeps containers warm at extra cost. SnapStart for Java reduces cold starts dramatically.
IAM — Identity and Access Management
IAM is AWS's permission system. EVERY API call hits IAM. Get IAM right and security follows; get it wrong and you have leaks.
Core concepts:
User — a human. Has long-lived credentials (password, access keys). For real humans only — not for app code.
Group — a collection of users. Permissions assigned to the group apply to all members.
Role — an identity that can be assumed. No long-lived credentials. Used by:
• EC2 instances (the instance gets temporary creds)
• Lambda functions
• Cross-account access
• Federated identities (SSO from corporate IdP)
• GitHub Actions via OIDC
Policy — a JSON document defining what's allowed. Attached to users, groups, or roles.
A simple policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
Policy structure:
• Effect: Allow / Deny
• Action: which API calls (s3:GetObject, * for all, s3:* for all S3)
• Resource: which resources (ARN patterns, * for all)
• Condition: optional, e.g. only from specific IPs, only with MFA
The principle: LEAST PRIVILEGE. Grant only what's needed.
Best practices in 2026:
• NO long-lived access keys for app code. Use IAM roles.
• Root account locked away with hardware MFA. Don't use it for daily work.
• AWS Organizations + AWS SSO for human users
• MFA on every IAM user
• Audit access regularly (IAM Access Analyzer)
• Separate accounts for prod and non-prod
• Use OIDC for CI/CD (no AWS keys in GitHub Actions)
Common pattern for an app on EC2:
1. Create IAM Role with policy granting only what app needs
2. Attach role to EC2 instance via instance profile
3. App's SDK auto-detects the role, gets temporary creds
4. App makes API calls; AWS verifies via IAM
5. No keys anywhere in your code or environment
Other Essential AWS Services
Brief tour of services you'll encounter:
VPC — Virtual networking. Covered in Module 3. Every workload runs in a VPC.
CloudFront — CDN. Caches content at edge locations worldwide. Use in front of S3, ALB, anywhere serving content.
Route 53 — DNS service. Highly available, integrates with everything (ALIAS records to ELB, CloudFront).
ELB — Elastic Load Balancing. ALB (HTTP/HTTPS), NLB (TCP/UDP), GWLB (network appliances). Covered in Module 3.
ECS / Fargate — Container orchestration. ECS is AWS's K8s alternative; Fargate runs containers serverlessly.
EKS — Managed Kubernetes. Covered in Modules 13-15.
CloudWatch — Metrics, logs, alarms. The monitoring layer for everything in AWS.
CloudFormation / CDK — Infrastructure as code. Covered later.
SQS — Managed queue. Module 13's task queues.
SNS — Pub/sub. Send a message to a topic; many subscribers receive it.
EventBridge — Event bus. Routes events between AWS services and your apps. Useful for cron-like schedules.
Secrets Manager — Stores secrets (DB passwords, API keys), rotates them automatically.
Parameter Store — Like Secrets Manager but cheaper for non-sensitive config.
KMS — Key Management Service. Encrypts data; manages encryption keys. Used by S3, RDS, EBS, etc. for at-rest encryption.
WAF — Web Application Firewall. Sits in front of ALB / CloudFront. Blocks SQL injection, bad bots, by IP.
Shield — DDoS protection. Standard tier is free; Advanced is for high-risk workloads.
GuardDuty — Threat detection. Monitors API calls and traffic for suspicious behavior.
This is the working set for 80% of AWS apps. Master these and you can build most things.
⁂ Back to all modules