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