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