Skip to main content
ClaudeWave
Skill71 repo starsupdated yesterday

aws-ec2

|

Install in Claude Code
Copy
git clone --depth 1 https://github.com/TerminalSkills/skills /tmp/aws-ec2 && cp -r /tmp/aws-ec2/skills/aws-ec2 ~/.claude/skills/aws-ec2
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# AWS EC2

Amazon Elastic Compute Cloud (EC2) provides resizable virtual servers in the cloud. It's the foundational compute service for running applications, from simple web servers to complex distributed systems.

## Core Concepts

- **Instance** — a virtual server with CPU, memory, storage, and networking
- **AMI** — Amazon Machine Image, a template for launching instances
- **Instance type** — hardware configuration (t3.micro, m5.xlarge, etc.)
- **Security group** — virtual firewall controlling inbound/outbound traffic
- **Key pair** — SSH authentication for Linux instances
- **EBS** — Elastic Block Store, persistent block storage volumes

## Launching Instances

```bash
# Launch a basic EC2 instance
aws ec2 run-instances \
  --image-id ami-0c55b159cbfafe1f0 \
  --instance-type t3.micro \
  --key-name my-key-pair \
  --security-group-ids sg-0123456789abcdef0 \
  --subnet-id subnet-0123456789abcdef0 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web-server-1}]' \
  --count 1
```

```bash
# Launch with user data script for bootstrapping
aws ec2 run-instances \
  --image-id ami-0c55b159cbfafe1f0 \
  --instance-type t3.small \
  --key-name my-key-pair \
  --security-group-ids sg-0123456789abcdef0 \
  --user-data file://setup.sh \
  --iam-instance-profile Name=ec2-app-role \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=app-server},{Key=Env,Value=prod}]'
```

```bash
# setup.sh — bootstrap script for EC2 instance
#!/bin/bash
yum update -y
yum install -y docker
systemctl start docker
systemctl enable docker
docker pull myapp:latest
docker run -d -p 80:8080 myapp:latest
```

## Instance Management

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

```bash
# Stop, start, terminate instances
aws ec2 stop-instances --instance-ids i-0123456789abcdef0
aws ec2 start-instances --instance-ids i-0123456789abcdef0
aws ec2 terminate-instances --instance-ids i-0123456789abcdef0
```

```bash
# Resize an instance (must be stopped first)
aws ec2 stop-instances --instance-ids i-0123456789abcdef0
aws ec2 modify-instance-attribute \
  --instance-id i-0123456789abcdef0 \
  --instance-type '{"Value": "t3.large"}'
aws ec2 start-instances --instance-ids i-0123456789abcdef0
```

## Security Groups

```bash
# Create a security group for a web server
aws ec2 create-security-group \
  --group-name web-sg \
  --description "Allow HTTP, HTTPS, SSH" \
  --vpc-id vpc-0123456789abcdef0
```

```bash
# Add inbound rules
aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --ip-permissions \
    'IpProtocol=tcp,FromPort=80,ToPort=80,IpRanges=[{CidrIp=0.0.0.0/0}]' \
    'IpProtocol=tcp,FromPort=443,ToPort=443,IpRanges=[{CidrIp=0.0.0.0/0}]' \
    'IpProtocol=tcp,FromPort=22,ToPort=22,IpRanges=[{CidrIp=203.0.113.0/24,Description=Office}]'
```

## AMIs

```bash
# Create an AMI from a running instance
aws ec2 create-image \
  --instance-id i-0123456789abcdef0 \
  --name "app-server-v1.2.0-$(date +%Y%m%d)" \
  --description "App server with latest patches" \
  --no-reboot
```

```bash
# List your AMIs
aws ec2 describe-images --owners self \
  --query 'Images[*].[ImageId,Name,CreationDate]' --output table
```

```bash
# Deregister old AMI and delete snapshot
aws ec2 deregister-image --image-id ami-0123456789abcdef0
aws ec2 delete-snapshot --snapshot-id snap-0123456789abcdef0
```

## EBS Volumes

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

```bash
# Attach volume to instance
aws ec2 attach-volume \
  --volume-id vol-0123456789abcdef0 \
  --instance-id i-0123456789abcdef0 \
  --device /dev/xvdf
```

```bash
# Create a snapshot for backup
aws ec2 create-snapshot \
  --volume-id vol-0123456789abcdef0 \
  --description "Daily backup $(date +%Y-%m-%d)" \
  --tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=daily-backup}]'
```

## Auto Scaling

```bash
# Create a launch template
aws ec2 create-launch-template \
  --launch-template-name app-server-template \
  --launch-template-data '{
    "ImageId": "ami-0c55b159cbfafe1f0",
    "InstanceType": "t3.medium",
    "SecurityGroupIds": ["sg-0123456789abcdef0"],
    "KeyName": "my-key-pair",
    "IamInstanceProfile": {"Name": "ec2-app-role"},
    "UserData": "'$(base64 -w0 setup.sh)'"
  }'
```

```bash
# Create an auto-scaling group
aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name app-asg \
  --launch-template LaunchTemplateName=app-server-template,Version='$Latest' \
  --min-size 2 \
  --max-size 10 \
  --desired-capacity 2 \
  --vpc-zone-identifier "subnet-aaa,subnet-bbb" \
  --target-group-arns "arn:aws:elasticloadbalancing:us-east-1:123456789:targetgroup/app-tg/abc123" \
  --health-check-type ELB \
  --health-check-grace-period 300
```

```bash
# Create scaling policy based on CPU
aws autoscaling put-scaling-policy \
  --auto-scaling-group-name app-asg \
  --policy-name cpu-scale-out \
  --policy-type TargetTrackingScaling \
  --target-tracking-configuration '{
    "PredefinedMetricSpecification": {"PredefinedMetricType": "ASGAverageCPUUtilization"},
    "TargetValue": 70.0,
    "ScaleInCooldown": 300,
    "ScaleOutCooldown": 60
  }'
```

## Spot Instances

```bash
# Request spot instances for cost savings (up to 90% off)
aws ec2 request-spot-instances \
  --instance-count 3 \
  --type "one-time" \
  --launch-specification '{
    "ImageId": "ami-0c55b159cbfafe1f0",
    "InstanceType": "c5.xlarge",
    "SecurityGroupIds": ["sg-0123456789abcdef0"],
    "SubnetId": "subnet-0123456789abcdef0"
  }'
```

## Best Practices

- Use launch templates over launch conf