EC2 Instance Public DNS Stability: When and Why It Changes in AWS


2 views

The public DNS of an EC2 instance (format: ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com) is dynamically generated and can change under specific circumstances. Let's examine the exact scenarios when this occurs:

  • Explicit Stop/Start: When you manually stop and restart an instance (not reboot), AWS assigns new public IP/DNS
  • Instance Termination: Obviously when the instance is terminated
  • Elastic IP Release: If you disassociate an Elastic IP and don't reassign it
  • VPC Changes: When modifying network interfaces or moving between subnets
  • Simple reboots (through AWS console or OS reboot commands)
  • Normal instance operations (running state)
  • When using Elastic IPs (even after stop/start)
  • Spot instances that aren't interrupted

For applications requiring stable endpoints, consider these AWS-native approaches:

# Using AWS CLI to associate Elastic IP
aws ec2 allocate-address --domain vpc
aws ec2 associate-address --instance-id i-1234567890abcdef --allocation-id eipalloc-12345678

# CloudFormation snippet for Elastic IP association
Resources:
  MyEIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
      InstanceId: !Ref MyEC2Instance

Other architectural patterns to consider:

  • Route53 DNS: Create a CNAME record pointing to your instance
  • Load Balancer: Use ALB/NLB with fixed DNS name
  • API Gateway: Front your instance with API Gateway

You can programmatically detect DNS changes using AWS SDKs:

// JavaScript example using AWS SDK
const AWS = require('aws-sdk');
const ec2 = new AWS.EC2();

async function checkInstanceDNS(instanceId) {
  const data = await ec2.describeInstances({
    InstanceIds: [instanceId]
  }).promise();
  
  return data.Reservations[0].Instances[0].PublicDnsName;
}

// Compare with stored value to detect changes

For production systems, never hardcode EC2 public DNS names. Instead:

  1. Use Elastic IPs for long-running instances
  2. Implement DNS abstraction with Route53
  3. Consider load balancers for web applications
  4. Build retry logic in clients when DNS changes occur

When working with AWS EC2 instances, the public DNS follows this pattern:

ec2-[public-ipv4]-[region].compute.amazonaws.com

This DNS is automatically assigned when your instance launches in a VPC. The critical thing to understand is that this DNS name is directly tied to the instance's public IPv4 address.

The public DNS will change in these scenarios:

  • Instance stopped and started (different from reboot)
  • Instance terminated and new one launched
  • Elastic IP disassociated from the instance
  • Underlying hardware failure requiring AWS to migrate your instance

For production applications, you should never hardcode the default public DNS. Instead use:

Option 1: Elastic IP

# AWS CLI example
aws ec2 allocate-address
aws ec2 associate-address --instance-id i-1234567890abcdef0 --public-ip 203.0.113.0

Option 2: Route 53 Alias Record

# Route 53 JSON configuration
{
  "Changes": [{
    "Action": "CREATE",
    "ResourceRecordSet": {
      "Name": "api.example.com",
      "Type": "A",
      "AliasTarget": {
        "HostedZoneId": "Z1H1FL5HABSF5",
        "DNSName": "dualstack.my-elb-123456789.us-west-2.elb.amazonaws.com",
        "EvaluateTargetHealth": false
      }
    }
  }]
}

Option 3: Load Balancer

For web services, always place instances behind an ALB/ELB:

# Terraform example
resource "aws_lb" "app" {
  name               = "my-app-lb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.lb.id]
  subnets            = aws_subnet.public.*.id
}

You can track changes using CloudWatch Events:

# CloudWatch Event Rule
{
  "source": ["aws.ec2"],
  "detail-type": ["EC2 Instance State-change Notification"],
  "detail": {
    "state": ["running", "stopped"]
  }
}