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