How to fetch second last AMI ID using AWS CLI - amazon-web-services

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'

Related

use jq to pull two elements from json

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)'

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"

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

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 get a list of all public IPs and their instance names on Amazon EC2

Anyone know how to get a list of all public IPs and their instance names on Amazon EC2 using aws CLI?
This got me the list of public IPs, but not their associated instance names.
aws ec2 describe-instances --query "Reservations[].Instances[].PublicIpAddress" --output text
Thanks in advance.
http://docs.aws.amazon.com/cli/latest/userguide/controlling-output.html
Update: The CLI now supports filters:
aws ec2 describe-instances --query "Reservations[].Instances[].[PublicIpAddress,InstanceId,Tags[?Key=='Name'].Value]"
Got it working using this:
aws ec2 describe-instances --output table --query 'Reservations[].Instances[].[Tags[?Key==`Name`] | [0].Value, PublicIpAddress]'
Adding this for folks that will commonly find this post when searching for how to get your instance info.
In powershell you can use the following:
(Get-EC2Instance -ProfileName Profile).Instances | select InstanceId,PrivateIPAddress,PublicIpAddress #{Name="Servername";
Expression={$_.tags | where key -eq "Name" | select Value -expand Value}} | Format-Table.
With the Python AWS CLI you can use:
aws ec2 describe-instances --region=us-east-1 --query 'Reservations[*].Instances[*].[InstanceId,Tags[?Key==`Name`].Value|[0],PrivateIpAddress,PublicIpAddress]' --output text --profile ProfileName