Interrogation des tags EC2 à partir d'une instance
Amazon a récemment ajouté la merveilleuse fonctionnalité de tagger les instances EC2 avec des paires de valeurs clés pour rendre la gestion d'un grand nombre de VMs un peu plus facile.
y a-t-il un moyen d'interroger ces balises de la même manière que certaines autres données définies par les utilisateurs? Par exemple:
$ wget -q -O - http://169.254.169.254/latest/meta-data/placement/availability-zone
us-east-1d
y a-t-il un moyen similaire pour interroger les tags?
10 réponses
vous pouvez utiliser une combinaison du outil de métadonnées AWS (pour récupérer votre ID d'instance) et le nouvelle API D'étiquette pour récupérer les étiquettes pour l'instance actuelle.
une fois que vous avez installé ec2-metadata
et ec2-describe-tags
(comme indiqué dans la réponse de Ranieri au-dessus de ), voici un exemple de commande shell pour obtenir le" nom "de l'instance courante, en supposant que vous ayez une étiquette" Name=Foo "dessus.
suppose que les variables D'environnement EC2_PRIVATE_KEY et EC2_CERT sont définies.
ec2-describe-tags \
--filter "resource-type=instance" \
--filter "resource-id=$(ec2-metadata -i | cut -d ' ' -f2)" \
--filter "key=Name" | cut -f5
retourne Foo
.
le script bash suivant renvoie le nom de votre instance ec2 actuelle (la valeur de la balise" Name"). Modifiez TAG_NAME à votre cas spécifique.
TAG_NAME="Name"
INSTANCE_ID="`wget -qO- http://instance-data/latest/meta-data/instance-id`"
REGION="`wget -qO- http://instance-data/latest/meta-data/placement/availability-zone | sed -e 's:\([0-9][0-9]*\)[a-z]*$:\1:'`"
TAG_VALUE="`aws ec2 describe-tags --filters "Name=resource-id,Values=$INSTANCE_ID" "Name=key,Values=$TAG_NAME" --region $REGION --output=text | cut -f5`"
pour installer l'aws cli
sudo apt-get install python-pip -y
sudo pip install awscli
dans le cas où vous utilisez IAM à la place des justificatifs d'identité explicites, utilisez ces autorisations IAM:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [ "ec2:DescribeTags"],
"Resource": ["*"]
}
]
}
vous pouvez ajouter ce script à votre cloud-init données de l'utilisateur pour télécharger les tags EC2 dans un fichier local:
#!/bin/sh
INSTANCE_ID=`wget -qO- http://instance-data/latest/meta-data/instance-id`
REGION=`wget -qO- http://instance-data/latest/meta-data/placement/availability-zone | sed 's/.$//'`
aws ec2 describe-tags --region $REGION --filter "Name=resource-id,Values=$INSTANCE_ID" --output=text | sed -r 's/TAGS\t(.*)\t.*\t.*\t(.*)/=""/' > /etc/ec2-tags
vous avez besoin des outils AWS CLI installés sur votre système: vous pouvez les installer avec une section packages
dans un fichier cloud-config avant le script, utiliser un AMI qui les inclut déjà, ou ajouter une commande apt
ou yum
au début du script.
pour accéder à EC2 tags Vous avez besoin d'une politique comme celle-ci dans le rôle IAM de votre instance:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1409309287000",
"Effect": "Allow",
"Action": [
"ec2:DescribeTags"
],
"Resource": [
"*"
]
}
]
}
les tags EC2 de l'instance seront disponibles en /etc/ec2-tags
dans ce format:
FOO="Bar"
Name="EC2 tags with cloud-init"
vous pouvez inclure le fichier as-is dans un script shell en utilisant . /etc/ec2-tags
, par exemple:
#!/bin/sh
. /etc/ec2-tags
echo $Name
les tags sont téléchargés lors de l'initialisation de l'instance, de sorte qu'ils ne reflètent pas les changements ultérieurs.
le script et la Politique IAM sont basés sur la réponse d'itaifrenkel.
si vous n'êtes pas dans la zone de disponibilité par défaut, les résultats de overthink retourneront vides.
ec2-describe-tags \
--region \
$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e "s/.$//") \
--filter \
resource-id=$(curl --silent http://169.254.169.254/latest/meta-data/instance-id)
Si vous souhaitez ajouter un filtre pour obtenir une balise spécifique (elasticbeanstalk:environnement-nom dans mon cas), alors vous pouvez le faire.
ec2-describe-tags \
--region \
$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e "s/.$//") \
--filter \
resource-id=$(curl --silent http://169.254.169.254/latest/meta-data/instance-id) \
--filter \
key=elasticbeanstalk:environment-name | cut -f5
et pour obtenir seulement la valeur pour l'étiquette que j'ai filtré sur, nous pipons pour couper et obtenir le cinquième champ.
ec2-describe-tags \
--region \
$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e "s/.$//") \
--filter \
resource-id=$(curl --silent http://169.254.169.254/latest/meta-data/instance-id) \
--filter \
key=elasticbeanstalk:environment-name | cut -f5
Pour Python:
from boto import utils, ec2
from os import environ
# import keys from os.env or use default (not secure)
aws_access_key_id = environ.get('AWS_ACCESS_KEY_ID', failobj='XXXXXXXXXXX')
aws_secret_access_key = environ.get('AWS_SECRET_ACCESS_KEY', failobj='XXXXXXXXXXXXXXXXXXXXX')
#load metadata , if = {} we are on localhost
# http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html
instance_metadata = utils.get_instance_metadata(timeout=0.5, num_retries=1)
region = instance_metadata['placement']['availability-zone'][:-1]
instance_id = instance_metadata['instance-id']
conn = ec2.connect_to_region(region, aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key)
# get tag status for our instance_id using filters
# http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/ApiReference-cmd-DescribeTags.html
tags = conn.get_all_tags(filters={'resource-id': instance_id, 'key': 'status'})
if tags:
instance_status = tags[0].value
else:
instance_status = None
logging.error('no status tag for '+region+' '+instance_id)
en utilisant les APIs 'user data' et 'meta data' de L'AWS, il est possible d'écrire un script qui enveloppe puppet pour lancer un puppet run avec un nom de cert personnalisé.
pour commencer une instance aws avec des données utilisateur personnalisées:' role: webserver '
#!/bin/bash
# Find the name from the user data passed in on instance creation
USER=$(curl -s "http://169.254.169.254/latest/user-data")
IFS=':' read -ra UDATA <<< "$USER"
# Find the instance ID from the meta data api
ID=$(curl -s "http://169.254.169.254/latest/meta-data/instance-id")
CERTNAME=${UDATA[1]}.$ID.aws
echo "Running Puppet for certname: " $CERTNAME
puppet agent -t --certname=$CERTNAME
ça s'appelle marionnette avec un nom d'emprunt comme ' webserver.i-hfg453.aws ' vous pouvez alors créer un manifeste de noeud appelé 'webserver' et puppets 'fuzzy node matching' signifiera qu'il est utilisé pour fournir tous les serveurs web.
cet exemple suppose que vous construisez sur une image de base avec une marionnette installée, etc.
prestations:
1) vous n'avez pas à passer vos lettres de créance
2) Vous pouvez être aussi granulaire que vous le souhaitez avec le rôle configs.
installer AWS CLI:
curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
sudo apt-get install unzip
unzip awscli-bundle.zip
sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
Obtenir les balises de l'instance en cours:
aws ec2 describe-tags --filters "Name=resource-id,Values=`ec2metadata --instance-id`"
sorties:
{
"Tags": [
{
"ResourceType": "instance",
"ResourceId": "i-6a7e559d",
"Value": "Webserver",
"Key": "Name"
}
]
}
utilisez un peu de perl pour extraire les étiquettes:
aws ec2 describe-tags --filters \
"Name=resource-id,Values=`ec2metadata --instance-id`" | \
perl -ne 'print "\n" if /\"Value\": \"(.*?)\"/'
Retourne:
Webserver
Téléchargez et exécutez un exécutable autonome pour le faire.
parfois, on ne peut pas installer awscli qui dépend de python. docker est peut-être absent.
Voici mon implémentation à golang: https://github.com/hmalphettes/go-ec2-describe-tags
vous pouvez alternativement utiliser le describe-instances
cli call plutôt que describe-tags
:
Cet exemple montre comment obtenir la valeur de 'mon-tag-name' pour l'exemple:
aws ec2 describe-instances --instance-id $(curl -s http://169.254.169.254/latest/meta-data/instance-id) --region ap-southeast-2 --query "Reservations[*].Instances[*].Tags[?Key=='my-tag-name'].Value" --output text
changez la région en fonction de votre situation locale. Cela peut être utile lorsque votre instance a le privilège describe-instances mais pas describe-tags dans la Politique de profil d'instance