AWS CLI add name to results of describe-instances query - amazon-web-services

I'm prefacing this with a call for any non-AWS-written guides for their CLI stuff... their examples are few and far between and tell me nothing about the required syntax and further, fleshed-out reading would be welcome.
I'm trying to replicate a few tasks we do in the GUI with a script to save time. Currently I'm trying to find out the state of an instance by feeding it the name of the instance (aka, the Name tag). The issue is that the output I'm getting is only the state, with no identifying information. Sometimes users will put in a wildcard and get multiple instances back, and I would like to display the name of each to differentiate.
My successful query for the state of an instance looks like so;
aws ec2 describe-instances --query "Reservations[].Instances[].State[]" --filter Name=tag:Name,Values="${userinput}" --output text
With an output of
16 running
16 running
16 running
16 running
16 running
16 running
While it is correct that all of these matched my input because of the wildcard, eg test*, I need to know what each one is called. Not the instance id, the name, ie test01, test02, etc.
I would have expected it to be
aws ec2 describe-instances --query "Reservations[].Instances[].State[].Tags[?Key=='Name'].Value" --filter Name=tag:Name,Values="${state}" --output text
but that outputs an error, or
aws ec2 describe-instances --query "Reservations[].Instances[].State[].[Tags[?Key=='Name'].Value]" --filter Name=tag:Name,Values="${state}" --output text
but that gives me None
How can I add the name column to the output?

The text output format is kind of ugly because it prints multiple lines per instance, but here's a working version:
aws ec2 describe-instances --query "Reservations[].Instances[].[State.Name, Tags[?Key=='Name'].Value[]]" --filter Name=tag:Name,Values="${userinput}" --output text
I couldn't figure out how to get each instance on one line using just the AWS CLI tool, but here's a version that prints one line per instance by piping to sed:
aws ec2 describe-instances --query "Reservations[].Instances[].[State.Name, Tags[?Key=='Name'].Value[]]" --filter Name=tag:Name,Values="${userinput}" --output text | sed 'N;s/\n/ /'

Related

I have a list of EC2's, and want to loop through the list in bash, does anyone have a way?

I'm using this command "aws ec2 describe-instances --region us-west-2 --filters "Name=instance-state-name,Values=running" --output table --query 'Reservations[].Instances[].InstanceId'". Returns a list of all my running ec2's in us west 2, i'd like to take each output in this list and loop through each one with another command to see which ones are using ssm. Thanks for all responses.
I've tried making an empty array, but that got me no where.
What I've tried, making variable x an empty list
x=[]
and then running the above command to try to have outputs added to empty list x=aws ec2 describe-instances --region us-west-2 --filters "Name=instance-state-name,Values=running" --output table --query 'Reservations[*].Instances[*].InstanceId'. In general I am more familiar with python, but this was just meant to be a quick bash tool.
error: getNonSSMEC2.sh: line 3: ec2: command not found
So firstly - when you want to capture bash command output as a variable you need to declare it like this: x=$(ls) or x=`ls`
Regarding loop:
x=`aws ec2 describe-instances --region us-west-2 --filters "Name=instance-state-name,Values=running" --query 'Reservations[*].Instances[*].InstanceId'`
for id in $(echo $x | jq -r ".[0][0]")
do
echo $id
done
I assume in the loop you should use this function to get SSM informations: https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-instance-information.html
Btw, you can always use describe-instance-information to get list of ec2 instances instead of using ec2 describe-instances.

How to list all EC2 instances of multiple accounts (profiles)

Is there an option I can give this command to make it iterate through all my profiles/accounts?
aws ec2 describe-instances --query "Reservations[*].Instances[*].
{PublicIP:PublicIpAddress,Type:InstanceType,Name:Tags[?Key=='Name']|
[0].Value,Status:State.Name}" --filters "Name=instance-state-name,Values=running"
"Name=tag:Name,Values='*'" --output table
I have to run this in multiple accounts and I was wondering if there's a way to avoid writing a script that loop through all the profiles
I can't find anywhere if there is something like --profile allProfiles or --profiles [*]
You will need to create a simple script since aws cli only works for a single profile.
In bash, that would be something like:
for profile in `aws configure list-profiles`; do aws ec2 describe-instances --profile $profile ;done;
What might be useful is to append each command's output to the same file and then process the file as if it was the output of a single command:
outputFile=`mktemp` ; for profile in `aws configure list-profiles`; do aws ec2 describe-instances --profile $profile >> $outputFile ;done; cat $outputFile
For json you might want to process the commands output via jq before appending to file.

AWS CLI: How to achieve certain output format for describe-instances?

I'm trying to pull a list of all of our instances formatted like so:
Tag:Name.Value instance-id private-ip-address
This is the command I'm using:
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[Tags[?Key==`Name`].Value[],InstanceId,PrivateIpAddress]' --output text
And this is what I'm getting as output:
instance-id private-ip-address
tag:name.value
Even though I've got the Tag bit before everything else, it still lists on a new line below the corresponding ID/IP.
Any way to fix this? Also any way to retrieve a format like this:
Tag:name.value,instance-id,private-ip-address
Thanks
CLI
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[[Tags[?Key==`Name`].Value[],InstanceId, PrivateIpAddress][]]' --output text | sed 's/\t/,/g'
It can be achieved without using jq just with aws cli query syntax.
You need to "flatten" tag name with other fields with [] operator. The output will be splitted by tab, so sed 's/\t/,/g' to replace tab with comma.
Note: on Macs sed 's/\t/,/g' may not work as \t is not recognized as Tab character. To insert tab, press Ctrl+V and then Tab
I've found jq to be the most flexible method for working with the AWS CLI.
The following takes input from describe-instances and pipes it into jq. jq extracts the bits you're interested in and outputs it in the CSV format you specified.
CLI
aws ec2 describe-instances |jq -r '.Reservations[].Instances[]| . as $i | [($i.Tags|from_entries|.Name)?, $i.InstanceId, $i.PrivateIpAddress] |#csv'
Output
"ac02-01","i-0123456789ABCDEF","10.0.0.214"
References
How to extract a particular Key-Value Tag from ec2 describe-instances

Terminate a set on EC2 instances by tags using AWS CLI

Faily new to AWS however I am looking to terminate a set of ec2 instances using the AWS CLI by filtering by a Tag name.
If I use describe-instances, I can filter by tag:key=value . For terminate-instances I don't see a way of filtering. I assume this is possible since I can filter and terminate using the AWS console but I am looking to do this via CLI.
Latest AWS CLI allows you to avoid the need for any scripts or jq:
aws ec2 terminate-instances --instance-ids $(aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId' --filters "Name=tag:tagkey,Values=tagvalue" --output text)
as long as the number of expected instances is not huge, the above can be used.
The terminate-instances command only takes a list of instance IDs. You would need to write a script to run the describe-instances command first and capture the instance IDs, then pass those IDs to the terminate-instances command.
I created the following script(.sh) and it worked for me:
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[InstanceId]' --filters 'Name=tag-value,Values=MYTAG' --output text |
grep stopped |
awk '{print $2}' |
while read line;
do aws ec2 terminate-instances --instance-ids $line
done

How do I use AWS CLI to list all instances with name, state, instance size and AZ in the same line

How do I use AWS CLI to list all instances with name, state, instance size and AZ in the same line?
I got close with this:
aws ec2 describe-instances --query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value[], Placement.AvailabilityZone,InstanceType,State.Name]' --output text
But that outputs the instance name below the rest. I want to keep them on the same line so I can copy to a spreadsheet.
You need to change Tags[?Key==Name].Value[] to Tags[?Key==Name].Value[] | [0]; I think it's because Tags[?Key==Name].Value[] returns an array which the text output format doesn't know how to put on a single line, piping to [0] extracts the (single) element out for you. So your full query should be :
aws ec2 describe-instances --query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value[] | [0], Placement.AvailabilityZone,InstanceType,State.Name]' --output text
If you don't wish to scratch your eyes out with the piping syntax, consider this simple shell workaround:
aws ec2 describe-instances --query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value[], Placement.AvailabilityZone,InstanceType,State.Name]' | \
while read Zone Type State ; do
read Name
echo "$Name $Zone $Type $State"
done
Assuming that the original command returns 2 lines like these for each machine:
my-ec2-host-xyz
us-east-1d t2.micro running
The output of the above script will be:
my-ec2-host-xyz us-east-1d t2.micro running
This hack is easily understood and can readily be adapted to --output text of any complexity.