As a follow-up to my previous question, I am having trouble getting tags to work right in this type of output. I want to print a table with each property as a row. This is how I expect it to look:
% aws --output table ec2 describe-instances --instance-id $id --query "Reservations[].Instances[0].[{ Property: 'Type', Value: InstanceType }]"
-------------------------------
| DescribeInstances |
+-----------+-----------------+
| Property | Value |
+-----------+-----------------+
| Type | g4dn.12xlarge |
+-----------+-----------------+
But with tag names it looks like this:
% aws --output table ec2 describe-instances --instance-id $id --query "Reservations[].Instances[0].[{ Property: 'Name', Value: Tags[?Key =='Name'].Value }]"
-------------------
|DescribeInstances|
+-----------------+
| Property |
+-----------------+
| Name |
+-----------------+
|| Value ||
|+---------------+|
|| Elliott-TKD ||
|+---------------+|
The tag value is correct, but the formatting is weird, and when combined with more other rows the table gets really ugly.
The filter part of your query ([?Key == 'Name']
) is creating what JMESPath is describing as a projection.
You will have to reset this projection in order to extract a single string out of it.
Resetting a projection can be achieved using pipes.
Projections are an important concept in JMESPath. However, there are times when projection semantics are not what you want. A common scenario is when you want to operate of the result of a projection rather than projecting an expression onto each element in the array. For example, the expression
people[*].first
will give you an array containing the first names of everyone in the people array. What if you wanted the first element in that list? If you triedpeople[*].first[0]
that you just evaluatefirst[0]
for each element in the people array, and because indexing is not defined for strings, the final result would be an empty array,[]
. To accomplish the desired result, you can use a pipe expression,<expression> | <expression>
, to indicate that a projection must stop.
Source: https://jmespath.org/tutorial.html#pipe-expressions
So your issue is very close to what they are describing here in the documentation and the reset of that projection can be achieved using:
Tags[?Key =='Name']|[0].Value
or, with:
Tags[?Key =='Name'].Value | [0]
which are two strictly identical queries.
Given the JSON:
{
"Reservations": [
{
"Instances": [
{
"Tags": [
{
"Key": "Name",
"Value": "Elliott-TKD"
},
{
"Key": "Foo",
"Value": "Bar"
}
]
}
]
}
]
}
The query
Reservations[].Instances[0].[{ Property: `Name`, Value: Tags[?Key == `Name`]|[0].Value }]
Will give the expected
[
[
{
"Property": "Name",
"Value": "Elliott-TKD"
}
]
]
So it will render properly in your table
------------------------------
| DescribeInstance |
+------------+---------------+
| Property | Value |
+------------+---------------+
| Name | Elliott-TKD |
+------------+---------------+