How to Retrieve External Hostname of AWS EC2 Instance Programmatically


2 views

When working with AWS EC2 instances, it's crucial to distinguish between internal and external hostnames:

  • Internal hostname: Resolves to private IP (e.g., ip-10-0-1-25.ec2.internal)
  • External hostname: Resolves to public IP/DNS (e.g., ec2-54-210-123-45.compute-1.amazonaws.com)

Here are three reliable approaches to retrieve the external hostname from within an EC2 instance:

1. Using AWS Instance Metadata Service

The most robust method using curl:

curl -s http://169.254.169.254/latest/meta-data/public-hostname

Example output:

ec2-203-0-113-25.compute-1.amazonaws.com

2. Via AWS CLI

If you have AWS CLI installed:

aws ec2 describe-instances \
--instance-ids $(curl -s http://169.254.169.254/latest/meta-data/instance-id) \
--query 'Reservations[0].Instances[0].PublicDnsName' \
--output text

3. Through Instance Metadata Endpoint

Alternative approach using wget:

wget -q -O - http://169.254.169.254/latest/meta-data/public-hostname

For your specific need with SCP, here's how to implement it:

# Get hostname and store in variable
EXT_HOST=$(curl -s http://169.254.169.254/latest/meta-data/public-hostname)

# Use in SCP command
scp -i ~/.ssh/key.pem /local/file.txt ec2-user@$EXT_HOST:/remote/path/
  • Always use IAM roles with least privilege
  • Never hardcode credentials in scripts
  • Consider using SSH agent forwarding for better security

If you're not getting the expected hostname:

  • Verify the instance has a public IP assigned
  • Check VPC settings and internet gateway configuration
  • Confirm security groups allow outbound HTTPS (for metadata service)

You can retrieve other useful instance metadata with:

curl http://169.254.169.254/latest/meta-data/

This will list all available metadata categories including:

ami-id
instance-type
placement/availability-zone
...

When working with AWS EC2 instances, you'll encounter two distinct hostnames:

  • Internal hostname: Resolves to private IP (e.g., ip-10-0-0-1.ec2.internal)
  • External hostname: Resolves to public IP/DNS (e.g., ec2-54-123-456-789.compute-1.amazonaws.com)

Here are several reliable approaches to retrieve the external hostname from within an EC2 instance:

Using EC2 Metadata Service

curl -s http://169.254.169.254/latest/meta-data/public-hostname

This returns the public DNS name like:

ec2-54-123-456-789.compute-1.amazonaws.com

Alternative AWS CLI Method

aws ec2 describe-instances \
  --instance-id $(curl -s http://169.254.169.254/latest/meta-data/instance-id) \
  --query 'Reservations[0].Instances[0].PublicDnsName' \
  --output text

For Elastic Beanstalk Environments

eb status | grep "CNAME" | awk '{print $2}'

Here's how to use the retrieved hostname for secure file transfers:

# Copy local file to remote EC2
scp -i ~/.ssh/key.pem ./file.txt ec2-user@$(curl -s http://169.254.169.254/latest/meta-data/public-hostname):/home/ec2-user/

# Copy from remote EC2 to local
scp -i ~/.ssh/key.pem ec2-user@$(curl -s http://169.254.169.254/latest/meta-data/public-hostname):/path/to/remote/file.txt .
  • Ensure your security group allows SSH (port 22) from your IP
  • Use IAM roles instead of hardcoding credentials
  • The public DNS may change if instance is stopped/started