2010-10-07 15 views
73

Amazon agregó recientemente la maravillosa función de etiquetar instancias EC2 con pares clave-valor para facilitar un poco la administración de un gran número de máquinas virtuales.Consultar etiquetas EC2 desde la instancia

¿Hay alguna forma de consultar estas etiquetas de la misma manera que algunos de los otros datos configurados por el usuario? Por ejemplo:

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

¿Hay alguna manera similar de consultar las etiquetas?

Respuesta

32

Puede usar una combinación de AWS metadata tool (para recuperar su ID de instancia) y new Tag API para recuperar las etiquetas de la instancia actual.

+0

OK, he seguido ese enlace, y parece que es la documentación de la API. ¿No hay ninguna herramienta que pueda usar o necesito leer la documentación de la API y escribir mi propia herramienta? –

+3

¿Está fácilmente disponible el comando ec2-describe-tags? Supuestamente está en el paquete ec2-api-tools, pero no obtuve nada más que el 404 cuando intenté instalarlo. –

+1

dar un ejemplo, obtener el valor del rol de etiqueta: aws ec2 describe-tags --filters Name = resource-id, Values ​​= 'ec2metadata --instance-id' --out = json | jq '.Tags [] | select (.Key == "role") | .Value ' – jolestar

40

Una vez que tenga ec2-metadata y ec2-describe-tags instalada (como se menciona en Ranieri's answer above), aquí es un ejemplo del comando shell para obtener el "nombre" de la instancia actual, suponiendo que tiene una etiqueta "Name = Foo" en él.

Asume que las variables de entorno EC2_PRIVATE_KEY y EC2_CERT están establecidas.

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

Esto devuelve Foo.

+13

Habría sido bueno si mis procesos pudieran obtener las etiquetas para la instancia actual sin tener que tener EC2_PRIVATE_KEY en la instancia también. :-( –

+1

@ william-payne Sí, eso es realmente cojo. Quizás usando el IAM de Amazon al menos podrías usar un usuario con acceso muy limitado a todo. FWIW, ya no uso este enfoque y solo uso scripts externos para configure el cuadro. – overthink

+11

@WilliamPayne Puede configurar un rol de IAM con la política "Acceso de solo lectura de Amazon EC2" y crear la instancia que tenga dicho rol. También es posible crear una política personalizada que tenga solo el privilegio "Describir etiquetas" si quiero ser más granular. – roverwolf

3

Usando las API de datos de usuario y metadatos de AWS es posible escribir un script que envuelva a la marioneta para iniciar una ejecución de marionetas con un nombre de certificado personalizado.

En primer lugar se inicia una instancia AWS con los datos de usuario personalizada: 'papel: servidor web'

#!/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 

Para esto se necesitan con un títere certname como 'webserver.i-hfg453.aws' a continuación, puede crear un nodo de manifiesto llamada "matching de nodo difuso" de "webserver" y títeres "significará que se utiliza para aprovisionar todos los servidores web.

Este ejemplo asume que construye una imagen base con títere instalado etc.

Beneficios:

1) Usted no tiene que pasar alrededor de sus credenciales

2) Puede ser tan granular como quieras con las configuraciones de roles.

5

Si no se encuentra en la zona de disponibilidad predeterminada, los resultados de overthink volverán vacíos.

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 desea agregar un filtro para obtener una etiqueta específica (elasticbeanstalk: entorno de nombre en mi caso), entonces usted puede hacer esto.

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 

y para obtener sólo el valor de la etiqueta que se filtra sobre, que tubo a cortar y obtener el 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 
35

El siguiente script bash devuelve el nombre de su instancia actual de ec2 (el valor de la etiqueta "Nombre"). Modifica TAG_NAME en tu caso específico.

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`" 

para instalar el AWS cli

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

En caso de usar IAM en lugar de credenciales explícitas, utiliza estos permisos IAM:

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

Me estaba dando" No tienes autorización para realizar esta operación "con' aws ec2 describe-tags'. Necesitaba agregar este IAM a las políticas en línea de mi función de IAM. ¡Gracias! –

5

Para 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) 
+0

Legit. Nota de los lectores para información local básica que ni siquiera necesita credenciales, solo el 'instance_metadata = utils.get_instance_metadata (timeout = 0.5, num_retries = 1) ' – Bartvds

+0

Además, esto funciona muy bien con los roles de IAM: si establece un rol de instancia, boto detectará automáticamente el ID y la clave. – dbn

10

Puede agregar este script a su datos de usuario init-nube para descargar las etiquetas de EC2 en un archivo 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(.*)/\1="\2"/' > /etc/ec2-tags 

Usted necesita las herramientas AWS CLI instalados en el sistema: puede instalarlos con una sección packages en un archivo de nube-config antes el script, use un AMI que ya los incluya, o agregue un comando apt o yum al comienzo del script.

Con el fin de acceder a las variables de EC2 que necesita una política como ésta en función de IAM de la instancia:

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

etiquetas EC2 de la instancia disponible en /etc/ec2-tags en este formato:

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

Usted puede incluir el archivo como está en un script de shell usando . /etc/ec2-tags, por ejemplo:

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

Las etiquetas se descargan durante la inicialización de la instancia, por lo que no reflejarán los cambios posteriores.


La secuencia de comandos y la política de IAM se basan en la respuesta de itaifrenkel.

+0

a + prefiero este método – Cmag

+0

, es una lástima que se rompa para las etiquetas creadas por grupos de autoescalado:' aws: autoscaling: groupName' – Cmag

+2

Luego intente esto: 'aws ec2 describe-etiquetas --region $ REGION --filter" Nombre = id-recurso, Valores = $ INSTANCE_ID "--output = texto | sed -r 's/TAGS \ t (. *) \ t. * \ t. * \ t (. *)/EC2_TAG_ \ 1 = "\ 2"/'| sed -r' s/aws: autoscaling:/aws_autoscaling_/'>/etc/ec2-tags' –

0

Instalar 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 

Recibe las etiquetas para la instancia actual:

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

Salidas:

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

usar un poco de Perl para extraer las etiquetas:

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

Devuelve:

Webserver 
+0

'ec2metadata' no está en aws-cli, pero se puede reemplazar por' curl --silent http:// 169.254.169.254/latest/meta-data/instance-id'. también, 'jq' puede analizar el json más fácilmente, o un formato de salida diferente es aún más fácil. – tedder42

Cuestiones relacionadas