Launch checklist
A launch needs an AMI, instance type, key pair, Security Group, subnet, storage, and optional user data. The AMI determines the OS and CPU architecture; the subnet determines network placement and AZ. A public IP changes after stop/start, while an Elastic IP is stable until you release it.
flowchart LR A["AMI<br/>Amazon Linux 2023"] --> T["Instance type<br/>t3.micro"] T --> N["Subnet + SG<br/>AZ 1a, sg-web"] N --> V["Storage<br/>gp3 root volume"] V --> U["User data<br/>cloud-init script"] U --> R["Running instance<br/>i-0a1b2c3d"] %% step A: The AMI provides the operating system, architecture and pre-installed software. %% step T: The type decides CPU and memory. %% step N: The subnet picks the VPC, AZ and whether it can get a public IP; the SG decides allowed ports. %% step V: The root EBS volume is created from the AMI's snapshot. %% step U: On first boot, cloud-init runs the user data script, for example to install nginx. %% step R: The instance reaches running and passes its status checks.
Storage choices
EBS is network-attached block storage and persists through a stop. The root EBS volume is deleted on termination according to DeleteOnTermination (true by default for root); extra volumes default to false and remain. Instance Store is fast and host-attached, but its data is lost on stop, hibernation, or termination.
User data
User data is a script run by cloud-init on the first boot only (unless you configure otherwise). It is not an automatic redeployment mechanism. A typical example:
#!/bin/bash
dnf install -y nginx
systemctl enable --now nginx
User data is limited to 16 KB and is visible to anyone who can read the instance attributes, so never put passwords in it; fetch secrets from Secrets Manager or Parameter Store using the instance role. If the script fails, read /var/log/cloud-init-output.log.
Instance metadata
Instance metadata exposes local instance facts — instance ID, AZ, IPs, the role's temporary credentials — at 169.254.169.254, reachable only from inside the instance.
Prefer IMDSv2: obtain a token with PUT, then include that token in the metadata request header. Tokens reduce the risk of unintended requests, such as an SSRF bug in a web app, reaching metadata and stealing role credentials. New AMIs such as Amazon Linux 2023 default to IMDSv2-only; you can enforce it with --metadata-options HttpTokens=required.
TOKEN=$(curl -s -X PUT http://169.254.169.254/latest/api/token -H "X-aws-ec2-metadata-token-ttl-seconds: 300")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id
Launch templates
A launch template saves all these settings as a versioned object. Auto Scaling groups require one, and it makes manual launches repeatable.
| Command | Purpose |
|---|---|
aws ec2 run-instances --image-id ami-0a1b2c3d --instance-type t3.micro --key-name training-key --subnet-id subnet-0a1b2c3d --security-group-ids sg-0a1b2c3d |
Launch an instance with explicit settings |
aws ec2 create-launch-template ... |
Save settings for reuse |
curl -X PUT .../latest/api/token |
Obtain an IMDSv2 token |
Traps: expecting user data to run on every reboot; putting secrets in user data; assuming the public IP survives a stop.