sort output of describe-instances?
The answer is to add | sort_by(@, &@[0][3])
aws ec2 describe-instances \
--filters "Name=tag:Group,Values=production" "Name=instance-state-name,Values=running" "Name=tag:Name,Values=prod-*-${CURRENT_SHA}-*" \
--query 'Reservations[*].Instances[*].[LaunchTime,InstanceId,PrivateIpAddress,Tags[?Key==`Name`] | [0].Value]| sort_by(@, &@[0][3])' \
--output table
As an enhancement to @ColinK's answer, I wanted to sort a table that had custom column headers but struggled with the syntax. I eventually got it to work so I thought I'd share in case someone else wanted to do the same. I added a column for State and sorted by that column.
--query 'sort_by(Reservations[*].Instances[*].{LaunchTime:LaunchTime, ID:InstanceId,IP:PrivateIpAddress,State:State.Name,Name:Tags[?Key==`Name`] | [0].Value}[], &State)'
short answer
add
[] | sort_by(@, &[3])
at the end of your expression. The brackets ([]
) will flatten the structure, sort_by(...)
will sort the result (which is a four-column table) by the fourth column. The full query will be:
--query 'Reservations[*].Instances[*].[LaunchTime,InstanceId,PrivateIpAddress,Tags[?Key==`Name`] | [0].Value][] | sort_by(@, &[3])'
long answer
inspecting your current query result
According to the describe-instances
docs, the structure of the describe-instances
output looks like this:
{
"Reservations": [
{
"Instances": [
{
"LaunchTime": "..LaunchTime..",
"InstanceId": "R1I1",
"PrivateIpAddress": "..PrivateIpAddress..",
"Tags": [{"Key": "Name", "Value": "foo"}]
},
{
"LaunchTime": "..LaunchTime..",
"InstanceId": "R1I2",
"PrivateIpAddress": "..PrivateIpAddress..",
"Tags": [{"Key": "Name", "Value": "baz"}]
}
]
},
{
"Instances": [
{
"LaunchTime": "..LaunchTime..",
"InstanceId": "R2I1",
"PrivateIpAddress": "..PrivateIpAddress..",
"Tags": [{"Key": "Name", "Value": "bar"}]
}
]
}
]
}
Using your original query
--query 'Reservations[*].Instances[*].[LaunchTime,InstanceId,PrivateIpAddress,Tags[?Key==`Name`] | [0].Value]'
will output
[
[
[
"..LaunchTime..",
"R1I1",
"..PrivateIpAddress..",
"foo"
],
[
"..LaunchTime..",
"R1I2",
"..PrivateIpAddress..",
"baz"
]
],
[
[
"..LaunchTime..",
"R2I1",
"..PrivateIpAddress..",
"bar"
]
]
]
flattening the query result
You can see in the above result of your query that you're getting a list of tables ([[{},{}],[{}]]
). I suppose you instead want a single non-nested table ([{},{},{}]
). To achieve that, simply add []
at the end of your query, i.e.
--query 'Reservations[*].Instances[*].[LaunchTime,InstanceId,PrivateIpAddress,Tags[?Key==`Name`] | [0].Value][]'
This will flatten the structure, resulting in
[
[
"..LaunchTime..",
"R1I1",
"..PrivateIpAddress..",
"foo"
],
[
"..LaunchTime..",
"R1I2",
"..PrivateIpAddress..",
"baz"
],
[
"..LaunchTime..",
"R2I1",
"..PrivateIpAddress..",
"bar"
]
]
Now it's time to sort the table.
sorting the table
When using sort_by
you shouldn't forget to prepend the expression by &
(ampersand). This way you specify a reference to that expression, which is then passed to sort_by
.
example: data | sort_by(@, &@)
is equivalent to data | sort(@)
.
The TagName
in the table you create ([LaunchTime,InstanceId,PrivateIpAddress,TagName]
) is the fourth column. You can get that column by piping the table to the expression [3]
:
TableExpression | [3]
But instead, you want to sort the table by the fourth column. You can do so like this:
TableExpression | sort_by(@, &[3])
and the resulting query will be:
--query 'Reservations[*].Instances[*].[LaunchTime,InstanceId,PrivateIpAddress,Tags[?Key==`Name`][] | [0].Value] | sort_by(@, &[3])'
Query result:
[
[
"..LaunchTime..",
"R2I1",
"..PrivateIpAddress..",
"bar"
],
[
"..LaunchTime..",
"R1I2",
"..PrivateIpAddress..",
"baz"
],
[
"..LaunchTime..",
"R1I1",
"..PrivateIpAddress..",
"foo"
]
]
Here is an other example that works also:
aws ec2 describe-instances --query 'Reservations[*].Instances[*].{Name:Tags[?Key==`Name`]|[0].Value,Instance:InstanceId} | sort_by(@, &[0].Name)'