EC2 Essentials
Compute · ENI · EBS · AMI · Key Pairs · Security Groups · Elastic IP · Lifecycle · Placement Groups · CLI
Part of my AWS learning journey — transitioning from Systems Engineer to Cloud/DevOps. EC2 is the foundation of AWS compute — understanding it deeply makes everything else make sense.
📋 Topics Covered
| # | Topic | Type |
|---|---|---|
| 1 | What is EC2 & Why Named EC2 | Concept |
| 2 | EC2 Instance Types & Families | Concept + Cert |
| 3 | AWS Compute Optimizer | Concept + DevOps |
| 4 | Elastic Network Interface (ENI) | Concept + Interview |
| 5 | Amazon EBS — Persistent Storage | Concept + Lab |
| 6 | EBS Volume Types & IOPS | Concept + Cert |
| 7 | EBS Snapshots & Cross-Region Copy | Concept + Lab |
| 8 | EBS Multi-Attach & Encryption | Concept + Cert |
| 9 | EBS vs S3 | Concept + Interview |
| 10 | Instance Store — Temporary Storage | Concept + Cert |
| 11 | AMI — Types, Selection & Sharing | Concept + Lab |
| 12 | EC2 Key Pairs | Concept + Lab |
| 13 | Security Groups | Concept + Interview |
| 14 | Elastic IP & Billing Estimation | Concept + Lab |
| 15 | EC2 Lifecycle — Start, Stop, Hibernate, Terminate | Concept + Cert |
| 16 | EC2 Status Checks | Concept + Cert |
| 17 | EC2 Placement Groups | Concept + Cert |
| 18 | AWS CLI — Installation, Config & EC2 Commands | Practical |
| 19 | boto3 — Python SDK for EC2 | Practical |
| 20 | Lab 1 — Launch EC2 as Web Server with User Data | Lab |
| 21 | Lab 2 — EC2 + S3 Access via Instance Profile | Lab |
| 22 | Lab 3 — EC2 Resize & EBS Volume Resize | Lab |
| 23 | Lab 4 — Custom AMI Creation & Validation | Lab |
| 24 | Lab 5 — EBS Snapshot Cross-Region Copy | Lab |
What is EC2 & Why Named EC2
Before cloud, running an application meant buying a physical server — weeks of procurement, rack installation, OS setup, then maintenance forever. EC2 changed that entirely.
EC2 = Elastic Compute Cloud — a virtual server running on AWS hardware that you can provision in minutes, pay for by the second, and terminate when done.
Why "Elastic Compute Cloud"? The "2" in EC2 is simply because "Elastic Compute Cloud" has two C's — it's a playful naming convention. More meaningfully: Elastic because it scales on demand (up or down, instantly), Compute because it provides raw processing power, and Cloud because it's delivered over the internet from AWS data centers.
The name breaks down:
- E — Elastic → scale up or down on demand, any time
- C — Compute → processing power (CPU, RAM, GPU) for your workloads
- C — Cloud → delivered over the internet from AWS data centers, not from your office
EC2 Instance Types — Choosing the Right Size
Every EC2 instance has a type — a predefined combination of CPU, RAM, storage, and network capacity. AWS groups them into families, each optimized for a different workload.
Analogy: Instance types are like vehicles. You don't drive a truck to pick up groceries, and you don't use a hatchback to transport 10 tonnes of cargo. Right tool for the right job.
| Family | Examples | Optimized For | Real Use Case |
|---|---|---|---|
| General Purpose | t3, m6i | Balanced CPU + RAM | Web servers, small databases, dev environments |
| Compute Optimized | c5, c6g | High CPU | Batch processing, ML inference, gaming servers |
| Memory Optimized | r5, x2 | Large RAM | In-memory databases, Redis, SAP HANA |
| Storage Optimized | i3, i4i | Fast local NVMe disk | NoSQL databases, data warehousing, Elasticsearch |
| Accelerated Computing | p3, g4dn | GPU | ML training, video rendering, scientific computing |
Instance naming — how to read it:
t3.medium→t= family (general purpose, burstable) ·3= generation (higher = newer, better price/performance) ·medium= size (nano → micro → small → medium → large → xlarge → 2xlarge...)
Free Tier: t2.micro or t3.micro — 750 hours/month for 12 months. Use this for all labs.
🎯 Cert tip: SAA-C03 frequently gives a scenario and asks which instance family fits. Know the families — especially General Purpose (t/m), Compute (c), Memory (r), Storage (i/d), GPU (p/g).
AWS Compute Optimizer
If you already have EC2 running in production and want to know if you're over or under-provisioned, AWS Compute Optimizer analyses your actual CloudWatch utilization data and recommends the optimal instance type.
For example: you launched a
c5.2xlargefor a web server, but Compute Optimizer sees CPU is consistently at 8% — it recommends at3.mediumat 60% lower cost.
Useful in production cost reviews. Not needed during initial setup or learning.
ENI — Elastic Network Interface
ENI = Elastic Network Interface — the virtual network card that gives your EC2 instance its network identity. Every EC2 instance gets a primary ENI automatically at launch.
Analogy: ENI is like a SIM card in a phone. The phone (EC2) needs the SIM (ENI) to have a phone number (IP address), connect to a network, and send/receive data. The SIM can be moved to a different phone — and the phone number comes with it.
What an ENI carries:
| Attribute | What it is |
|---|---|
| Private IPv4 | Internal IP within your VPC — always present, never changes |
| Public IPv4 | Internet-facing IP — assigned if enabled, changes on stop/start |
| Elastic IP | Static public IP you allocate separately — doesn't change |
| IPv6 | Optional, if the VPC has IPv6 enabled |
| MAC Address | Unique hardware identifier — used for software licensing |
| Security Groups | Firewall rules — applied at the ENI level, not the instance level |
Why ENI lives at the interface level (not instance level):
Security Groups and IPs are properties of the ENI, not the EC2 instance directly. When you "change the security group on an EC2," you're actually changing it on the primary ENI. This distinction matters when you have multiple ENIs on one instance — each can have different security groups.
Why multiple ENIs on one instance:
- Separate management traffic from application traffic (e.g., one ENI on a private subnet, one on a management subnet)
- Move a network identity from a failed instance to a healthy one — the Elastic IP and Security Groups travel with the ENI
🎯 Interview tip: "How do you move an Elastic IP from a failed EC2 to a replacement instance with zero client-side change?" — Detach the ENI from the failed instance and attach it to the replacement. Or disassociate and reassociate the Elastic IP. The client's connection target never changes.
EBS — Persistent Storage for EC2
EBS = Elastic Block Store — the hard disk for your EC2 instance. It's where your OS, application files, and data live.
Analogy: EC2 is your laptop. EBS is the hard drive inside it. If you sell the laptop (terminate EC2), you can remove the hard drive first (detach EBS) and plug it into a new laptop (attach to new EC2). The data stays intact.
Key characteristics:
- Persistent — data survives EC2 stop/restart (unlike Instance Store)
- Network-attached — connected via high-speed AWS network, not physically inside the EC2 host
- AZ-locked — lives in one specific AZ, can only attach to EC2 in the same AZ
- Replicated within AZ — AWS replicates within the AZ for durability (not cross-AZ)
- Independently scalable — you can resize EBS without replacing the EC2 instance
EBS Volume Types
| Type | IOPS | Throughput | Best For |
|---|---|---|---|
| gp3 (General Purpose SSD) | 3,000–16,000 | Up to 1,000 MB/s | Default choice for most workloads |
| gp2 (Legacy General Purpose SSD) | Up to 16,000 | 250 MB/s | Older default — prefer gp3 for new volumes |
| io2 (Provisioned IOPS SSD) | Up to 64,000 | 1,000 MB/s | High-performance databases, SAP, Oracle |
| st1 (Throughput Optimized HDD) | N/A | Up to 500 MB/s | Big data, log processing, Kafka |
| sc1 (Cold HDD) | N/A | Up to 250 MB/s | Infrequent access, archival, cheapest |
IOPS = Input/Output Operations Per Second — how many read/write operations your storage handles per second.
Analogy: IOPS is like a highway's capacity. gp3 is a 4-lane road — handles normal traffic well. io2 is a 10-lane expressway — built for when hundreds of database queries are rushing through every second.
🎯 Cert tip: gp3 = default choice. io2 = high-IOPS databases. The difference between gp3 and gp2: gp3 allows you to independently set IOPS and throughput (not tied to volume size like gp2). Always choose gp3 for new volumes.
EBS Snapshots
A Snapshot is a point-in-time backup of your EBS volume, stored in S3 (you don't see the S3 bucket — AWS manages it internally).
- Incremental — first snapshot is a full copy. Each subsequent snapshot only stores what changed since the last one. Saves significant cost and time.
- Cross-AZ/Region capable — a snapshot in Mumbai can be used to create a volume in Singapore
- AMI source — custom AMIs are built from snapshots
- No instance downtime required — snapshots can be taken while the instance is running
When to take snapshots:
- Before making any significant change to your server (patching, config changes)
- Before terminating an instance that has data you might need
- Scheduled backups for production systems (use AWS Backup for automation)
- When copying data to another AZ or Region
🎯 Cert scenario: "How do you move EBS data to a different AZ?" — EBS is AZ-locked so you can't move it directly. Take a snapshot → create a new volume from the snapshot in the target AZ → attach to the EC2 in that AZ.
EBS Multi-Attach
Normally: one EBS volume → one EC2 instance. Multi-Attach breaks this rule for specialized workloads.
- Only available on io1 or io2 volumes
- Attach one volume to up to 16 EC2 instances simultaneously within the same AZ
- Requires a cluster-aware file system (Oracle OCFS2, GFS2) — standard Linux file systems like ext4 or xfs cannot handle concurrent writes safely
- Use case: clustered high-availability databases
🎯 Interview tip: "Can two EC2 instances share the same EBS volume?" → Yes, but only with io1/io2 Multi-Attach, only in the same AZ, and only with a cluster-aware file system.
EBS Encryption
- Encrypts data at rest (stored on disk) and in transit (moving between EC2 and EBS over the network)
- Uses AWS KMS keys — either AWS-managed or customer-managed
- Zero performance impact — encryption/decryption happens transparently in hardware
- Snapshots of encrypted volumes are automatically encrypted
- Can be enabled as account-level default — all new volumes encrypted automatically
EBS vs S3 — The Common Confusion
| EBS | S3 | |
|---|---|---|
| Type | Block storage (like a hard disk) | Object storage (like file storage) |
| Access | Attached to one EC2 instance | Via API/URL from anywhere |
| Use For | OS, databases, application files | Images, videos, backups, static sites |
| Scope | AZ-specific | Region-wide, globally accessible |
| Persistence | Survives stop/restart | Permanent until you delete |
| Analogy | Internal hard drive | Google Drive in the cloud |
Instance Store — Fast but Temporary
Instance Store is physical storage built directly into the EC2 host machine. It's not a separate network volume — it's the actual spinning disk or NVMe SSD on the physical server your EC2 runs on.
Analogy: Instance Store is RAM in your laptop — extremely fast because it's physically right there, but completely wiped when you turn off the machine.
| Instance Store | EBS | |
|---|---|---|
| Speed | Very high (physically attached) | High (network-attached) |
| Persistence | ❌ Lost on stop/terminate/host failure | ✅ Persists |
| Cost | Included with certain instance types | Charged separately per GB |
| Use Case | Temporary buffers, caches, scratch space | OS, databases, any persistent data |
⚠️ Never store anything you need long-term on Instance Store. If the instance stops, terminates, or the underlying hardware fails — data is gone with zero recovery path. This includes planned stops, not just crashes.
AMI — Amazon Machine Image
AMI = Amazon Machine Image — a pre-built template containing everything needed to launch an EC2 instance: the OS, installed software, configuration, and the root volume snapshot.
Analogy: AMI is like a cookie cutter. Once you have the perfect cookie shape (your configured server), you can stamp out identical copies as many times as you want, instantly.
AMI Types — EBS-Backed vs Instance Store-Backed
| EBS-Backed AMI | Instance Store-Backed AMI | |
|---|---|---|
| Root volume | EBS snapshot | S3-stored template |
| Can stop instance? | ✅ Yes | ❌ No — can only terminate |
| Boot time | Faster | Slower |
| Persistence | Root data survives stop | Root data lost on stop |
| Use for | Everything — production, dev, test | Legacy workloads |
✅ Always use EBS-backed AMIs. Instance Store-backed is legacy and rarely used today.
AMI Sources
| Source | What it is |
|---|---|
| AWS Provided | Amazon Linux 2/2023, Ubuntu, Windows — official, regularly patched |
| AWS Marketplace | Pre-built commercial or open-source AMIs (WordPress, Nginx, Oracle) |
| Community AMIs | Shared by other AWS users — use with caution, verify before use |
| Custom AMI | You build from a configured EC2 instance — your exact setup, reusable |
AMI Selection
When choosing an AMI, consider:
- OS — Amazon Linux 2023 for AWS-optimized workloads, Ubuntu for developer familiarity
- Architecture — x86_64 (most common) vs arm64 (Graviton — cheaper, better price/performance)
- Virtualization — HVM (hardware virtual machine) — the only current option for modern instances
- Region — AMIs are Region-specific. Same AMI ID doesn't exist in another Region
AMI Sharing
AMIs can be shared in three ways:
Private (default): Only your account can use it.
Shared with specific accounts: You provide AWS account IDs — only those accounts can launch from your AMI. Common in multi-account organizations (share a golden image from a build account to all environment accounts).
Public: Anyone in any AWS account can use it. This is how community AMIs work.
Important: When you share an AMI, you're sharing the snapshot permissions, not the data itself. The recipient can launch instances from your AMI but cannot access your original snapshot directly.
Encryption + Sharing caveat: If your AMI is encrypted with a KMS key (Customer Managed Key), you must also share that KMS key with the target account — otherwise they can't decrypt the snapshot to launch from it. AWS-managed keys cannot be shared across accounts, so encrypted AMIs shared across accounts must use Customer Managed KMS keys.
AMI is Region-specific — to use in another Region:
EC2 Console → AMIs → select AMI → Actions → Copy AMI → choose target Region → Copy. A new AMI ID is created in the target Region.
EC2 Key Pairs
A Key Pair is a public-private cryptographic pair used to authenticate to EC2 without a password.
How it works:
You create a Key Pair in AWS Console.
AWS stores the public key on your EC2 instance (in~/.ssh/authorized_keys).
You download the private key — a.pemfile. Once only. Never again.
To connect:ssh -i my-key.pem ec2-user@<public-ip>
EC2 verifies: "Does this private key match my public key?" → Yes → Access granted.
Access methods by OS:
-
Linux/Mac: SSH with
.pemfile -
Windows: Convert
.pemto.ppkfor PuTTY, or use Windows native SSH (newer versions) - Browser (EC2 Instance Connect): No key needed — direct from Console, works for Amazon Linux and Ubuntu
⚠️ If you lose your
.pemfile, you lose SSH access permanently. AWS has no recovery path. Store it safely. Never check it into Git. Never share it.
Security Groups
A Security Group is a stateful virtual firewall that controls what traffic can reach your EC2 instance — applied at the ENI level.
Analogy: A Security Group is the bouncer at a club entrance. You give the bouncer a list of rules — only people matching the list get in. Everyone else is turned away by default.
Default behaviour:
- Inbound: deny all — nothing gets in unless explicitly allowed
- Outbound: allow all — everything can leave
Stateful — what this means:
If you allow inbound traffic on port 80, the response traffic automatically goes out — you don't need a separate outbound rule for it. The Security Group tracks the connection and knows the response belongs to an allowed inbound request.
Common rules:
| Purpose | Protocol | Port | Source |
|---|---|---|---|
| SSH access | TCP | 22 | Your IP only (never 0.0.0.0/0 in production) |
| Web server (HTTP) | TCP | 80 | 0.0.0.0/0 (public) |
| Web server (HTTPS) | TCP | 443 | 0.0.0.0/0 (public) |
| Windows RDP | TCP | 3389 | Your IP only |
| Database (MySQL) | TCP | 3306 | App server's Security Group |
⚠️ Never open port 22 to 0.0.0.0/0 in production. Bots scan the entire internet for open SSH ports constantly. Restrict SSH to your specific IP or use a Bastion Host.
🎯 Interview tip: "Difference between Security Group and NACL?" — Security Group is stateful, operates at the instance/ENI level, Allow rules only. NACL is stateless, operates at the subnet level, Allow and Deny rules. Security Groups are your first layer; NACLs are a second optional layer.
Elastic IP & Billing Estimation
Elastic IP
By default, when you stop and restart an EC2 instance, its public IP changes. This breaks DNS, client configurations, and whitelists.
Elastic IP solves this — a static public IPv4 address that stays assigned to your account until you release it.
Pricing — the trap people fall into:
- ✅ Free when associated with a running EC2 instance
- ❌ Charged (~$0.005/hr ≈ ₹0.40/hr) when allocated but not associated or associated with a stopped instance
⚠️ Always release Elastic IPs after labs. An unattached Elastic IP silently charges you every hour. AWS charges for idle IPs to discourage hoarding of public IPv4 addresses.
Steps:
Allocate: EC2 Console → Elastic IPs → Allocate Elastic IP Address → Allocate
Associate: Select the Elastic IP → Actions → Associate → choose Instance → Associate
Disassociate: Select the Elastic IP → Actions → Disassociate
Release (stop charges): Select the Elastic IP → Actions → Release Elastic IP Address
Billing Estimation
Before deploying anything in AWS, estimate the cost first using AWS Pricing Calculator at calculator.aws.
How to use:
Go to calculator.aws → Create estimate → Add service (EC2) → Select Region (ap-south-1) → Choose instance type, OS, and hours per month → Add EBS storage → Add data transfer if needed → View monthly estimate
Key EC2 billing components:
| Component | How Charged |
|---|---|
| Instance compute | Per second (minimum 60 seconds), based on instance type + OS |
| EBS storage | Per GB-month (charged even when instance is stopped) |
| EBS snapshots | Per GB-month stored in S3 |
| Elastic IP (idle) | Per hour when not attached to a running instance |
| Data transfer OUT | Per GB leaving AWS to the internet |
Three pricing models:
| Model | Commitment | Savings | Use When |
|---|---|---|---|
| On-Demand | None | 0% | Learning, unpredictable workloads |
| Reserved Instances | 1–3 years | 30–70% | Steady production workloads running 24/7 |
| Spot Instances | None (can be interrupted) | Up to 90% | Batch jobs, fault-tolerant workloads |
EC2 Lifecycle — Start, Stop, Hibernate, Terminate
Every EC2 instance goes through states. Understanding what each state means for billing and data is critical.
State flow:
Launch → Pending (starting up, not billed yet) → Running (operational, billed per second) → Stopping → Stopped (EBS still billed, compute not billed, can restart) → Terminated (deleted forever, not recoverable)
| State | Compute Billing | EBS Billing | Data Preserved | Recoverable |
|---|---|---|---|---|
| Running | ✅ Yes | ✅ Yes | Yes | — |
| Stopped | ❌ No | ✅ Yes | EBS data yes, RAM no | ✅ Yes |
| Hibernated | ❌ No | ✅ Yes | EBS + RAM (to disk) | ✅ Yes |
| Terminated | ❌ No | ❌ No (deleted) | ❌ No | ❌ Never |
EC2 Hibernate
Hibernate is like putting your laptop to sleep — the instance pauses, RAM contents are written to the EBS root volume, and when you start it again, the OS resumes exactly where it left off.
Why it exists:
Stop: OS shuts down → restart boots the OS from scratch → applications restart → takes time
Hibernate: RAM saved to EBS → restart restores RAM → OS and applications resume instantly → no boot time
Requirements for Hibernate:
- Root EBS volume must be encrypted (required — RAM contents are sensitive)
- Root EBS must have enough free space to hold all RAM contents
- Instance must be configured to allow hibernation at launch (can't enable after launch)
- Maximum hibernate duration: 60 days
- Not available on all instance types — check AWS documentation
Use case: Long-running processes that are expensive to restart (ML training checkpoints, complex application states, developer environments you want to resume quickly).
EC2 Status Checks
AWS automatically runs health checks on every EC2 instance every minute.
System Status Check — checks the AWS infrastructure (power, network, hardware host)
- If this fails: problem is on AWS's side — the physical host has an issue
- Fix: Stop and Start the instance. This moves it to a new physical host. Do NOT just reboot — that keeps it on the same failing host.
Instance Status Check — checks the OS and software inside your EC2
- If this fails: problem is inside your instance — OS crashed, kernel panic, file system corruption
- Fix: Reboot the instance to restart the OS, or SSH in and fix the issue directly
EBS Volume Status Check — checks attached EBS volumes for IO impairment
- If this fails: EBS volume is degraded and not serving reads/writes properly
- Fix: Detach and reattach the volume, or restore from snapshot
🎯 Classic cert question: "Your EC2 system status check fails. What do you do?" → Stop and Start (NOT Reboot). Reboot keeps it on the same host and won't fix a hardware-level failure.
CloudWatch Integration: Set alarms on status checks to trigger automatic recovery actions — this is how production systems self-heal without human intervention.
EC2 Placement Groups
When you launch multiple EC2 instances, AWS decides where to place them on physical hardware. Placement Groups let you control this placement strategy.
Three strategies:
Cluster — all instances packed tightly in one AZ, on hardware physically close together
- Ultra-low latency between instances, highest network throughput (up to 10 Gbps between instances)
- Risk: if the rack fails, all instances are affected
- Use for: HPC (High Performance Computing), ML training requiring fast inter-node communication, Hadoop/Spark jobs
Spread — each instance on a separate physical rack, even separate data centers within an AZ
- Maximum fault isolation — rack failure only affects one instance
- Limit: max 7 instances per AZ per Spread placement group
- Use for: small groups of critical instances that absolutely cannot fail together (master nodes, critical databases)
Partition — instances grouped into partitions (groups of racks), each partition isolated from others
- Balance of performance and fault isolation
- Each partition can have many instances; partitions don't share hardware
- Use for: Hadoop, Kafka, Cassandra, HBase — distributed systems with many nodes per logical group
Analogy:
- Cluster = teammates at the same table — fast communication, but one fire affects all
- Spread = teammates in different buildings — isolated, but limited seats per building
- Partition = teammates on different floors of the same building — grouped but isolated from other floors
🎯 Cert scenarios: "Lowest latency between instances" → Cluster. "7 critical instances must never fail together" → Spread. "200-node Kafka cluster with fault isolation" → Partition.
AWS CLI — Installation, Config & EC2 Commands
AWS CLI lets you control all AWS services from your terminal. Essential for DevOps — no Console clicking, full automation capability.
Installation:
# Linux/Mac
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version
Configuration:
aws configure
# AWS Access Key ID: [your key]
# AWS Secret Access Key: [your secret]
# Default region name: ap-south-1
# Default output format: json
Credentials stored in ~/.aws/credentials and config in ~/.aws/config.
⚠️ Never hardcode credentials in scripts or push to GitHub. For EC2 accessing AWS services, use IAM Roles with Instance Profiles — no credentials on the instance at all.
Common EC2 CLI commands:
# List all instances (all states)
aws ec2 describe-instances
# List only running instances
aws ec2 describe-instances --filters "Name=instance-state-name,Values=running"
# Launch a new instance
aws ec2 run-instances \
--image-id ami-0f5ee92e2d63afc18 \
--instance-type t2.micro \
--key-name my-key-pair \
--security-group-ids sg-0123456789abcdef0
# Stop an instance
aws ec2 stop-instances --instance-ids i-1234567890abcdef0
# Start an instance
aws ec2 start-instances --instance-ids i-1234567890abcdef0
# Terminate an instance
aws ec2 terminate-instances --instance-ids i-1234567890abcdef0
# Describe security groups
aws ec2 describe-security-groups
# Create a snapshot
aws ec2 create-snapshot \
--volume-id vol-0123456789abcdef0 \
--description "Pre-migration backup"
# Copy snapshot to another region
aws ec2 copy-snapshot \
--source-region ap-south-1 \
--source-snapshot-id snap-0123456789abcdef0 \
--region us-east-1 \
--description "Cross-region copy"
boto3 — Python SDK for EC2
boto3 is the AWS SDK for Python — write scripts that interact with EC2 (and all AWS services) programmatically.
pip install boto3
import boto3
ec2 = boto3.resource('ec2', region_name='ap-south-1')
# List all EC2 instances and their states
for instance in ec2.instances.all():
print(f"ID: {instance.id} | Type: {instance.instance_type} | State: {instance.state['Name']}")
# Stop a specific instance
instance = ec2.Instance('i-1234567890abcdef0')
instance.stop()
print("Instance stopped")
# Start a specific instance
instance.start()
print("Instance started")
# Create a snapshot of a volume
ec2_client = boto3.client('ec2', region_name='ap-south-1')
snapshot = ec2_client.create_snapshot(
VolumeId='vol-0123456789abcdef0',
Description='Automated daily backup'
)
print(f"Snapshot created: {snapshot['SnapshotId']}")
🎯 DevOps use: Auto-start/stop instances on a schedule (Lambda + EventBridge), automated AMI creation before deployments, custom health check dashboards. This is where your Python-for-DevOps foundation connects directly to AWS infrastructure.
🧪 Lab 1 — Launch EC2 as Web Server with User Data
Objective: Launch an EC2 instance that automatically installs and starts Apache on first boot, serving a custom webpage — without any manual SSH setup.
Steps:
EC2 Console → Launch Instance
Name:
lab-webserver
AMI: Amazon Linux 2023 (64-bit x86)
Instance type: t2.micro (Free Tier)
Key pair: create new →lab-key→ download.pem
Security Group: Create newlab-sg
Inbound rules: HTTP (80) from 0.0.0.0/0 · SSH (22) from My IPAdvanced details → User Data → paste:
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/instance-id)
AZ=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/placement/availability-zone)
cat > /var/www/html/index.html << EOF
<!DOCTYPE html>
<html>
<body style="font-family:Arial;text-align:center;padding:60px;background:#0A1628;color:#fff;">
<h1 style="color:#FF9900;">Hello from EC2!</h1>
<p>Instance ID: <b style="color:#FF9900;">$INSTANCE_ID</b></p>
<p>Availability Zone: <b style="color:#FF9900;">$AZ</b></p>
</body>
</html>
EOF
Launch → wait 2–3 minutes → copy Public IP → open in browser
Expected: a webpage showing your Instance ID and AZ ✅
What to verify:
- Page loads via HTTP on port 80 ✅
- Instance ID and AZ are real values from the metadata service ✅
- SSH works:
ssh -i lab-key.pem ec2-user@<public-ip>✅ -
systemctl status httpdshows Apache is running and enabled ✅
🧪 Lab 2 — EC2 + S3 Access via Instance Profile
Objective: Attach an IAM Role to an EC2 instance so it can access S3 without any credentials configured on the instance.
Steps:
Step 1 — Create S3 bucket
S3 Console → Create bucket →iam-lab-bucket-[yourname]→ CreateStep 2 — Upload a test file
Upload atest.txtfile with some text contentStep 3 — Create IAM Role for EC2
IAM → Roles → Create Role → AWS Service → EC2
Attach:AmazonS3ReadOnlyAccess
Name:EC2-S3-ReadOnly-Role→ CreateStep 4 — Attach role during EC2 launch (or modify existing)
Launch EC2 → Advanced Details → IAM Instance Profile →EC2-S3-ReadOnly-Role
OR on existing: EC2 → Actions → Security → Modify IAM Role → select role → UpdateStep 5 — SSH into EC2 and test
# List buckets — no aws configure needed
aws s3 ls
# → your bucket appears ✅
# Download the test file
aws s3 cp s3://iam-lab-bucket-[yourname]/test.txt .
cat test.txt
# → file contents displayed ✅
# Try to write — should fail (ReadOnly policy)
aws s3 cp test.txt s3://iam-lab-bucket-[yourname]/write-test.txt
# → AccessDenied ✅ (Least Privilege working correctly)
What this proves: EC2 accessed S3 using temporary credentials from the Instance Profile and Metadata Service. Zero aws configure, zero hardcoded keys. The AccessDenied on write proves the policy boundary is real.
🧪 Lab 3 — EC2 Resize & EBS Volume Resize
Objective: Change an EC2 instance type and expand an EBS volume without data loss.
Part A — Resize EC2 Instance Type
Step 1: Stop the instance (cannot resize while running)
EC2 → Select instance → Instance State → Stop → wait for Stopped stateStep 2: Change instance type
Actions → Instance Settings → Change Instance Type → selectt2.small→ ApplyStep 3: Start the instance
Instance State → StartStep 4: Verify
Instance Type column showst2.small✅
SSH in and confirm the instance is fully operational ✅
Part B — Resize EBS Volume (Online — No Downtime)
Step 1: Modify the EBS volume
EC2 → Volumes → select the root volume → Actions → Modify Volume
Change size from 8 GiB to 16 GiB → Modify → confirm
Wait for state to showoptimizingthencompletedStep 2: Extend the file system inside EC2 (OS doesn't automatically see the new space)
SSH into the running instance:
# Check current disk usage
df -h
# Check the block device (the volume expanded, filesystem hasn't yet)
lsblk
# Grow the partition (for nvme-based instances like t3)
sudo growpart /dev/xvda 1
# or for newer instances:
sudo growpart /dev/nvme0n1 1
# Extend the filesystem
sudo xfs_growfs / # Amazon Linux 2023 uses XFS
# or for ext4:
sudo resize2fs /dev/xvda1
# Verify new size
df -h
Expected: df -h now shows ~16 GB instead of 8 GB ✅
Key insight: EBS can be expanded without stopping the instance or losing data. But the OS must be told to use the new space — just expanding the volume doesn't automatically extend the file system.
🧪 Lab 4 — Custom AMI Creation & Validation
Objective: Configure an EC2 instance, create a custom AMI from it, and launch a new instance from that AMI to verify it inherits all customizations.
Steps:
Step 1: Configure a base EC2 instance
Launch EC2 (Amazon Linux 2023, t2.micro)
SSH in and customize:
sudo yum update -y
sudo yum install -y nginx git
sudo systemctl start nginx
sudo systemctl enable nginx
# Create a custom welcome page
echo "<h1>Custom AMI - $(date)</h1>" | sudo tee /usr/share/nginx/html/index.html
# Verify Nginx is serving
curl localhost
Step 2: Create the AMI
EC2 Console → Instances → select your instance
Actions → Image and Templates → Create ImageImage name:
custom-nginx-ami
Image description:Amazon Linux 2023 with Nginx pre-installed
No reboot: leave unchecked (AWS will reboot to ensure a consistent snapshot)
Create Image → note the AMI IDWait 5–10 minutes for status to change from
pendingtoavailableStep 3: Launch a new instance from your AMI
EC2 → Launch Instance
AMI → My AMIs → selectcustom-nginx-ami
t2.micro, same security group (HTTP 80 + SSH 22) → LaunchStep 4: Validate
Wait 2 minutes → open the new instance's Public IP in browser
Expected: Nginx serves your custom page — without any User Data script ✅Step 5: SSH and verify
ssh -i lab-key.pem ec2-user@<new-instance-ip>
nginx -v # Nginx is installed ✅
systemctl status nginx # Nginx is running ✅
cat /usr/share/nginx/html/index.html # Custom page is there ✅
What this demonstrates: The AMI captured the entire state of the configured instance. Any new instance launched from this AMI starts with Nginx pre-installed, pre-configured, and serving — no setup required.
🧪 Lab 5 — EBS Snapshot Cross-Region Copy
Objective: Create an EBS snapshot, copy it to another Region, and restore it as a new volume there. This is the foundation of cross-region disaster recovery and data migration.
Steps:
Step 1: Create a snapshot of your EBS volume
EC2 → Volumes → select your volume → Actions → Create Snapshot
Description:cross-region-dr-snapshot→ Create Snapshot
Note the Snapshot ID (snap-xxxxxxxx)
Wait for State to showcompletedStep 2: Copy snapshot to another Region
Via Console:
EC2 → Snapshots → select your snapshot → Actions → Copy Snapshot
Destination Region:us-east-1(N. Virginia)
Description:Copied from ap-south-1 for DR testing→ Copy Snapshot
Via CLI:
aws ec2 copy-snapshot \
--source-region ap-south-1 \
--source-snapshot-id snap-0123456789abcdef0 \
--region us-east-1 \
--description "DR copy from Mumbai to Virginia"
Step 3: Switch Region in Console to us-east-1
Verify the copied snapshot appears in Snapshots →completedstatus ✅Step 4: Create a volume from the copied snapshot
Select the snapshot → Actions → Create Volume from Snapshot
Volume type: gp3, Size: same as source
AZ:us-east-1a(or any AZ in us-east-1)
Create VolumeStep 5: Attach to an EC2 in us-east-1 and verify data
Launch a t2.micro EC2 in us-east-1
EC2 → Volumes → select the new volume → Actions → Attach Volume → select instance
SSH into the EC2:
# List block devices
lsblk
# New volume appears (e.g., /dev/xvdf)
# Mount it
sudo mkdir /data
sudo mount /dev/xvdf /data
# Verify the data from Mumbai is accessible
ls /data
cat /data/[any-file-from-source-instance]
# → Data from Mumbai visible in Virginia ✅
Real-world use cases for cross-region snapshot copy:
- Disaster Recovery: Primary Region fails → restore from snapshot in DR Region → minimal data loss
- Data Migration: Moving workloads from one Region to another
- Global Compliance Testing: Test with production data copy in a different Region without touching production
- Multi-Region Backup: Regulatory requirement to keep backups in multiple geographies
⚡ Quick Revision
EC2 Instance Families
- t/m = General Purpose · c = Compute · r = Memory · i/d = Storage · p/g = GPU
ENI
- Virtual network card — carries private IP, public IP, Elastic IP, MAC, Security Groups
- Applied at ENI level, not instance level — one instance can have multiple ENIs
EBS Volume Types
- gp3 = default, most workloads (set IOPS/throughput independently)
- io2 = high-performance databases, Multi-Attach
- st1 = big data throughput, sequential reads
- sc1 = cold/infrequent access, cheapest
AMI
- Blueprint for EC2: OS + software + config + root volume snapshot
- Region-specific — must copy AMI to use in another Region
- EBS-backed = can stop/start, use always · Instance Store-backed = legacy, avoid
- Sharing: private (default) / shared with account IDs / public
Lifecycle
- Running → billed per second
- Stopped → EBS billed, compute not billed, can restart
- Hibernated → RAM saved to EBS, resumes exactly where left off
- Terminated → gone forever, not recoverable
Status Checks
- System check fails → Stop + Start (moves to new physical host)
- Instance check fails → Reboot (fixes OS, stays on same host)
Placement Groups
- Cluster = low latency, same AZ, HPC workloads
- Spread = max isolation, separate racks, max 7 per AZ
- Partition = distributed systems, many nodes per partition
Pricing
- On-Demand = pay per second, no commitment
- Reserved = 1–3 years, 30–70% savings
- Spot = up to 90% off, can be interrupted with 2-min notice
Elastic IP
- Free when attached to a running instance
- Charged when idle or attached to a stopped instance — always release after labs
💼 Interview Questions
Q1: What is the difference between stopping and terminating an EC2 instance?
Stopping shuts the instance down — EBS data persists, compute billing stops, you can start it again. Terminating permanently deletes the instance and by default its root EBS volume. There is no recovery from termination.
Q2: An EC2 instance is in a different AZ than your EBS volume. Can you attach it?
No. EBS volumes are AZ-locked. To use EBS data across AZs: take a snapshot of the volume → create a new volume from that snapshot in the target AZ → attach to EC2 in that AZ.
Q3: What is the difference between Instance Store and EBS?
Instance Store is physical storage attached to the EC2 host — very fast but completely lost when the instance stops, terminates, or the underlying host fails. EBS is persistent network-attached storage that survives stop/restart and can be detached and reattached to other instances.
Q4: A system status check is failing on your EC2. What do you do?
Stop and Start the instance — not Reboot. This moves the instance to a new physical host. Rebooting keeps it on the same failing hardware and won't resolve a system-level infrastructure issue.
Q5: What is EC2 Hibernate and when would you use it?
Hibernate saves the entire RAM contents to the encrypted EBS root volume, then stops the instance. When started again, the OS and all applications resume exactly where they left off — no boot time, no re-initialization. Use it for long-running workloads that are expensive to restart — ML training checkpoints, complex stateful processes, developer environments you want to resume quickly.
Q6: What is the difference between EBS-backed and Instance Store-backed AMIs?
EBS-backed AMIs have the root volume stored as an EBS snapshot — instances can be stopped and restarted, and data on the root volume persists. Instance Store-backed AMIs store the root volume in S3 — instances cannot be stopped (only terminated), and root volume data is lost on termination. Always use EBS-backed AMIs.
Q7: When would you use a Cluster vs Spread placement group?
Cluster for workloads needing ultra-low latency and high throughput between instances — HPC, ML training. Spread for critical instances that must be isolated from each other's hardware failures — each instance goes on a separate physical rack, maximum 7 per AZ.
Q8: What are the real-world use cases for copying an EBS snapshot to another Region?
Cross-region disaster recovery (restore in DR Region if primary fails), data migration between Regions, regulatory compliance requiring backups in multiple geographies, and testing with production data in a non-production Region.
🔬 Practice Tasks
Launch an EC2 with a User Data script that installs Nginx (not Apache) and serves a custom page showing the instance ID, type, and region — all fetched from the metadata service. Access via public IP.
Allocate an Elastic IP. Launch an EC2. Note its public IP. Stop the instance — confirm the dynamic IP changed. Attach the Elastic IP. Stop and start again — confirm the IP stays the same. Release the Elastic IP when done.
Attach a second EBS volume to a running EC2 instance. SSH in, format it (
mkfs.xfs), mount it, write a file to it. Stop the instance. Start it again. Confirm the file persists (note: you'll need to remount — add to/etc/fstabfor automatic mount).Expand an EBS volume from 8 GB to 20 GB on a running instance (no downtime). SSH in and extend the file system using
growpartandxfs_growfs. Verify withdf -h.Create a custom AMI from a configured EC2 instance. Launch a second instance from that AMI. Verify all customizations are present without any manual setup.
Create a snapshot, copy it to a different Region via CLI, create a volume from it, attach to an EC2 in that Region, mount it, and verify the data from the original Region is accessible.
Using AWS CLI: describe all running instances, stop one by instance ID, start it again, create a snapshot of its root volume — all without touching the Console.
Use calculator.aws to estimate the monthly cost of: 1 × t3.micro EC2 (Linux, ap-south-1, 24/7) + 20 GB gp3 EBS + 100 GB data transfer out. Then estimate the same setup on Reserved Instance pricing (1 year, no upfront). Note the difference in monthly cost.
Using boto3: write a Python script that lists all EC2 instances in
ap-south-1, prints their ID, type, and state, and automatically stops any instance inrunningstate that has a tagEnvironment: dev.
AWS Session 4 — EC2 Essentials | Cloud + DevOps learning journey — Systems Engineer → Cloud/DevOps Engineer
Top comments (0)