I\'m trying to use the Amazon AWS Command Line Tools to find all instances that do not have a specified tag.
Finding all instances WITH a tag is simple enough, e.g.<
I too was totally shocked by how difficult this is to do via the CLI. I liked user2616321's answer, but I was having a little trouble making it output the exact fields I wanted per instance. After spending a while messing around and failing with JMESPath in the query syntax, I ended up just making a little ruby script to do this. In case anyone wants to save a few minutes writing one of their own, here it is:
#!/usr/bin/env ruby
require 'json'
# We'll output any instance that doesn't contain all of these tags
desired_tags = if ARGV.empty?
%w(Name)
else
ARGV
end
# Put the keys we want to output per instance/reservation here
reservation_keys = %w(OwnerId RequesterId)
instance_keys = %w(Tags InstanceId InstanceType PublicDnsName LaunchTime PrivateIpAddress KeyName)
instances_without_tags = []
# Just use CLI here to avoid AWS dependencies
reservations = JSON.parse(
`aws ec2 describe-instances`
)["Reservations"]
# A reservation is a single call to spin up instances. You could potentially
# have more than one instance in a reservation, but often only one is
# spun up at a time, meaning there is a single instance per reservation.
reservations.each do |reservation|
reservation["Instances"].each do |instance|
# Filter instances without the desired tags
tag_keys = instance["Tags"].map { |t| t["Key"] }
unless (tag_keys & desired_tags).length == desired_tags.length
instances_without_tags <<
reservation.select { |k| reservation_keys.include?(k) }.
merge(instance.select { |k| instance_keys.include?(k) })
end
end
end
puts JSON.pretty_generate(instances_without_tags)
I was having the same problem and I figured out how to query on Tag-Values you will most likely have the same tag-key defined for all the instances; I have defined a tag-key "MachineName" on all my instances and I want to filter by the the values of the Tag-key Name
Below is the example to filter where the Name=Machine1
use the option
--filters "Name=tag-key,Values=MachineName" "Name=tag-values,Values=Machine1"
This works fine for me
Since --filters
parameter doesn't seem to support inverse filtering, here's my solution to this problem using --query
parameter:
aws ec2 describe-instances \
--query 'Reservations[].Instances[?!contains(Tags[].Key, `Name`)][].InstanceId'
It looks at an array of tag keys for each instance and filters those instance that don't have Tag 'Name' in the array. Then flattens output to array of instance IDs.
jq
or other command to filter output.