# EC2

## 1. What EC2 Is

**EC2 (Elastic Compute Cloud)** rents you a virtual machine — an **instance** — by the second. Unlike owning hardware, you can launch one in minutes, resize it, or terminate it entirely, and every instance boots from an **AMI (Amazon Machine Image)**: a snapshot of an OS + pre-installed software that becomes the instance's starting disk state.

```bash
aws ec2 run-instances \
  --image-id ami-0abcdef1234567890 \
  --instance-type t3.micro \
  --subnet-id subnet-0111 \
  --security-group-ids sg-0app \
  --iam-instance-profile Name=AppInstanceProfile \
  --key-name my-keypair
```

![An EC2 instance runs continuously and is billed the whole time, while Lambda runs only per invocation with cold starts when no warm container exists](diagrams/01-ec2-vs-lambda.svg)

## 2. Instance Types and Sizing

Instance types encode a **family** (workload shape) and a **size** (vCPU/RAM amount): `t3.micro`, `m5.large`, `c5.xlarge`, `r5.2xlarge`.

| Family prefix | Optimized for |
|---|---|
| `t` | Burstable general purpose (cheap, CPU credits) |
| `m` | Balanced general purpose |
| `c` | Compute-heavy (CPU-bound workloads) |
| `r` | Memory-heavy (in-memory caches, big datasets) |

Doubling the size suffix (`large` -> `xlarge` -> `2xlarge`) roughly doubles vCPU and RAM together — you don't tune them independently within one family.

## 3. AMIs

An AMI is a template: root volume snapshot + block device mapping + architecture + launch permissions. AWS publishes official AMIs (Amazon Linux, Ubuntu...), or you bake your own **custom AMI** from a configured instance so every new launch starts pre-installed and pre-configured, instead of running a bootstrap script on every boot.

## 4. Launching: Where an Instance Actually Lives

Every instance launches into exactly one **subnet** (from `02-vpc_subnets_route_tables`), which determines whether it's reachable from the internet (public subnet + public IP) or not (private subnet). It also gets:

- One or more **security groups** (stateful firewall — its own topic, `09-security_groups`) controlling what traffic reaches it
- Optionally, an **IAM instance profile** (from `01-fundamentals_and_iam`) — the mechanism that hands the instance a *role*, not long-lived credentials
- A **key pair** for SSH (Linux) or to decrypt the Administrator password (Windows)

```bash
aws ec2 run-instances --subnet-id subnet-private-a --no-associate-public-ip-address ...
# instance lands in a private subnet: no public IP, unreachable from the internet directly
```

## 5. Instance Lifecycle

```
pending -> running -> [stopping -> stopped -> pending -> running]* -> shutting-down -> terminated
```

- **Stop**: the instance halts, but its EBS root volume (by default) persists — restart it later and your disk state is exactly as you left it. A stopped instance's **public IP is released** unless you attached a persistent Elastic IP; its private IP and EBS volumes survive.
- **Terminate**: permanent. Any EBS volume with `DeleteOnTermination=true` (the default for the root volume) is destroyed with the instance.
- **Instance store** volumes (physically attached to the host, not EBS) are lost on *stop* too, not just terminate — a common surprise for anyone assuming "stop" always preserves everything.

## 6. EBS: Attached Block Storage

**EBS (Elastic Block Store)** volumes are network-attached disks, independent of the instance's own lifecycle unless `DeleteOnTermination` says otherwise. A volume can be detached from one instance and reattached to another, and EBS snapshots (point-in-time, incremental) back up a volume's contents to S3 under the hood.

## 7. User Data: Bootstrapping at Launch

```bash
aws ec2 run-instances --user-data file://bootstrap.sh ...
```
```bash
#!/bin/bash
# bootstrap.sh — runs once, as root, on first boot only
yum install -y nginx
systemctl enable --now nginx
```

User data is how a from-scratch AMI becomes a configured, running service without manual login — the same mechanism an Auto Scaling Group (`11-scalability_and_monitoring`) relies on to bring up identical new instances unattended.

## 8. Under the Hood: The Instance Metadata Service

An instance profile doesn't inject credentials into environment variables or files — the instance queries a link-local HTTP endpoint only reachable from inside itself:

```bash
# from inside the instance:
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/AppInstanceProfile
# returns short-lived AccessKeyId/SecretAccessKey/SessionToken, auto-rotated by AWS before expiry
```

This is IMDSv2: the token-gated version, required (in modern accounts) specifically to prevent a server-side-request-forgery (SSRF) vulnerability in application code from silently proxying an attacker's request straight to `169.254.169.254` and handing over the instance's role credentials. The AWS SDK's default credential chain checks this endpoint automatically — it's why code running on an EC2 instance with an attached role needs zero explicit credential configuration.

## 9. Common Pitfalls

1. **Assuming "stop" preserves everything.** Public IPs (unless Elastic) and instance-store data are lost on stop, not just terminate.
2. **Hardcoding access keys into an application instead of using an instance profile.** The instance profile role (via IMDS) removes the need for any secret to leak in the first place.
3. **Launching into a public subnet by default out of habit.** Most application/database tiers belong in private subnets, reachable only through a load balancer or bastion.
4. **Undersizing/oversizing by guessing.** `t`-family burstable instances throttle hard once CPU credits run out under sustained load — fine for bursty traffic, wrong for steady CPU-bound work.
5. **Forgetting `DeleteOnTermination` on non-root volumes**, leaving orphaned EBS volumes (and their cost) behind after terminating instances.

## 10. Quick Reference

| Concept | Key fact |
|---|---|
| AMI | boot template: OS + software + block device mapping |
| Instance type | family (workload shape) + size (vCPU/RAM) |
| Stop | halts, EBS root persists, public IP released unless Elastic |
| Terminate | permanent; `DeleteOnTermination` volumes destroyed with it |
| User data | one-time boot script, root, first launch only |
| Instance profile | hands the instance a role via IMDS — no hardcoded keys |
| IMDSv2 | token-gated metadata endpoint, mitigates SSRF credential theft |

```bash
aws ec2 describe-instances --instance-ids i-0123456789abcdef0
aws ec2 stop-instances --instance-ids i-0123456789abcdef0
aws ec2 terminate-instances --instance-ids i-0123456789abcdef0
```
