53

I want to list the public IP addresses of my EC2 instances using Bash, separated by a delimiter (space or a new-line).

I tried to pipe the output to jq with aws ec2 describe-instances | jq, but can't seem to isolate just the IP addresses.

Can this be done by aws alone, specifying arguments to jq, or something else entirely?

Bas Peeters
  • 3,269
  • 4
  • 33
  • 49

5 Answers5

122

Directly from the aws cli:

aws ec2 describe-instances \
  --query "Reservations[*].Instances[*].PublicIpAddress" \
  --output=text
Julio Faerman
  • 13,228
  • 9
  • 57
  • 75
  • 1
    Awesome. But this outputs three columns: one with IP's on every row and two with IP's only on some rows. I get a nice tab-separated list when I use `Reservations[*].Instances[*].PublicIpAddress[]` for the query argument instead. – Bas Peeters Jul 25 '14 at 08:08
  • 8
    Wrap your `PublicIpAddress` in square-brackets to ensure 1-per-line, as suggested here: https://github.com/aws/aws-cli/issues/914#issuecomment-56210312. This works for me `--query 'Reservations[].Instances[].[PublicIpAddress]` – jaygooby Sep 05 '16 at 20:40
  • Is there a way to filter using security group? I tried: "aws ec2 describe-instances --filters Name=vpc-id,Values={vpcid} Name=InstanceId,Values={securityGroupID} --output=text" . But I get nothing – Shahar Hamuzim Rajuan Feb 05 '18 at 07:51
  • 2
    If you want the instances' KeyName to go with the public IP address, you can get it with `--query "Reservations[*].Instances[*].[KeyName, PublicIpAddress]"` – Daryn May 20 '19 at 13:36
21
  • Filter on running instances (you can drop that part if you don't need it)
  • Query for each PublicIPaddress and the Name Tag, handling when Name isn't set
aws ec2 describe-instances \
  --filter "Name=instance-state-name,Values=running" \
  --query "Reservations[*].Instances[*].[PublicIpAddress, Tags[?Key=='Name'].Value|[0]]" \
  --output text
Brad Giaccio
  • 325
  • 2
  • 4
  • aws ec2 describe-instances --region {{ region }} \ --filters Name=instance-state-name,Values=running \ --query 'Reservations[*].Instances[].{ID:InstanceId, Name:Tags[?Key==`Name`].Value,EnvID:Tags[?Key==`EnvID`].Value, EnvLayer:Tags[?Key==`EnvLayer`].Value, Type:InstanceType, AZ:Placement.AvailabilityZone, State:State.Name, IP:PrivateIpAddress | [0] }' \ --output text | sed -e 's,ENVID,,g' -e 's,ENVLAYER,,g' -e 's,NAME,,g' | tr '\t' '\n' | sed -e '/^$/d' | awk '{ORS=NR%8?", ":"\n";print}' – Ashish Karpe Jan 05 '23 at 04:39
  • I am using above command, getting None for IP:PrivateIpAddress in my output >> "ca-central-1a, i-xyz, None, running, r5.xlarge, 800, ABC, XYZ800" .......... @Brad Giaccio please could let me know what's wrong here why it's not showing PrivateIpAddress – Ashish Karpe Jan 05 '23 at 04:42
  • Note I am running this command inside Jenkins and Ansible pipeline so this output is displayed in Jenkins console output – Ashish Karpe Jan 05 '23 at 06:59
  • You want `Ip:PrivateIpAddress` vice `IP` – Brad Giaccio Jan 11 '23 at 02:12
9

The below command would list the IP addresses of all your running EC2 instances

aws ec2 describe-instances | grep PublicIpAddress | grep -o -P "\d+\.\d+\.\d+\.\d+" | grep -v '^10\.'

Hope that answers your query...

But this works without all the errors about access:

wget -qO- http://instance-data/latest/meta-data/public-ipv4/|grep .
dkb
  • 4,389
  • 4
  • 36
  • 54
A Null Pointer
  • 2,261
  • 3
  • 26
  • 28
  • 1
    I just tried the same command today 10/23/15 and it works perfectly fine without any problems. What is the error that you see ? – A Null Pointer Oct 23 '15 at 20:30
  • 1
    Grep works differently on OSX which has the BSD version of grep vs GNU found mostly on other standard Linux distributions http://stackoverflow.com/questions/19413494/does-grep-work-differently-on-osx – A Null Pointer Oct 26 '15 at 21:52
6

You can use instance metadata so you can run the following command from the ec2 instance:

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

and it will give you the public IP of the instance. If you want the private IP, you will run

curl http://169.254.169.254/latest/meta-data/local-ipv4
Frederic Henri
  • 51,761
  • 10
  • 113
  • 139
  • 2
    This is great! However, I suggest using `wget -qO -` instead of `curl` (even though I use curl 99.9% or the time in my scripts. The reason is that `curl` will output the content of the 404 page if the server doesn't have a public IP, and `wget` does not. So in bash it's simple to do `public_ip="$(wget -qO - http://169.254.169.254/latest/meta-data/public-ipv4)"` and get expected results. You can then test with `if [[ -n $public_ip ]]; then echo "Public IP: $public_ip"; fi` – Bruno Bronosky Jan 17 '18 at 19:29
5
aws ec2 describe-instances --query "Reservations[].Instances[][PublicIpAddress]"

Refer: http://docs.aws.amazon.com/cli/latest/userguide/controlling-output.html

Sarat Chandra
  • 5,636
  • 34
  • 30