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


10 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"