How to Properly Stop and Restart an EC2 Instance Without Losing IP Configuration or Database Connectivity


2 views

When dealing with EC2 instances, it's crucial to understand the difference between stopping and terminating:

// AWS CLI examples
# This preserves EBS volumes and ENI configuration
aws ec2 stop-instances --instance-ids i-1234567890abcdef0

# THIS IS DESTRUCTIVE (avoids accidental termination)
aws ec2 terminate-instances --instance-ids i-1234567890abcdef0

By default, EC2 instances receive new public IPs upon restart. To maintain consistency:

// Assigning an Elastic IP (EIP) before stopping
aws ec2 allocate-address
aws ec2 associate-address --instance-id i-1234567890abcdef0 --public-ip 203.0.113.0

For private IPs (critical for DB connections):

  • VPC instances retain private IPs by default
  • Classic EC2 requires explicit configuration

If using Route 53:

// Sample CloudFormation snippet for DNS record
"WebServerRecord" : {
  "Type" : "AWS::Route53::RecordSet",
  "Properties" : {
    "HostedZoneName" : "x.com.",
    "Name" : "www.x.com.",
    "Type" : "A",
    "TTL" : "300",
    "ResourceRecords" : [ { "Fn::GetAtt" : [ "EC2Instance", "PublicIp" ] } ]
  }
}

To ensure seamless DB reconnection:

# Sample PostgreSQL connection string with retry logic
DATABASE_URL="postgresql://user:password@db-private-ip/dbname\
?connect_timeout=10\
&application_name=webapp\
&keepalives=1\
&keepalives_idle=30\
&keepalives_interval=10\
&keepalives_count=5"

Step-by-step for changing instance type:

  1. Create AMI backup: aws ec2 create-image --instance-id i-1234567890abcdef0 --name "web-server-backup"
  2. Stop instance (not terminate!)
  3. Modify instance type: aws ec2 modify-instance-attribute --instance-id i-1234567890abcdef0 --instance-type m5.large
  4. Start instance

Typical duration for West US region:

Operation Average Time
Instance stop 1-2 minutes
Type modification Instant
Instance start 3-5 minutes
Full process 5-8 minutes

Post-restart checklist automation:

#!/bin/bash
# Verify critical services
if ! curl -Is http://localhost/health-check | grep "200 OK"; then
  systemctl restart apache2
fi

# Test DB connection
if ! psql -h $DB_HOST -U $DB_USER -c "SELECT 1" $DB_NAME; then
  logger "DB connection failed after restart"
  exit 1
fi

# Check DNS resolution
if ! dig +short $DOMAIN | grep -q $EIP; then
  aws route53 change-resource-record-sets --change-batch file://update-dns.json
fi

When you stop and restart an Amazon EC2 instance, several technical considerations come into play regarding networking and service continuity:

# Sample AWS CLI command to stop an instance
aws ec2 stop-instances --instance-ids i-1234567890abcdef0

# Corresponding start command
aws ec2 start-instances --instance-ids i-1234567890abcdef0

The key thing to understand is that public IPs are not preserved by default. However, Elastic IPs remain attached:

  • Default public IP: Changes after restart (new DHCP lease)
  • Elastic IP: Persists through stop/start cycles
  • Private IP: Typically remains the same within the same VPC

Your DNS configuration needs special attention:

// Example route53 record before stop
{
  "Name": "x.com",
  "Type": "A",
  "TTL": 300,
  "ResourceRecords": [
    {"Value": "54.1.1.1"}
  ]
}

If using the default public DNS (ec2-54-1-1-1...), this will break after restart. Solutions:

  1. Use Elastic IP (recommended for production)
  2. Update DNS records programmatically
  3. Use Route53 health checks for automated failover

For database connectivity, implement these best practices:

# Example connection string with retry logic
DATABASE_URL="postgresql://user:pass@db-host:5432/dbname?connect_timeout=10&keepalives=1"

Connection handling strategies:

  • Implement exponential backoff in your application
  • Use RDS proxy for stable database endpoints
  • Configure security groups to allow new instance IP

To change instance types while minimizing downtime:

  1. Stop the instance (takes 1-2 minutes typically)
  2. Change instance type in AWS console or via CLI:
aws ec2 modify-instance-attribute \
  --instance-id i-1234567890abcdef0 \
  --instance-type "m5.large"
  1. Start the instance (2-5 minutes for full services)

Before production changes, test this sequence:

#!/bin/bash
# Test script for stop/start procedure
INSTANCE_ID="i-1234567890abcdef0"

echo "Stopping instance..."
aws ec2 stop-instances --instance-ids $INSTANCE_ID
aws ec2 wait instance-stopped --instance-ids $INSTANCE_ID

echo "Modifying instance type..."
aws ec2 modify-instance-attribute \
  --instance-id $INSTANCE_ID \
  --instance-type "m5.large"

echo "Starting instance..."
aws ec2 start-instances --instance-ids $INSTANCE_ID
aws ec2 wait instance-running --instance-ids $INSTANCE_ID

echo "Checking system status..."
ssh -i key.pem ec2-user@$(aws ec2 describe-instances \
  --instance-ids $INSTANCE_ID \
  --query 'Reservations[0].Instances[0].PublicIpAddress' \
  --output text) \
  "systemctl status nginx"