J'essaie d'utiliser les outils de ligne de commande Amazon AWS pour rechercher toutes les instances pour lesquelles aucune balise n'est spécifiée.
La recherche de toutes les instances AVEC une balise est assez simple, par exemple.
ec2-describe-instances --filter "tag-key=Name"
Mais comment pourrais-je inverser ce filtre pour ne renvoyer que les instances qui n'ont pas de balise "Nom"?
Cela fera ce que vous demandez - trouvez toutes les instances qui ne contiennent pas de balise nommée "YOUR_KEY_NAME_HERE" (les filtres de la deuxième ligne pour les occurrences sans balise nommée "Nom"):
aws ec2 describe-instances | jq '.Reservations[].Instances[] | select(contains({Tags: [{Key: "YOUR_KEY_NAME_HERE"} ]}) | not)'
aws ec2 describe-instances | jq '.Reservations[].Instances[] | select(contains({Tags: [{Key: "Name"} ]}) | not)'
Si vous souhaitez filtrer la valeur de la balise au lieu du nom de la balise, cette requête répertorie toutes les instances ne contenant pas de balise nommée YOUR_KEY_NAME_HERE dont la valeur est EXCLUDE_ME. (La deuxième ligne répertorie les instances qui ne sont pas nommées "testbox1".)
aws ec2 describe-instances | jq '.Reservations[].Instances[] | select(contains({Tags: [{Key: "YOUR_KEY_NAME_HERE"}, {Value: "EXCLUDE_ME"}]}) | not)'
aws ec2 describe-instances | jq '.Reservations[].Instances[] | select(contains({Tags: [{Key: "Name"}, {Value: "testbox1"}]}) | not)'
Felipe a raison. L'analyse de la sortie est la seule solution, car l'API AWS ne fournit pas cette fonctionnalité, pas plus que les interfaces de ligne de commande AWS officielles. La sortie JSON est très analysable, en particulier si elle est comparée aux enregistrements de texte multilignes que l'ancienne CLI imprime par défaut.
http://docs.aws.Amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html
L'API elle-même renvoie JSON et le nouvel awscli imprime ce JSON en tant que format de sortie par défaut. Le programme "jq" est très utile pour l’analyser. Il peut même se colorier lorsqu’il est envoyé à un terminal. Vous pouvez également le texte en sortie pour le réduire en chaînes.
Vous pouvez le faire avec jmespath (le moteur qui gère le paramètre --query
) malgré ce que d'autres disent:
aws ec2 describe-instances \
--query 'Reservations[].Instances[?!not_null(Tags[?Key == `Name`].Value)] | []'
Étant donné que le paramètre --filters
ne semble pas prendre en charge le filtrage inverse, voici la solution à ce problème avec le paramètre --query
:
aws ec2 describe-instances \
--query 'Reservations[].Instances[?!contains(Tags[].Key, `Name`)][].InstanceId'
Il examine un tableau de clés de balises pour chaque instance et filtre celles qui ne possèdent pas de balise 'Nom' dans le tableau. Ensuite, aplatit la sortie en un tableau d'identifiants d'instance.
jq
ou d'une autre commande pour filtrer la sortie.Malheureusement, l'appel d'api sous-jacent DescribeSnapshots ne prend pas en charge le filtrage de balise inverse, de même que la CLI. Vous pouvez toutefois effectuer un filtrage côté client avec le paramètre --query
qui effectue un JMESPath search. Cela vous évitera d'avoir à utiliser des pipes comme avec la réponse de user2616321.
Par exemple:
aws ec2 describe-instances --query "Reservations[].Instances[?Tags[?Key == 'Name']][]"
Ajoutez .InstanceId
à la fin pour obtenir uniquement les identifiants d'instance.
J'avais le même problème et j'ai compris comment interroger Tag -Values. J'ai défini une clé de balise "MachineName" sur toutes mes instances et je souhaite filtrer par les valeurs du nom de clé de balise
Vous trouverez ci-dessous un exemple de filtrage où Name = Machine1
utiliser l'option
--filters "Name=tag-key,Values=MachineName" "Name=tag-values,Values=Machine1"
Cela fonctionne bien pour moi
Autant que je sache, directement à travers la CLI, vous ne pourrez pas le faire.
Par la syntaxe que vous utilisez, je suppose que vous utilisez l’ancienne CLI. Je vous suggère de télécharger le nouveau CLI http://aws.Amazon.com/cli/ et d'appeler
aws ec2 describe-instances --output json
à partir de python, Ruby ou de n’importe quel langage de script, vous pouvez analyser le filtre de sortie JSON en utilisant l’expression régulière appropriée en fonction de vos besoins
Moi aussi, j'ai été totalement choqué par la difficulté de le faire via la CLI. J'ai aimé la réponse de user2616321, mais je rencontrais un peu de difficulté à le faire afficher les champs exacts que je voulais par instance. Après avoir passé un certain temps à déconner et à échouer avec JMESPath dans la syntaxe de requête, j'ai fini par créer un petit script Ruby pour le faire. Au cas où quelqu'un voudrait gagner quelques minutes en écrivant l'un des leurs, le voici:
#!/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)