Interrogare i tag EC2 dall’interno dell’istanza

Amazon ha recentemente aggiunto la meravigliosa funzione di codificare le istanze EC2 con coppie chiave-valore per semplificare la gestione di un gran numero di macchine virtuali.

C’è un modo per interrogare questi tag allo stesso modo di alcuni altri dati impostati dall’utente? Per esempio:

$ wget -q -O - http://169.254.169.254/latest/meta-data/placement/availability-zone us-east-1d 

C’è un modo simile per interrogare i tag?

È ansible utilizzare una combinazione dello strumento di metadati AWS (per recuperare l’ID istanza) e la nuova API tag per recuperare i tag per l’istanza corrente.

Una volta che hai ec2-metadata ed ec2-describe-tags (come menzionato nella risposta di Ranieri sopra ), ecco un esempio di comando shell per ottenere il “nome” dell’istanza corrente, assumendo che tu abbia un tag “Name = Foo” su di essa.

Presuppone che le variabili di ambiente EC2_PRIVATE_KEY e EC2_CERT siano impostate.

 ec2-describe-tags \ --filter "resource-type=instance" \ --filter "resource-id=$(ec2-metadata -i | cut -d ' ' -f2)" \ --filter "key=Name" | cut -f5 

Questo restituisce Foo .

Il seguente script di bash restituisce il nome dell’istanza corrente di ec2 (il valore del tag “Name”). Modifica TAG_NAME nel tuo caso specifico.

 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]*\)[az]*\$:\\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`" 

Per installare il cli aws

 sudo apt-get install python-pip -y sudo pip install awscli 

Se utilizzi IAM invece di credenziali esplicite, utilizza queste autorizzazioni IAM:

 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:DescribeTags"], "Resource": ["*"] } ] } 

È ansible aggiungere questo script ai dati utente di cloud-init per scaricare i tag EC2 in un file locale:

 #!/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(.*)/\1="\2"/' > /etc/ec2-tags 

Sono necessari gli strumenti CLS di AWS installati sul sistema: è ansible installarli con una sezione di packages in un file di configurazione cloud prima dello script, utilizzare un AMI che li include già o aggiungere un comando apt o yum all’inizio del script.

Per accedere ai tag EC2 è necessario un criterio come questo nel ruolo IAM della tua istanza:

 { "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1409309287000", "Effect": "Allow", "Action": [ "ec2:DescribeTags" ], "Resource": [ "*" ] } ] } 

I tag EC2 dell’istanza saranno disponibili in /etc/ec2-tags in questo formato:

 FOO="Bar" Name="EC2 tags with cloud-init" 

Puoi includere il file così com’è in uno script di shell usando . /etc/ec2-tags . /etc/ec2-tags , ad esempio:

 #!/bin/sh . /etc/ec2-tags echo $Name 

I tag vengono scaricati durante l’inizializzazione dell’istanza, quindi non rifletteranno le modifiche successive.


La politica di script e IAM si basa sulla risposta di itaifrenkel.

Se non ci si trova nella zona di disponibilità predefinita, i risultati dell’overthink verrebbero restituiti vuoti.

 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) 

Se si desidera aggiungere un filtro per ottenere un tag specifico (elasticbeanstalk: nome-ambiente nel mio caso), è ansible farlo.

 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 

E per ottenere solo il valore per il tag che ho filtrato, eseguiamo il pipe per tagliare e ottenere il quinto campo.

 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 

Per 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) 

Utilizzando le API ‘user data’ e ‘meta data’ di AWS è ansible scrivere uno script che avvolge puppet per avviare una marionetta con un nome di certificato personalizzato.

Per prima cosa avviare un’istanza aws con dati utente personalizzati: ‘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 

Questo chiama puppet con un nome cert come "webserver.i-hfg453.aws", quindi puoi creare un manifest nodo chiamato "webserver" e il "nodo fuzzy matching" dei pupazzi significherà che è usato per fornire tutti i server web.

Questo esempio presuppone che tu costruisca su un'immagine base con puppet installato ecc.

Benefici:

1) Non devi passare le tue credenziali

2) Puoi essere molto dettagliato con le configurazioni dei ruoli.

Installa CLI AWS:

 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 

Ottieni i tag per l’istanza corrente:

 aws ec2 describe-tags --filters "Name=resource-id,Values=`ec2metadata --instance-id`" 

Uscite:

 { "Tags": [ { "ResourceType": "instance", "ResourceId": "i-6a7e559d", "Value": "Webserver", "Key": "Name" } ] } 

Usa un po ‘di perl per estrarre i tag:

 aws ec2 describe-tags --filters \ "Name=resource-id,Values=`ec2metadata --instance-id`" | \ perl -ne 'print "$1\n" if /\"Value\": \"(.*?)\"/' 

Ritorna:

 Webserver 

Scarica ed esegui un eseguibile standalone per farlo.

A volte non è ansible installare awscli che dipende da python. la finestra mobile potrebbe anche essere fuori dall’immagine.

Ecco la mia implementazione in golang: https://github.com/hmalphettes/go-ec2-describe-tags

In alternativa, puoi usare la chiamata cli describe-instances piuttosto che describe-tags :

Questo esempio mostra come ottenere il valore di ‘my-tag-name’ per l’istanza:

 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 

Cambia la regione in base alle tue circostanze locali. Ciò può essere utile laddove l’istanza ha il privilegio delle istanze descrittore ma non i tag descrittivi nella politica del profilo di istanza