Amazon EC2 instances receive a public DNS name formatted like ec2-x-x-x-x.compute-1.amazonaws.com
. This automatically generated DNS entry follows the same lifecycle as the instance's public IP address. Both will change when you:
- Stop and restart the instance
- Terminate the instance
- Change instance types that require hardware virtualization
This behavior is intentional and serves several purposes:
// Example of retrieving the public DNS in AWS CLI
aws ec2 describe-instances \
--instance-ids i-1234567890abcdef0 \
--query 'Reservations[].Instances[].PublicDnsName' \
--output text
- Provides immediate DNS resolution without manual configuration
- Works seamlessly with Elastic IPs when assigned
- Maintains consistency with AWS's ephemeral resource model
For production environments, consider these solutions:
1. Elastic IP + Route 53
# Terraform example for Route 53 record
resource "aws_route53_record" "web" {
zone_id = "${aws_route53_zone.primary.zone_id}"
name = "web.example.com"
type = "A"
ttl = "300"
records = ["${aws_eip.web.public_ip}"]
}
2. Load Balancer DNS
ALB/ELB DNS names remain stable and can be:
- Used directly (though still not permanent)
- Mapped to custom domains via CNAME
3. EC2 Instance Connect Endpoint
AWS's newer solution for stable access:
aws ec2 create-instance-connect-endpoint \
--subnet-id subnet-123456 \
--security-group-ids sg-123456 \
--region us-west-2
The default public DNS is useful for:
- Temporary testing environments
- CI/CD pipelines that rebuild infrastructure
- Automated scripts that can handle DNS changes
// Python example handling dynamic DNS
import boto3
def get_instance_dns(instance_id):
ec2 = boto3.client('ec2')
response = ec2.describe_instances(InstanceIds=[instance_id])
return response['Reservations'][0]['Instances'][0]['PublicDnsName']
When working with AWS EC2 instances, you'll notice the public DNS follows the pattern ec2-x-x-x-x.compute-1.amazonaws.com
. This address isn't persistent - it changes whenever you:
- Stop and restart the instance
- Terminate the instance
- Change instance types
- Move to different availability zones
The public DNS is directly tied to the public IP address, which itself is ephemeral by default. This design reflects AWS's elastic infrastructure philosophy. The reasons include:
1. Cost optimization (elastic IPs cost money when not attached)
2. Resource flexibility
3. Load balancing capabilities
4. Multi-AZ deployment patterns
Here are three technical approaches to handle this in your applications:
1. Using Elastic IPs with Route 53
import boto3
# Assign elastic IP
ec2 = boto3.client('ec2')
response = ec2.allocate_address(Domain='vpc')
allocation_id = response['AllocationId']
# Associate with instance
ec2.associate_address(
AllocationId=allocation_id,
InstanceId='i-1234567890abcdef0'
)
# Update Route53 record
route53 = boto3.client('route53')
route53.change_resource_record_sets(
HostedZoneId='Z3M3LMPEXAMPLE',
ChangeBatch={
'Changes': [{
'Action': 'UPSERT',
'ResourceRecordSet': {
'Name': 'api.example.com',
'Type': 'A',
'TTL': 300,
'ResourceRecords': [{
'Value': response['PublicIp']
}]
}
}]
}
)
2. Instance Metadata Service Lookup
For temporary needs, query the instance metadata:
curl http://169.254.169.254/latest/meta-data/public-hostname
3. CloudFormation with Custom Domain
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
# Instance properties here
MyElasticIP:
Type: AWS::EC2::EIP
Properties:
InstanceId: !Ref MyEC2Instance
MyDNSRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneName: example.com.
Name: api.example.com
Type: A
TTL: '300'
ResourceRecords:
- !GetAtt MyElasticIP.PublicIp
Despite its limitations, the public DNS can be useful for:
- Temporary testing environments
- CI/CD pipelines where instances are ephemeral
- Internal services that use service discovery
- Blue/green deployments with load balancers
For production systems, consider:
- Always using Route 53 or another DNS service
- Implementing health checks with your DNS
- Using CloudFront or ALB for additional abstraction
- Automating DNS updates in your deployment scripts