aws cli query and output table format with named column - amazon-web-services

I just want to list EC2 with a table output format with a name for my column. But when I add the query to avoid to get EC2 from Auto Scaling Group, I got an error...
aws ec2 describe-instances --query 'Reservations[].Instances[].{AZ:Placement.AvailabilityZone}' --profile dev --output table
-------------------
|DescribeInstances|
+-----------------+
| AZ |
+-----------------+
| eu-west-3a |
| eu-west-3a |
| eu-west-3a |
...
OK
And there :
aws ec2 describe-instances --query 'Reservations[].Instances[?!contains(Tags[].Key, `aws:autoscaling:groupName`)].{AZ:Placement.AvailabilityZone}' --profile dev --output table
Row should have 1 elements, instead it has 0

Yeah, JMESPATH can be weird sometimes. Try:
aws ec2 describe-instances --query 'Reservations[].Instances[?!contains(Tags[].Key, `aws:autoscaling:groupName`)]|[].{AZ:Placement.AvailabilityZone}' --profile dev --output table
(If it works, don't ask me why.)

Related

Filtering aws ebs volumes by Time Creation

I'm trying to write a script that will delete all available volumes that are up for more than 1 hour.
So I took the line that filters the volumes by state
aws ec2 describe-volumes --filters Name=status,Values=available | jq '.Volumes[]'
And I tried to combine it with another query I have for filtering snapshots by time creation
aws ec2 describe-snapshots --owner self --output json | jq '.Snapshots[] | select(.StartTime < "'$(date --date='-1 month' '+%Y-%m-%d')'") | [.Description, .StartTime, .SnapshotId]'
So I combined this query but it does not return any volume
aws ec2 describe-volumes --filters Name=status,Values=available | jq '.Volumes[] | select(.CreateTime < "'$(date --date='-1 hour' '+%Y-%m-%d')'") | [.VolumeId]'
And another weird thing, if I replace CreateTime with blabla the query does not fail but returns me the volume
~ $ aws ec2 describe-volumes --filters Name=status,Values=available | jq '.Volumes[] | select(.blabla < "'$(date --date='-1 hour' '+%Y-%m-%d')'") | [.VolumeId]'
Found another way to do this
aws ec2 describe-volumes --filters Name=status,Values=available --query "Volumes[?(CreateTime<'$(date --date='-1 day' '+%Y-%m-%d')')].[VolumeId]" --output text

How do you list only accounts numbers and account names under an AWS organization using AWS CLI

Using the AWS CLI, how do I output a list of all the accounts with just Account Names and Account Numbers?
The below command outputs Account Names and Numbers along with other values, how do I filter this?
aws organizations list-accounts
The below command outputs Account names and Account numbers in a tabular format -
aws organizations list-accounts --query 'Accounts[*].[Name, Id]' --output table
Output:
----------------------------------------------------------------------
| ListAccounts |
+----------------------------------------------------+---------------+
| alphabet-finance-dev | 80XX00000001 |
| alphabet-security-prd | 80XX43500061 |
| alphanet-devops-tst | 50XX00000046 |
| ................ | ............ |
+----------------------------------------------------+---------------+
For output in text -
aws organizations list-accounts --query 'Accounts[*].[Name, Id]' --output text
For output in JSON -
aws organizations list-accounts --query 'Accounts[*].[Name, Id]' --output json
For output in YAML -
aws organizations list-accounts --query 'Accounts[*].[Name, Id]' --output yaml

aws cli ec2 describe-instances table output

I want to run an ec2 describe-instances command and get output in a table format as follows (where name is the Value of the Tag with Key 'Name'):
----------------------------------------------------------
| DescribeInstances |
+-------------+----------------+--------------+----------+
| instance_id | ip_address | name | state |
+-------------+----------------+--------------+----------+
| i-g93g494d | 99.99.99.01 | name1 | running |
| i-a93f754c | 99.99.99.02 | name2 | running |
+-------------+----------------+--------------+----------+
I can run the following command:
aws ec2 describe-instances --instance-ids i-g93g494d i-a93f754c --query "Reservations[*].Instances[*].{name: Tags[?Key=='Name'].Value, instance_id: InstanceId, ip_address: PrivateIpAddress, state: State.Name}" --output json
and obtain output:
[
[
{
"instance_id": "i-g93g494d",
"state": "running",
"ip_address": "99.99.99.01",
"name": [
"name1"
]
}
],
[
{
"instance_id": "i-a93f754c",
"state": "running",
"ip_address": "99.99.99.02",
"name": [
"name2"
]
}
]
]
However, when I run the same command with --output table rather than --output json I get an error.
command:
aws ec2 describe-instances --instance-ids i-g93g494d i-a93f754c --query "Reservations[*].Instances[*].{name: Tags[?Key=='Name'].Value, instance_id: InstanceId, ip_address: PrivateIpAddress, state: State.Name}" --output json
output:
list index out of range
I would like the table output to look like the above example but I'm having difficulty solving this. I'd very much appreciate any help anyone can offer on this.
You need to use pipe expression to filter the Tag results and get the first value such as:
aws ec2 describe-instances --instance-ids i-g93g494d i-a93f754c --query "Reservations[*].Instances[*].{name: Tags[?Key=='Name'] | [0].Value, instance_id: InstanceId, ip_address: PrivateIpAddress, state: State.Name}" --output table
There is a nice related blog post here: Get a list of instance with id, name and type
Here's a python program that can be used to generate listings from the descibe-instances command:
import json
import sys
with open( sys.argv[1] ) as f:
aws = json.load( f )
Reservations = aws['Reservations']
for Reservation in Reservations:
Instances = Reservation['Instances']
for Instance in Instances:
Tags = Instance['Tags']
for Tag in Tags:
if Tag['Key'] == "Name":
print Tag['Value'],Instance['PrivateIpAddress'],Instance['InstanceId'],Instance['State']['Name']
BTW, I absolutely LOVE Volkan Paksoy's answer. That's going into my bag o' tricks. The above python may have the advantage of allowing you to be more expressive with your search criteria or somehow combining results. In short, it's python, and you don't have to figure out how to use the aws syntax.
Here's how to invoke the python script above:
python parse.py <( aws ec2 describe-instances )
Of course, your mileage may vary. For instance, you may not have your region defaulted so, you may need to add an extra parameter as follows:
python parse.py <( aws ec2 --region us-east-2 describe-instances )
And you can than manipulate the output a bit to select only running instances and put in a well formatted column list:
python parse.py <( aws ec2 --region us-east-2 describe-instances ) | column -t | sort -k1,1 | cat -n | grep running
One last note, as I stated, I am a fan of the one liner provided by Volkan. I was just wondering how if the column ordering can be manipulated. I found that aws is sorting the columns alphabetically. To make the ordering obvious, I put numbers in front of the attribute names. However, these attribute names weren't interpreted properly as identifiers, so I had to quote them with double quotes. Here's what I wound up with, please note the subtle quoting changes ( and not so subtle quoting around 'Name' ):
aws ec2 describe-instances --query 'Reservations[*].Instances[*].{"01-name": Tags[?Key=='"'Name'"'] | [0].Value, "03-instance_id": InstanceId, "02-ip_address": PrivateIpAddress, "04-state" : State.Name}' --output table

How to Extract the Tag name from ec2 snapshot_id

With this command I am getting the snapshot id but i want to get the name associated with this id [TAGS]
aws ec2 describe-snapshots --owner-ids ********** --output text | awk /vol-6ac16d63/ | grep -y "2014-02-01" | awk "/vol-6ac16d63/{print \$5}"
try describe-tags:
aws ec2 describe-tags --filters Name=resource-id,Values=snap-XXXXXXX Name=key,Values=Name --query "Tags[*].Value" --output text

aws cli: How can I query list values?

The aws cli has a --query option, which allows you to select only some information.
For an example, I am interested in getting just the Security group name from ec2 describe-instances.
If I run:
aws ec2 describe-instances --output text --query 'Reservations[*].Instances[*].[InstanceId,InstanceType,SecurityGroups]
my output looks like:
i-xxxxxxx m1.type [{u'GroupName': 'groupName', u'GroupId': 'sg-xxxxx'}]
I can also access elements of the list using an index:
aws ec2 describe-instances --output text --query 'Reservations[*].Instances[*].[InstanceId,InstanceType,Tags[0].Value,Tags[0].Name]
Is it possible to query tags so that instead of Tag[0] I search for a Tag where the name is specified?
As of 1.3.0, you can now query that information like this:
--query 'Reservations[*].Instances[*].Tags[?Key==`<keyname>`].Value[]'
So where you have this:
"Tags" : [
{
"Value" : "webserver01",
"Key" : "InstanceName"
},
you'd want to do this:
aws ec2 describe-instances --query 'Reservations[*].Instances[*].Tags[?Key==`InstanceName`].Value[]'
What you probably want to use is the --filters option:
aws ec2 describe-instances --output text --filters "Name=tag-key, Values=SecurityGroups, Name=tag-value, Values=Foo" --region us-east-1
You can change the filters around to "query" for the exact field you're looking for.
checkout this slideshare from the Atlanta AWS meetup group's talk on the new AWS CLI for more examples
This way works for me: (this only works in version 1.3.0 and above)
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[InstanceId, Tags[?Key==`Name`].Value[*]]'
select security_groups from aws.aws_ec2_instance;
> select security_groups from aws.aws_ec2_instance limit 1;
+---------------------------------------------------------------------------------------------------------------------------------+
| security_groups |
+---------------------------------------------------------------------------------------------------------------------------------+
| [{"GroupId":"sg-xxxx","GroupName":"xxxx"},{"GroupId":"sg-xxxxxx","GroupName":"xxxx"}] |
+---------------------------------------------------------------------------------------------------------------------------------+
This will just list out the security groups for your instances.
You can also use
select security_groups from aws.aws_ec2_instance where instance_id = 'i-xxxxxx';