use jq to pull two elements from json - amazon-web-services

I need to build a list of our AMIs. I need to get the AMI ID and the AMI Name. How can I do that in one command?
Right now I can only go:
aws ec2 describe-images --owners self --profile=nonprod | jq -r '.Images[].ImageId'
To get the AMI ID. Or I can go:
aws ec2 describe-images --owners self --profile=nonprod | jq -r '.Images[].Name'
To get the AMI name. But is there a way to get at both elements in a single command?

Instead of jq, use the (JMESPath) query option of the CLI to extract the values you want.
aws ec2 describe-images --owners self --query 'Images[*].[ImageId, Name]' --output text
Output
ami-12345678 MY-AMI-2018-05
ami-90123456 MY-AMI-2018-06

For the record, here's how to combine the two jq commands:
jq -r '.Images[] | (.ImageId, .Name)'

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 fetch second last AMI ID using AWS CLI

Using below AWS CLI command, I am able to fetch recently created AMI ID by sorting CreationDate.
aws ec2 describe-images --owners 1234567890 --filters 'Name=name,Values=*AMI*' 'Name=state,Values=available' --output json | jq -r '.Images | sort_by(.CreationDate) | last(.[]).ImageId'
I also wanted to get the second last AMI ID using AWS CLI. Could someone help me out on this?
You can use indices, like in python ([-2]):
aws ec2 describe-images --owners 1234567890 --filters 'Name=name,Values=*AMI*' 'Name=state,Values=available' --output json | jq -r '.Images | sort_by(.CreationDate)[-2].ImageId'

AWS CLI command to list stopped instances

ec2-describe-instances --filter "instance-state-name=stopped"
This helps me list all stopped instances with all its details.
How should I modify the command that it only gives me the names of the stopped instances?
You are using old style commands. Use AWS CLI to get what you want.
aws ec2 describe-instances --filters "Name=instance-state-name,Values=stopped" --query 'Reservations[].Instances[].Tags[?Key==`Name`].Value[]'
you can use aws cli combined with other tools like jq
aws ec2 describe-instances \
--filter Name=instance-state-name,Values=stopped \
--query 'Reservations[].Instances[].{ID: InstanceId,Hostname: PublicDnsName,Name: Tags[?Key==`Name`].Value }' \
| jq '.[] | .Name[]'
this will produce output in form:
"instance2"
"instance1"

Possible: AWS CLI Describe Not Equal To

I am currently using the AWS CLI to select instances and I have the following query:
aws ec2 describe-instances --filter "Name=instance.group-name,Values=my-cluster" "Name=instance-state-name,Values=running,pending,stopped" 'Name=tag:Name, Values=someInstance*'
This works and selects all the instances that start with someInstance.
However, I want to do the opposite, select all other instances that do NOT match this. I have tried using a regex but this doesn't work:
aws ec2 describe-instances --filter "Name=instance.group-name,Values=my-cluster" "Name=instance-state-name,Values=running,pending,stopped" 'Name=tag:Creater, Values=^(?!someInstance).*$'
Is this possible?
This can be accomplished by using JQ -
aws ec2 describe-instances --filter "Name=instance.group-name,Values=my-group" "Name=instance-state-name,Values=running,pending,stopped" | jq '.Reservations[].Instances[] | select(contains({Tags: [{Key: "Creator"}^C{Value: "myExclusion"}]}) | not)'

How to find non-shared aws ami

I'd like to delete all AMIs that my own and they are non-shared.
Eg:
$aws ec2 describe-images --executable-users 804427628951
This will list all images by user 804427628951 with explicit launch permissions. But I don't know how to list all non-shared AMI. Could you please help?
Thanks.
You can list all of your own Amazon Machine Images (AMIs) with the command:
aws ec2 describe-images --filters Name=image-type,Values=machine Name=owner-id,Values=YOUR_ACCOUNT_ID
Within the output, private images will be shown as "Public": false.
You could also show only private images:
aws ec2 describe-images --filters Name=image-type,Values=machine Name=is-public,Values=false Name=owner-id,Values=YOUR_ACCOUNT_ID
You can list AMIs that are in an account and how they are shared using a combination of aws ec2 describe-images and aws ec2 describe-image-attribute. The latter can return the launchPermission element which is a list of accounts that the AMI is shared with. Combining the two allows you to iterate over all images and count how many times they are shared as follows:
for ami in $(aws ec2 describe-images --owners self | jq -r '.Images[].ImageId')
do aws ec2 describe-image-attribute --image-id $ami --attribute 'launchPermission' | \
jq '.ImageId + " - " + ([.LaunchPermissions[]]|length|tostring)'
done
In your case you're only interested in the unshared images so you might want to do this:
for ami in $(aws ec2 describe-images --owners self | jq -r '.Images[].ImageId')
do
ct=$(aws ec2 describe-image-attribute --image-id $ami --attribute 'launchPermission' | \
jq '[.LaunchPermissions[]]|length')
if [ 0 -eq $ct ]; then echo $ami; fi
done