`n

AWS EC2 Instance Configuration - Complete Guide

Published: September 25, 2024 | Reading time: 20 minutes

AWS EC2 Overview

Amazon Elastic Compute Cloud (EC2) provides scalable virtual servers in the cloud:

EC2 Features
# Key Features
- Virtual servers (instances)
- Multiple instance types
- Auto scaling
- Load balancing
- Elastic IP addresses
- Security groups
- IAM integration

AWS Account Setup

Account Configuration

Initial Setup
# 1. Create AWS Account
# Visit: https://aws.amazon.com/
# Sign up with email and payment method

# 2. Enable MFA
# Go to IAM > Users > Security credentials
# Enable MFA device (Google Authenticator recommended)

# 3. Create IAM User
# Create user with programmatic access
# Attach policies: AmazonEC2FullAccess
# Download access keys (CSV file)

# 4. Configure AWS CLI
aws configure
# Enter Access Key ID
# Enter Secret Access Key
# Enter region (e.g., us-east-1)
# Enter output format (json)

Key Pair Creation

SSH Key Setup
# Generate SSH key pair
ssh-keygen -t ed25519 -C "aws-ec2-key"

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

# Set proper permissions
chmod 400 my-ec2-key.pem

# List key pairs
aws ec2 describe-key-pairs

# Connect to instance
ssh -i my-ec2-key.pem ec2-user@INSTANCE_IP

Instance Creation

Launch Instance

EC2 Launch Commands
# Launch instance via CLI
aws ec2 run-instances \
  --image-id ami-0abcdef1234567890 \
  --count 1 \
  --instance-type t3.micro \
  --key-name my-ec2-key \
  --security-group-ids sg-12345678 \
  --subnet-id subnet-12345678 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web-server}]'

# Get latest Ubuntu AMI ID
aws ec2 describe-images \
  --owners 099720109477 \
  --filters "Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-22.04-lts-amd64-server-*" \
  --query 'Images[*].[ImageId,Name,CreationDate]' \
  --output table

# List running instances
aws ec2 describe-instances \
  --filters "Name=instance-state-name,Values=running" \
  --query 'Reservations[*].Instances[*].[InstanceId,InstanceType,State.Name,PublicIpAddress]' \
  --output table

Instance Types

General Purpose

  • t3.micro - 1 vCPU, 1 GB RAM
  • t3.small - 2 vCPU, 2 GB RAM
  • t3.medium - 2 vCPU, 4 GB RAM
  • m5.large - 2 vCPU, 8 GB RAM
  • m5.xlarge - 4 vCPU, 16 GB RAM

Compute Optimized

  • c5.large - 2 vCPU, 4 GB RAM
  • c5.xlarge - 4 vCPU, 8 GB RAM
  • c5.2xlarge - 8 vCPU, 16 GB RAM
  • c5.4xlarge - 16 vCPU, 32 GB RAM
  • c5.9xlarge - 36 vCPU, 72 GB RAM

Security Groups

Security Group Configuration

Security Group Setup
# Create security group
aws ec2 create-security-group \
  --group-name web-server-sg \
  --description "Security group for web server"

# Add SSH rule
aws ec2 authorize-security-group-ingress \
  --group-id sg-12345678 \
  --protocol tcp \
  --port 22 \
  --cidr 0.0.0.0/0

# Add HTTP rule
aws ec2 authorize-security-group-ingress \
  --group-id sg-12345678 \
  --protocol tcp \
  --port 80 \
  --cidr 0.0.0.0/0

# Add HTTPS rule
aws ec2 authorize-security-group-ingress \
  --group-id sg-12345678 \
  --protocol tcp \
  --port 443 \
  --cidr 0.0.0.0/0

# Add custom port rule
aws ec2 authorize-security-group-ingress \
  --group-id sg-12345678 \
  --protocol tcp \
  --port 3000 \
  --cidr 0.0.0.0/0

# List security groups
aws ec2 describe-security-groups \
  --group-ids sg-12345678

VPC and Networking

VPC Configuration

VPC Setup
# Create VPC
aws ec2 create-vpc \
  --cidr-block 10.0.0.0/16 \
  --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=my-vpc}]'

# Create subnet
aws ec2 create-subnet \
  --vpc-id vpc-12345678 \
  --cidr-block 10.0.1.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-subnet}]'

# Create internet gateway
aws ec2 create-internet-gateway \
  --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=my-igw}]'

# Attach internet gateway to VPC
aws ec2 attach-internet-gateway \
  --internet-gateway-id igw-12345678 \
  --vpc-id vpc-12345678

# Create route table
aws ec2 create-route-table \
  --vpc-id vpc-12345678 \
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=public-rt}]'

# Create route to internet gateway
aws ec2 create-route \
  --route-table-id rtb-12345678 \
  --destination-cidr-block 0.0.0.0/0 \
  --gateway-id igw-12345678

# Associate subnet with route table
aws ec2 associate-route-table \
  --subnet-id subnet-12345678 \
  --route-table-id rtb-12345678

Instance Management

Instance Operations

Instance Management
# Start instance
aws ec2 start-instances --instance-ids i-1234567890abcdef0

# Stop instance
aws ec2 stop-instances --instance-ids i-1234567890abcdef0

# Reboot instance
aws ec2 reboot-instances --instance-ids i-1234567890abcdef0

# Terminate instance
aws ec2 terminate-instances --instance-ids i-1234567890abcdef0

# Get instance status
aws ec2 describe-instances \
  --instance-ids i-1234567890abcdef0 \
  --query 'Reservations[*].Instances[*].[InstanceId,State.Name,PublicIpAddress]'

# Create snapshot
aws ec2 create-snapshot \
  --volume-id vol-12345678 \
  --description "Backup snapshot"

# Create AMI from instance
aws ec2 create-image \
  --instance-id i-1234567890abcdef0 \
  --name "my-web-server-ami" \
  --description "Web server AMI"

Elastic IP

Elastic IP Setup
# Allocate Elastic IP
aws ec2 allocate-address \
  --domain vpc \
  --tag-specifications 'ResourceType=elastic-ip,Tags=[{Key=Name,Value=web-server-eip}]'

# Associate Elastic IP with instance
aws ec2 associate-address \
  --instance-id i-1234567890abcdef0 \
  --allocation-id eipalloc-12345678

# Disassociate Elastic IP
aws ec2 disassociate-address \
  --association-id eipassoc-12345678

# Release Elastic IP
aws ec2 release-address \
  --allocation-id eipalloc-12345678

# List Elastic IPs
aws ec2 describe-addresses

Application Deployment

User Data Script

Bootstrap Script
#!/bin/bash
# user-data.sh - Instance bootstrap script

# Update system
yum update -y

# Install Node.js
curl -fsSL https://rpm.nodesource.com/setup_18.x | bash -
yum install -y nodejs

# Install PM2
npm install -g pm2

# Install Nginx
yum install -y nginx
systemctl start nginx
systemctl enable nginx

# Create application directory
mkdir -p /var/www/myapp
cd /var/www/myapp

# Clone application (replace with your repo)
git clone https://github.com/yourusername/your-app.git .

# Install dependencies
npm install

# Create PM2 ecosystem file
cat > ecosystem.config.js << EOF
module.exports = {
  apps: [{
    name: 'myapp',
    script: 'app.js',
    instances: 'max',
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    }
  }]
};
EOF

# Start application
pm2 start ecosystem.config.js
pm2 save
pm2 startup

# Configure Nginx
cat > /etc/nginx/conf.d/myapp.conf << EOF
server {
    listen 80;
    server_name _;
    
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_cache_bypass \$http_upgrade;
    }
}
EOF

# Restart Nginx
systemctl restart nginx

Auto Scaling

Launch Template

Launch Template
# Create launch template
aws ec2 create-launch-template \
  --launch-template-name web-server-template \
  --launch-template-data '{
    "ImageId": "ami-0abcdef1234567890",
    "InstanceType": "t3.micro",
    "KeyName": "my-ec2-key",
    "SecurityGroupIds": ["sg-12345678"],
    "UserData": "'$(base64 -w 0 user-data.sh)'",
    "TagSpecifications": [{
      "ResourceType": "instance",
      "Tags": [{"Key": "Name", "Value": "web-server"}]
    }]
  }'

# Create Auto Scaling Group
aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name web-server-asg \
  --launch-template LaunchTemplateName=web-server-template,Version=1 \
  --min-size 1 \
  --max-size 10 \
  --desired-capacity 2 \
  --vpc-zone-identifier "subnet-12345678,subnet-87654321"

# Create scaling policy
aws autoscaling put-scaling-policy \
  --auto-scaling-group-name web-server-asg \
  --policy-name scale-up-policy \
  --policy-type TargetTrackingScaling \
  --target-tracking-configuration '{
    "TargetValue": 70.0,
    "PredefinedMetricSpecification": {
      "PredefinedMetricType": "ASGAverageCPUUtilization"
    }
  }'

Load Balancing

Application Load Balancer

ALB Setup
# Create target group
aws elbv2 create-target-group \
  --name web-server-tg \
  --protocol HTTP \
  --port 3000 \
  --vpc-id vpc-12345678 \
  --target-type instance \
  --health-check-path /health

# Create Application Load Balancer
aws elbv2 create-load-balancer \
  --name web-server-alb \
  --subnets subnet-12345678 subnet-87654321 \
  --security-groups sg-12345678 \
  --scheme internet-facing \
  --type application

# Create listener
aws elbv2 create-listener \
  --load-balancer-arn arn:aws:elasticloadbalancing:region:account:loadbalancer/app/web-server-alb/1234567890123456 \
  --protocol HTTP \
  --port 80 \
  --default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:region:account:targetgroup/web-server-tg/1234567890123456

# Register targets
aws elbv2 register-targets \
  --target-group-arn arn:aws:elasticloadbalancing:region:account:targetgroup/web-server-tg/1234567890123456 \
  --targets Id=i-1234567890abcdef0,Port=3000

Monitoring and Logging

CloudWatch Setup

CloudWatch Configuration
# Install CloudWatch agent
wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
sudo rpm -U ./amazon-cloudwatch-agent.rpm

# Configure CloudWatch agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

# Start CloudWatch agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json

# Create CloudWatch alarm
aws cloudwatch put-metric-alarm \
  --alarm-name "High CPU Utilization" \
  --alarm-description "Alarm when CPU exceeds 80%" \
  --metric-name CPUUtilization \
  --namespace AWS/EC2 \
  --statistic Average \
  --period 300 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 2 \
  --alarm-actions arn:aws:sns:region:account:topic-name

Backup and Recovery

EBS Snapshots

Backup Strategy
# Create snapshot
aws ec2 create-snapshot \
  --volume-id vol-12345678 \
  --description "Daily backup $(date +%Y-%m-%d)"

# Create snapshot with tags
aws ec2 create-snapshot \
  --volume-id vol-12345678 \
  --description "Automated backup" \
  --tag-specifications 'ResourceType=snapshot,Tags=[{Key=Name,Value=web-server-backup},{Key=Environment,Value=production}]'

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

# Create volume from snapshot
aws ec2 create-volume \
  --snapshot-id snap-12345678 \
  --availability-zone us-east-1a \
  --volume-type gp3 \
  --size 20

# Attach volume to instance
aws ec2 attach-volume \
  --volume-id vol-87654321 \
  --instance-id i-1234567890abcdef0 \
  --device /dev/sdf

Cost Optimization

Cost Management

Cost Optimization
# Use Spot Instances for non-critical workloads
aws ec2 request-spot-instances \
  --spot-price "0.05" \
  --instance-count 1 \
  --type "one-time" \
  --launch-specification '{
    "ImageId": "ami-0abcdef1234567890",
    "InstanceType": "t3.micro",
    "KeyName": "my-ec2-key",
    "SecurityGroupIds": ["sg-12345678"]
  }'

# Use Reserved Instances for predictable workloads
aws ec2 purchase-reserved-instances-offering \
  --reserved-instances-offering-id 12345678-1234-1234-1234-123456789012 \
  --instance-count 1

# Enable detailed billing
aws budgets create-budget \
  --account-id 123456789012 \
  --budget '{
    "BudgetName": "EC2 Monthly Budget",
    "BudgetLimit": {
      "Amount": "100",
      "Unit": "USD"
    },
    "TimeUnit": "MONTHLY",
    "BudgetType": "COST"
  }'

# Set up cost alerts
aws budgets create-notification \
  --account-id 123456789012 \
  --budget-name "EC2 Monthly Budget" \
  --notification '{
    "NotificationType": "ACTUAL",
    "ComparisonOperator": "GREATER_THAN",
    "Threshold": 80,
    "ThresholdType": "PERCENTAGE"
  }' \
  --subscribers '[
    {
      "SubscriptionType": "EMAIL",
      "Address": "admin@example.com"
    }
  ]'

Best Practices

Security Recommendations

Security Checklist

  • Use IAM roles instead of access keys
  • Enable MFA for all users
  • Use least privilege principle
  • Regular security group reviews
  • Enable VPC Flow Logs
  • Use AWS Config for compliance
  • Regular security audits

Performance Tips

  • Choose appropriate instance types
  • Use EBS-optimized instances
  • Enable enhanced networking
  • Use placement groups for low latency
  • Optimize EBS volume types
  • Use CloudFront for global content
  • Monitor and optimize costs

Summary

AWS EC2 instance configuration involves several key components:

  • Account Setup: IAM users, MFA, access keys
  • Instance Creation: AMI selection, instance types, key pairs
  • Security: Security groups, VPC configuration
  • Networking: Subnets, internet gateways, route tables
  • Deployment: User data scripts, application setup
  • Scaling: Auto Scaling Groups, launch templates
  • Load Balancing: Application Load Balancer setup
  • Monitoring: CloudWatch, alarms, logging
  • Backup: EBS snapshots, recovery procedures
  • Cost Management: Reserved instances, spot instances

Need More Help?

Struggling with AWS EC2 configuration or need help optimizing your cloud infrastructure? Our AWS experts can help you design and implement scalable, secure cloud solutions.

Get AWS Help