How to Retrieve EC2 Instance Private and Public IPs Using AWS CLI: A Developer’s Guide


1 views

Many online solutions suggest using wget or curl to query instance metadata, but these methods fail when:

  • Instances aren't internet-facing
  • Security groups block external access
  • You need to query multiple instances programmatically

To get comprehensive IP information for your EC2 instances, use the describe-instances command with proper query filtering:

aws ec2 describe-instances \
  --instance-ids i-00914683ababcba7eb1 \
  --query 'Reservations[].Instances[].{PrivateIP:PrivateIpAddress, PublicIP:PublicIpAddress}' \
  --output json

For production environments, you'll often need to query multiple instances:

# Get all running instances with their IPs
aws ec2 describe-instances \
  --filters Name=instance-state-name,Values=running \
  --query 'Reservations[].Instances[].{InstanceID:InstanceId, PrivateIP:PrivateIpAddress, PublicIP:PublicIpAddress}' \
  --output table

Case 1: Get IPs for instances with specific tags

aws ec2 describe-instances \
  --filters Name=tag:Environment,Values=production \
  --query 'Reservations[].Instances[].{Name:Tags[?Key==Name].Value|[0], PrivateIP:PrivateIpAddress}' \
  --output text

Case 2: Extract just the public IP for SSH access

aws ec2 describe-instances \
  --instance-ids i-00914683ababcba7eb1 \
  --query 'Reservations[].Instances[].PublicIpAddress' \
  --output text

If you don't see public IPs in the output:

  • The instance may not be in a public subnet
  • No Elastic IP is assigned
  • The instance was stopped and started (changes public IP)

To specifically find instances with public IPs:

aws ec2 describe-instances \
  --filters Name=ip-address,Values=* \
  --query 'Reservations[].Instances[].InstanceId'

Add these to your ~/.bashrc for quick access:

get-ec2-ips() {
  aws ec2 describe-instances \
    --instance-ids $1 \
    --query 'Reservations[].Instances[].{PrivateIP:PrivateIpAddress, PublicIP:PublicIpAddress}' \
    --output table
}

list-running-ec2() {
  aws ec2 describe-instances \
    --filters Name=instance-state-name,Values=running \
    --query 'Reservations[].Instances[].{ID:InstanceId, Type:InstanceType, AZ:Placement.AvailabilityZone, PrivateIP:PrivateIpAddress, PublicIP:PublicIpAddress}' \
    --output table
}

Powerful queries for specific needs:

# Get instance IDs and their VPC IDs
aws ec2 describe-instances --query 'Reservations[].Instances[].[InstanceId,VpcId]'

# Find instances in specific AZ with private IPs
aws ec2 describe-instances \
  --filters Name=availability-zone,Values=us-east-1a \
  --query 'Reservations[].Instances[].[InstanceId,PrivateIpAddress]'

# Get all public DNS names
aws ec2 describe-instances \
  --query 'Reservations[].Instances[].PublicDnsName' \
  --output text

When managing AWS infrastructure, you often need to programmatically access instance network information. While curl ifconfig.me works for internet-facing instances, here's the proper AWS CLI approach:

aws ec2 describe-instances \
  --instance-ids i-00914683ababcba7eb1 \
  --query 'Reservations[].Instances[].{PrivateIP:PrivateIpAddress, PublicIP:PublicIpAddress}' \
  --output json

The API returns IP addresses in this structure:

{
  "Reservations": [
    {
      "Instances": [
        {
          "PrivateIpAddress": "172.31.32.156",
          "PublicIpAddress": "54.210.167.204"
        }
      ]
    }
  ]
}

For production environments, filtering by tags is often more practical:

aws ec2 describe-instances \
  --filters Name=tag:Environment,Values=prod Name=tag:Role,Values=web \
  --query 'Reservations[].Instances[].[InstanceId,PrivateIpAddress,PublicIpAddress]' \
  --output table

For complex environments, combine multiple filters and output formats:

# Get all running instances with their network info
aws ec2 describe-instances \
  --filters Name=instance-state-name,Values=running \
  --query 'Reservations[].Instances[].[
    InstanceId,
    PrivateIpAddress,
    PublicIpAddress || N/A,
    VpcId,
    SubnetId
  ]' \
  --output text

Some instances might not have public IPs. This JMESPath query handles null values:

aws ec2 describe-instances \
  --instance-ids i-00914683ababcba7eb1 \
  --query 'Reservations[].Instances[].{
    InstanceId: InstanceId,
    PrivateIP: PrivateIpAddress,
    PublicIP: PublicIpAddress || "NotAssigned"
  }'

To export all instance network information to CSV:

aws ec2 describe-instances \
  --query 'Reservations[].Instances[].[
    InstanceId,
    PrivateIpAddress,
    PublicIpAddress || N/A,
    Placement.AvailabilityZone
  ]' \
  --output csv > ec2_network_inventory.csv