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:
- Use Elastic IPs for long-running instances
- Implement DNS abstraction with Route53
- Consider load balancers for web applications
- 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"]
}
}