Reputation: 63
In the new AWS console I can do inverse search, i.e.: search that does not match a certain value, with a filter.
I am trying to achieve the same using the AWS cli v2. It's straight forward to filter by tag but how do I exclude a tag at the same time?
aws ec2 describe-instances \
--query 'Reservations[].Instances[].[InstanceId]' \
--filter "Name=tag:MYTAG,Values=MYVALUE" \
--output text
I'm trying to get a list of instances with a certain tag but at the same time exclude some of those instances based on another tag.
For example: Lets say I have instances with the following tags:
tag: env | value: dev
tag: eks | value: true
I want to build a list of instances with the key-value pair of env
/dev
but want to exclude them if they also have the key-value pair of eks
/true
.
I can see JMESPath has a boolean for contains
but I'm struggling to get anywhere with it.
Upvotes: 6
Views: 3224
Reputation: 39079
Using contains
will not really lead you anywhere, because, the mere fact that the Tags
array contains "Key": "eks"
, won't tell you much without the associated value.
And if you go on dissociating the Key
and Value
, it will be a nightmare to find back which is what.
Here is an oversimplified example to actually do the tag filtering — in an inclusive way:
Reservations[]
.Instances[?
Tags[?Key == `env` && Value == `dev`]
].[InstanceId]
With this, we are stating that we want all instances having a tag object that would have both its Key
equal to env
and its Value
equal to dev
.
Now, we can add an and expression and further filter it
Reservations[]
.Instances[?
Tags[?Key == `env` && Value == `dev`]
&& Tags[?Key == `eks` && Value == `false`]
].[InstanceId]
Now, we also account for the object having the tag eks
with a value of false
.
You will still miss some case with this, though, because you also have to account for instances that are totally missing the eks
tag. And this one is a bit trickier:
Reservations[]
.Instances[?
Tags[?Key == `env` && Value == `dev`]
&& (
!not_null(Tags[?Key == `eks`])
|| Tags[?Key == `eks` && Value == `false`]
)
].[InstanceId]
Ends up being the final expression you need. We added here an or expression that allows our previous query to also filter instances that do not have an eks
tag, with a double negation (we do not want any object that have a non-empty array of eks
tags, so we want all the one that do have an empty eks
array).
So, your command line ends up being:
aws ec2 describe-instances \
--query 'Reservations[]
.Instances[?
Tags[?Key == `env` && Value == `dev`]
&& (
!not_null(Tags[?Key == `eks`])
|| Tags[?Key == `eks` && Value == `false`]
)
].[InstanceId]' \
--output text
Side note: A further simplification of the above query could be
Reservations[]
.Instances[?
Tags[?Key == `env` && Value == `dev`]
&& (
!not_null(Tags[?Key == `eks`])
|| Tags[?Key == `eks` && !Value]
)
].[InstanceId]
As the Value
field should be a boolean already, we can just negate it with a not expression.
Upvotes: 7