Skip to content
beginner Phase 1 · AWS Fundamentals

EC2 Compute

Launch, configure, and manage virtual servers with Amazon EC2.

1h 30m
0 problems
Topic Progress 0%

EC2 Instance Types and Selection

EC2 Instance Types and Selection

Amazon EC2 provides scalable computing capacity in the AWS cloud. Instance types vary by CPU, memory, storage, and networking.

Instance Type Families

Family Use Case Example
T3/T3a Burstable general purpose t3.micro (2 vCPU, 1 GiB)
M5/M6i General purpose, balanced m5.large (2 vCPU, 8 GiB)
C5/C6g Compute optimized c5.xlarge (4 vCPU, 8 GiB)
R5/R6i Memory optimized r5.large (2 vCPU, 16 GiB)
I3 Storage optimized i3.xlarge (4 vCPU, 30.5 GiB)
G5 GPU accelerated g5.xlarge (4 vCPU, 16 GiB)

Launch an EC2 Instance

# Launch a new EC2 instance
aws ec2 run-instances \
  --image-id ami-0c55b159cbfafe1f0 \
  --instance-type t3.micro \
  --key-name my-key-pair \
  --security-group-ids sg-xxx \
  --subnet-id subnet-xxx \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=WebServer}]' \
  --user-data '#!/bin/bash
yum update -y
yum install httpd -y
systemctl start httpd
systemctl enable httpd
'

# List running instances
aws ec2 describe-instances \
  --filters "Name=instance-state-name,Values=running" \
  --query 'Reservations[*].Instances[*].[InstanceId,InstanceType,PublicIpAddress,Tags[?Key==`Name`].Value|[0]]' \
  --output table

Instance Lifecycle

Pending → Running → Stopping → Stopped → Running
                     ↘ Terminated
  • Stop/Start: Instance moves to new hardware (public IP changes)
  • Hibernate: RAM saved to EBS, faster restart
  • Terminate: Instance destroyed (default EBS volumes deleted)
# Stop an instance
aws ec2 stop-instances --instance-ids i-xxx

# Start an instance
aws ec2 start-instances --instance-ids i-xxx

# Terminate an instance
aws ec2 terminate-instances --instance-ids i-xxx

EC2 Security Groups and Key Pairs

EC2 Security Groups and Key Pairs

Security Groups

Security groups act as virtual firewalls controlling inbound and outbound traffic.

# Create a security group
aws ec2 create-security-group \
  --group-name web-server-sg \
  --description "Web server security group" \
  --vpc-id vpc-xxx

# Allow HTTP inbound
aws ec2 authorize-security-group-ingress \
  --group-id sg-xxx \
  --protocol tcp \
  --port 80 \
  --cidr 0.0.0.0/0

# Allow HTTPS inbound
aws ec2 authorize-security-group-ingress \
  --group-id sg-xxx \
  --protocol tcp \
  --port 443 \
  --cidr 0.0.0.0/0

# Allow SSH from specific IP only
aws ec2 authorize-security-group-ingress \
  --group-id sg-xxx \
  --protocol tcp \
  --port 22 \
  --cidr 203.0.113.0/32

# Allow all outbound (default)
aws ec2 authorize-security-group-egress \
  --group-id sg-xxx \
  --protocol -1 \
  --cidr 0.0.0.0/0

# List security group rules
aws ec2 describe-security-groups --group-ids sg-xxx

Security Group Rules Summary

┌─────────────────────────────────────────────┐
│            Security Group                   │
├─────────────────────────────────────────────┤
│ Inbound Rules                               │
│ ┌──────┬──────┬─────────────┐              │
│ │ Port │ Proto│ Source      │              │
│ ├──────┼──────┼─────────────┤              │
│ │ 22   │ TCP  │ 203.0.113.x │              │
│ │ 80   │ TCP  │ 0.0.0.0/0   │              │
│ │ 443  │ TCP  │ 0.0.0.0/0   │              │
│ └──────┴──────┴─────────────┘              │
│ Outbound Rules (default: all allowed)       │
│ ┌──────┬──────┬─────────────┐              │
│ │ ALL  │ ALL  │ 0.0.0.0/0   │              │
│ └──────┴──────┴─────────────┘              │
└─────────────────────────────────────────────┘

Key Pairs

# Create a key pair
aws ec2 create-key-pair --key-name my-key-pair --query 'KeyMaterial' --output text > my-key-pair.pem

# Set permissions (Linux/Mac)
chmod 400 my-key-pair.pem

# Connect via SSH
ssh -i my-key-pair.pem ec2-user@<public-ip>

# Use SSM Session Manager (no SSH needed)
aws ssm start-session --target i-xxx

EBS Storage Volumes

EBS Storage Volumes

Elastic Block Store provides persistent block storage for EC2 instances.

EBS Volume Types

Type Use Case IOPS Throughput Size Range
gp3 General purpose SSD 3,000-16,000 125-1,000 MB/s 1 GiB-16 TiB
gp2 General purpose SSD Up to 16,000 Up to 250 MB/s 1 GiB-16 TiB
io2 High performance SSD Up to 64,000 Up to 1,000 MB/s 4 GiB-16 TiB
st1 Throughput HDD 500 500 MB/s 500 GiB-16 TiB
sc1 Cold HDD 250 250 MB/s 500 GiB-16 TiB

EBS Operations

# Create an EBS volume
aws ec2 create-volume \
  --availability-zone us-east-1a \
  --size 100 \
  --volume-type gp3 \
  --iops 3000 \
  --throughput 125 \
  --tag-specifications 'ResourceType=volume,Tags=[{Key=Name,Value=DataVolume}]'

# Attach a volume to an instance
aws ec2 attach-volume \
  --volume-id vol-xxx \
  --instance-id i-xxx \
  --device /dev/sdf

# On the instance, mount the volume:
# sudo mkfs -t ext4 /dev/nvme1n1
# sudo mkdir /data
# sudo mount /dev/nvme1n1 /data

# Create a snapshot
aws ec2 create-snapshot \
  --volume-id vol-xxx \
  --description "Daily backup" \
  --tag-specifications 'ResourceType=snapshot,Tags=[{Key=Backup,Value=Daily}]'

# List snapshots
aws ec2 describe-snapshots --owner-ids self --query 'Snapshots[*].[SnapshotId,VolumeId,State,StartTime]' --output table

EBS Encryption

# Enable encryption by default for your account
aws ec2 enable-ebs-encryption-by-default

# Create an encrypted volume
aws ec2 create-volume \
  --availability-zone us-east-1a \
  --size 100 \
  --volume-type gp3 \
  --encrypted \
  --kms-key-id alias/aws/ebs

AMIs and User Data

AMIs and User Data

Amazon Machine Images (AMIs)

AMIs provide the information required to launch an instance. They contain a root volume template, launch permissions, and block device mappings.

# Find Amazon Linux 2 AMI
aws ec2 describe-images \
  --owners amazon \
  --filters "Name=name,Values=amzn2-ami-hvm-*-x86_64-gp2" \
  --query 'sort_by(Images,&CreationDate)[-1].ImageId' \
  --output text

# Create an AMI from a running instance
aws ec2 create-image \
  --instance-id i-xxx \
  --name "MyApp-AMI-$(date +%Y%m%d)" \
  --description "Custom AMI for web application"

# Share an AMI with another account
aws ec2 modify-image-attribute \
  --image-id ami-xxx \
  --launch-permission 'Add=[{UserId=123456789012}]'

User Data Scripts

User data scripts run on first boot. Use them to automate instance configuration:

#!/bin/bash
yum update -y
yum install -y httpd php

# Configure Apache
echo '<html><body><h1>Hello from EC2!</h1></body></html>' > /var/www/html/index.html

systemctl start httpd
systemctl enable httpd

# Install CloudWatch agent
yum install -y amazon-cloudwatch-agent

# Signal CloudFormation (if used)
/opt/aws/bin/cfn-signal -e $? --stack my-stack --resource WebServer --region us-east-1

Launch Templates

# Create a launch template
aws ec2 create-launch-template \
  --launch-template-name MyWebTemplate \
  --version-description "Version 1" \
  --launch-template-data '{
    "ImageId": "ami-xxx",
    "InstanceType": "t3.micro",
    "KeyName": "my-key-pair",
    "SecurityGroupIds": ["sg-xxx"],
    "UserData": "IyEvYmluL2Jhc2gKeXVtIHVwZGF0ZSAteQ==",
    "BlockDeviceMappings": [{
      "DeviceName": "/dev/xvda",
      "Ebs": {
        "VolumeSize": 30,
        "VolumeType": "gp3",
        "Encrypted": true
      }
    }]
  }'

Auto Scaling and Load Balancing

Auto Scaling Groups and Load Balancing

Auto Scaling Group (ASG)

ASGs automatically adjust the number of EC2 instances based on demand.

# Create a launch template
aws ec2 create-launch-template \
  --launch-template-name asg-template \
  --launch-template-data '{
    "ImageId": "ami-xxx",
    "InstanceType": "t3.micro",
    "SecurityGroupIds": ["sg-xxx"]
  }'

# Create an Auto Scaling Group
aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name my-asg \
  --launch-template LaunchTemplateName=asg-template \
  --min-size 2 \
  --max-size 10 \
  --desired-capacity 2 \
  --vpc-zone-identifier "subnet-xxx,subnet-yyy" \
  --target-group-arns arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-tg/xxx

# Configure scaling policy
aws autoscaling put-scaling-policy \
  --auto-scaling-group-name my-asg \
  --policy-name cpu-target-tracking \
  --policy-type TargetTrackingScaling \
  --target-tracking-configuration '{
    "PredefinedMetricSpecification": {
      "PredefinedMetricType": "ASGAverageCPUUtilization"
    },
    "TargetValue": 70.0
  }'

Application Load Balancer (ALB)

# Create an ALB
aws elbv2 create-load-balancer \
  --name my-alb \
  --type application \
  --subnets subnet-xxx subnet-yyy \
  --security-groups sg-xxx

# Create a target group
aws elbv2 create-target-group \
  --name my-targets \
  --protocol HTTP \
  --port 80 \
  --vpc-id vpc-xxx \
  --health-check-path /health

# Create a listener
aws elbv2 create-listener \
  --load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:xxx:loadbalancer/app/my-alb/xxx \
  --protocol HTTP \
  --port 80 \
  --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:xxx:targetgroup/my-targets/xxx

Architecture Diagram

                    ┌──────────────┐
                    │  Internet    │
                    └──────┬───────┘
                           │
                    ┌──────▼───────┐
                    │     ALB      │
                    └──────┬───────┘
                           │
              ┌────────────┼────────────┐
              │            │            │
        ┌─────▼─────┐┌────▼────┐┌─────▼─────┐
        │    EC2    ││   EC2   ││    EC2    │
        │  (AZ-1a) ││ (AZ-1b)││  (AZ-1c) │
        └───────────┘└─────────┘└───────────┘

EC2 Pricing Optimization

EC2 Pricing Optimization

Instance Purchase Options

Option Discount Commitment Best For
On-Demand None None Dev/test, unpredictable
Reserved (1yr) ~40% 1 year Steady-state workloads
Reserved (3yr) ~60% 3 years Predictable long-term
Spot Up to 90% None Batch, fault-tolerant
Savings Plans Up to 72% $/hr commitment Flexible across families

Spot Instance Strategy

# Launch a Spot Instance
aws ec2 run-instances \
  --image-id ami-xxx \
  --instance-type c5.xlarge \
  --instance-market-options '{
    "MarketType": "spot",
    "SpotOptions": {
      "MaxPrice": "0.05",
      "SpotInstanceType": "one-time",
      "InstanceInterruptionBehavior": "terminate"
    }
  }'

# Request Spot Fleet
aws ec2 request-spot-fleet \
  --spot-fleet-request-config '{
    "IamFleetRole": "arn:aws:iam::xxx:role/aws-ec2-spot-fleet-tagging-role",
    "TargetCapacity": 5,
    "InstanceInterruptionBehavior": "terminate",
    "LaunchSpecifications": [{
      "ImageId": "ami-xxx",
      "InstanceType": ["c5.xlarge", "c5a.xlarge", "m5.xlarge"]
    }]
  }'

Cost Monitoring

# Get current EC2 costs
aws ce get-cost-and-usage \
  --time-period Start=2024-01-01,End=2024-01-31 \
  --granularity MONTHLY \
  --metrics UnblendedCost \
  --group-by Type=DIMENSION,Key=SERVICE \
  --filter '{"Dimensions":{"Key":"SERVICE","Values":["Amazon Elastic Compute Cloud - Compute"]}}'

# Find underutilized instances
aws cloudwatch get-metric-statistics \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-xxx \
  --start-time 2024-01-01T00:00:00Z \
  --end-time 2024-01-31T23:59:59Z \
  --period 86400 \
  --statistics Average

Rightsizing Recommendations

# Get AWS Compute Optimizer recommendations
aws compute-optimizer get-ec2-instance-recommendations \
  --instance-arns arn:aws:ec2:us-east-1:xxx:instance/i-xxx