How to find EC2 instances that have "null" for the PublicIpAddress? - amazon-web-services

When I run ...
$ aws ec2 describe-instances --region=us-west-1 \
> --filters Name=instance-state-name,Values=stopped \
> Name=ip-address,Values=null \
> Name=block-device-mapping.status,Values=attached \
> --query "Reservations[].Instances[].[InstanceId,PublicIpAddress,BlockDeviceMappings[].Ebs.VolumeId]"
I get back ...
[]
If I take out the filter Name=ip-address,Values=null I get this back ...
[
[
"i-XXXXX",
null,
[
"vol-f6f6f6f"
]
],
[
"i-d4XXXX8b",
"XX.XX.XXX.XX",
[
"vol-0ca0ca0ca"
]
],
How can I just get those EC2 instances that just have "null" for the PublicIpAddress?

Since there is no public-ip, that filter doesn't seem to work.
Instead, I notice that such instances seem to have this entry:
"PublicDnsName": "",
Therefore, you should be able to use this logic:
aws ec2 describe-instances --query 'Reservations[].Instances[?PublicDnsName==``].InstanceId'

Related

Create awscli table output with EC2 Instance Name and Private IP address

If I don't try and put into a table, this is the output
[
[
"naaws_01"
],
"[\"172.24.7.96\",\"172.24.3.248\"]"
]
Using this command
aws ec2 describe-instances \
--query 'Reservations[*].Instances[].[ Tags[?Key==`Name`].Value, NetworkInterfaces[].PrivateIpAddress[] | join(`,`, to_array(to_string(#))) ]' \
--profile famc-prod \
--region us-east-1 \
--output table
The result is a table with name and IP address in a single column. I'm not able to split on [name],[list of IP address]
aws ec2 describe-instances \
--query 'Reservations[*].Instances[].[ Tags[?Key==`Name`].Value | join(`, `, #), NetworkInterfaces[].PrivateIpAddress[] | join(`, `, to_array(to_string(#))) ]' \
--profile famc-prod \
--region us-east-1 \
--output table
A couple of things I discovered...
First, I was trying to string together the query and then pass to the join to_array.
aws ec2 describe-instances \
--query 'Reservations[*].Instances[].[ Tags[?Key==Name].Value, NetworkInterfaces[].PrivateIpAddress[] | join
Following the example, https://stackoverflow.com/a/56671906/7802257
I noticed that it was query | join the next item | join the next item | join to array
The way I was doing it originally the results are,
[
[
"naaws_01"
],
[
"172.24.7.96",
"172.24.3.248"
]
],
Notice the pattern [], [] - I couldn't parse that
Using the correct answer the results are (ignore the results; focus on pattern)
[
[
"i-07c722b2a227ff5e6",
[
"All internal"
]
]
]
Now, with a "comma" it can be parsed into a table.
Hope my explanation helps.

Find all aws load balancers which has a particular instance

I would like to get names of all the aws load balancers which has a particular instance.
I can list the instances in the ELB's using the following command
aws elb describe-load-balancers --query "LoadBalancerDescriptions[*].{ID:LoadBalancerName,InstanceId:Instances[*].InstanceId}[*]. {ELB:ID,InstanceId:InstanceId[*]}" --output=json
Sample Output:
[
{
"ELB": "my_name",
"InstanceId": [
"instance-id-A",
"instance-id-B",
]
},
{
"ELB": "my_name2",
"InstanceId": [
"instance-id-B",
"instance-id-C"
]
},
{
"ELB": "my_name3",
"InstanceId": [
"instance-id-A",
"instance-id-C"
]
}
]
How do I filter this output to only return the ELB names which has instance id A?
The contains command will give you what you're looking for
aws elb describe-load-balancers --query "LoadBalancerDescriptions[*].{ID:LoadBalancerName,InstanceId:Instances[*].InstanceId}[?contains(to_string(#),'instance-id-A')]"
Provides output:
[
{
"ID": "lb_name",
"InstanceId": [
"i-1234567890"
]
}
]
References
http://jmespath.org/specification.html#contains
Another approach, which I like better as I think is more easy to use, is to use jq for filtering:
aws elb describe-load-balancers | jq -r '.LoadBalancerDescriptions[] | select (.Instances[].InstanceId == "instance-id-A") | .LoadBalancerName'
Output:
SampleLBName1
SampleLBName2

How to get all security groups through AWS CLI of an EC2 to show in a table

I am trying to show all instances along with attached security groups, block device name and their deleteontermination status. I need to show this data in table format but I am continuously getting the below error.
Kindly help me to understand what I am missing here.
PR-MacBook-Pro:~ pr$ aws ec2 describe-instances --output table --query 'Reservations[*].Instances[*].[InstanceId,SecurityGroups[].GroupName,Placement.AvailabilityZone,BlockDeviceMappings[].DeviceName, BlockDeviceMappings[].Ebs.DeleteOnTermination]'
Row should have 1 elements, instead it has 2
PR-MacBook-Pro:~ pr$
I came across this while searching in google.
After I did a bit of research I found that you have to use | join(`, `, #)
So the command will be
aws ec2 describe-instances --output table --query 'Reservations[*].Instances[*].[InstanceId,SecurityGroups[].GroupName | join(`, `, #),Placement.AvailabilityZone,BlockDeviceMappings[].DeviceName | join(`, `, #), BlockDeviceMappings[].Ebs.DeleteOnTermination | join(`, `, to_array(to_string(#)))]'
modify your command as below to make it work
aws ec2 describe-instances --output table --region "us-east-1" --query 'Reservations[*].Instances[*].[InstanceId,SecurityGroups[].GroupName |[0],Placement.AvailabilityZone,BlockDeviceMappings[].DeviceName |[0], BlockDeviceMappings[].Ebs.DeleteOnTermination|[0] ]'
the response was in the format of
[
[
"i-xxxxxxxx",
[
"xxxxxx"
],
"us-east-1a",
[
"/dev/xvda"
],
[
true
]
]
]
so you need parse the array element using | [0]

How to extract a particular Key-Value Tag from ec2 describe-instances

I've got the following from describe-instances:
{
"Reservations": [
{
"Instances": [
{
"PublicDnsName": "ec2-xxxxx.amazonaws.com",
"Tags": [
{
"Key": "Name",
"Value": "yyyyy"
},
{
"Key": "budget_cluster",
"Value": "zzzzz"
},
{
"Key": "poc",
"Value": "aaaaaaa"
}
]
}
]
}
]
}
For each instance, I would like to extract the PublicDnsName and the value of the "budget_cluster" tag key. How to do this either with ec2 describe-instances or with jq ?
Modifying Frédéric's answer:
aws ec2 describe-instances --output text --query \
'Reservations[].Instances[].[PublicDnsName, Tags[?Key==`budget_cluster`].Value | [0]]'
Would produce:
ec2-xxxxx.amazonaws.com zzzzz
ec2-bbbbb.amazonaws.com yyyyy
I've changed the output to text, which removes as much formatting as possible and selected the individual tag value with | [0] since there will only ever be one per instance anyway. Finally, I removed the [] at the end so that the resulting list isn't flattened. That way in text output each entry will be on its own line.
You can also make this more robust by only selecting instances that actually have that tag. You could do so with further modifications to the --query parameter, but it is better in this case to use the --filters parameter since it does service-side filtering. Specifically you want the tag-key filter: --filters "Name=tag-key,Values=budget_cluster"
aws ec2 describe-instances --output text \
--filters "Name=tag-key,Values=budget_cluster" --query \
'Reservations[].Instances[?Tags[?Key==`budget_cluster`]].[PublicDnsName, Tags[?Key==`budget_cluster`].Value | [0]]'
Would still produce:
ec2-xxxxx.amazonaws.com zzzzz
ec2-bbbbb.amazonaws.com yyyyy
But over the wire you would only be getting the instances you care about, thus saving money on bandwidth.
Using jq 1.5 or later, the simplest approach is to use from_entries.
After a minimal fix of the illustrative input, the following invocation:
$ jq '.Reservations[]
| .Instances[]
| [.PublicDnsName, (.Tags|from_entries|.budget_cluster)]' input.json
produces:
[
"ec2-xxxxx.amazonaws.com",
"zzzzz"
]
If you do not have jq 1.5 or later, the following should work:
$ jq1.4 '.Reservations[]
| .Instances[]
| [.PublicDnsName, (.Tags[]|select(.Key=="budget_cluster") | .Value)]' input.json
The answer of #peak is great and I keep learning from him on the jq part but again you can achieve quite a lot from the AWS CLI
aws ec2 describe-instances --query \
'Reservations[].Instances[].{PublicDnsName:PublicDnsName, Budget:Tags[?Key==`budget_cluster`].Value}'
would produce
[
{
"PublicDnsName": "ec2-xxxxx.amazonaws.com",
"Budget": [
"zzzz",
]
}
]
If you do not want to make a new strict JSon out of it, just take the values
aws ec2 describe-instances --query \
'Reservations[].Instances[].[PublicDnsName, Tags[?Key==`budget_cluster`].Value][]'
will produce
[
"ec2-xxxxx.amazonaws.com",
[
"zzzz"
]
]

How to list only the instance id and related tags

I using the CLI tools and I want to list only the instance ID and related tags of an instance. The command that I am using is ec2-describe instances. I have tried certain filters but nothing is working out.
Can anybody help ??
error :
./Instance_Audit.sh: line 24: $: command not found
./Instance_Audit.sh: line 25: syntax error near unexpected token `do'
./Instance_Audit.sh: line 25: ` do echo $ID ; echo $(aws ec2 describe-instances --query "Reservations[].Instances[?InstanceId==\`$ID\`].Tags[]") done'
Using the aws cli, I can produce a few different alternatives of the tag output:
aws ec2 describe-instances --output text --query 'Reservations[*].Instances[*].[InstanceId,Tags[]]'
Result: i-xxxxx [{u'Value': 'key1value', u'Key': 'key1name'}, {u'Value': 'key2value', u'Key': 'key2name'}]
aws ec2 describe-instances --output text --query 'Reservations[*].Instances[*].[InstanceId,Tags[].*]'
Result: i-xxxxx [['key1value', 'key1name'], ['key2value', 'key2name']]
aws ec2 describe-instances --output text --query 'Reservations[*].Instances[*].[InstanceId,Tags[].Key,Tags[].Value]'
Result: i-xxxx ['key1name', 'key2name'] ['key1value' 'key2value']
Is any of those formats what you're looking for?
The AWS CLI command
aws ec2 describe-instances --region us-west-2 --query 'Reservations[].Instances[].[InstanceId,Tags[]]' --output text
produces these results:
i-789c55c3
Name Instance1
aws:cloudformation:logical-id Instance1
aws:cloudformation:stack-id arn:aws:cloudformation:us-west-2:012345678901:stack/test10-test10-foobarfoobar/a6e545a0-af52-11e4-a0be-50d5020578e0
aws:cloudformation:stack-name test10-test10-foobarfoobar
i-77c108cc
Name Instance2
aws:cloudformation:logical-id Instance2
aws:cloudformation:stack-id arn:aws:cloudformation:us-west-2:012345678901:stack/test10-test10-foobarfoobar/a6e545a0-af52-11e4-a0be-50d5020578e0
aws:cloudformation:stack-name test10-test10-foobarfoobar
If that is not in the format you are looking for, can you provide an example of they format you are expecting?
If you want to only display the instance id and the tags associated to that instance, you can use something like :
$ for ID in $(aws ec2 describe-instances --region eu-west-1 --query "Reservations[].Instances[].InstanceId" --output text); do echo $ID ; echo $(aws ec2 describe-instances --region eu-west-1 --query "Reservations[].Instances[?InstanceId==\`$ID\`].Tags[]") done
i-60****2a
[ [ { "Value": "SB", "Key": "Name" } ] ]
i-1a****56
[ [ { "Value": "Course and Schedule on Apache 2.4", "Key": "Name" } ] ]
i-88eff3cb
[ [ { "Value": "secret.com", "Key": "Name" } ] ]
i-e7****a5
[ [ { "Value": "2014.03 + Docker", "Key": "Name" } ] ]
I could not find a way to do that with only one AWS CLI call. Should someone come up with a shorter solution, I would love to hear from you.
If you want to filter to certain tag key/value only, you can edit the aws ec2 describe-instances to add a --filter option.
For example :
aws ec2 describe-instances --region eu-west-1 --filter "Name=tag:Name,Values=SB"
--Seb
simple answer:
aws ec2 describe-instances \
--query 'Reservations[*].Instances[*].[InstanceId,Tags[*]]'
not so simple answer .. the same principle could be applied to both instances and vpc's
# how-to get all the tags per instance-id with aws ec2 for prd env
while read -r i ; do \
aws ec2 describe-tags --filters "Name=resource-id,Values=$i" \
--profile prd; done < <(aws ec2 describe-instances \
--query 'Reservations[*].Instances[*].InstanceId' --profile prd)
# how-to get all the tags per virtual-private-cloud-id
while read -r v; do aws ec2 describe-tags \
--filters "Name=resource-id,Values=$v" ; \
done < <(aws ec2 describe-vpcs \
--query 'Vpcs[*].VpcId'|perl -ne 's/\t/\n/g;print')