Запросити теги EC2 зсередини примірника


96

Нещодавно Amazon додав чудову особливість тегування екземплярів EC2 парами «ключ-значення», щоб трохи полегшити управління великою кількістю віртуальних машин.

Чи є спосіб запитати ці теги так само, як і деякі інші дані набору користувачів? Наприклад:

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

Чи існує якийсь подібний спосіб запитувати теги?

Відповіді:


35

Ви можете використовувати комбінацію інструмента метаданих AWS (для отримання ідентифікатора свого примірника) та нового API тегів для отримання тегів для поточного екземпляра.


Гаразд, я перейшов за цим посиланням, і, схоже, це документація API. Чи не існує інструменту, який я можу використовувати, чи мені потрібно прочитати документацію API і написати власний інструмент?
Едвард Фолк

3
Чи легко доступна команда ec2-description-tags? Нібито він знаходиться в пакеті ec2-api-tools, але в мене нічого не було, окрім 404-х, коли я намагався його встановити.
Едвард Фолк

2
наведіть приклад, отримайте значення ролі тегу: aws ec2 description-tags --filters Name = resource-id, Values ​​= ec2metadata --instance-id--out = json | jq '.Tags [] | select (.Key == "role") | .Value '
jolestar

11
Це вказівник на відповідь, але не сама по собі відповідь
Roy Truelove

3
ec2metadataІнструмент є застарілим. Тепер ви запитуєте "магічну" URL-адресу за адресою 169.254.169.254/latest/meta-data - натисніть її за допомогою cURL, і вона дасть вам магічні кінцеві точки, які ви можете використовувати для отримання різних бітів даних. У цьому випадку ви curl http://169.254.169.254/latest/meta-data/instance-idотримуєте ваш ідентифікатор вашого екземпляра
Асфанд Казі

52

Наступний скрипт bash повертає Ім'я вашого поточного екземпляра ec2 (значення тегу "Ім'я"). Змініть TAG_NAME до вашого конкретного випадку.

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

Щоб встановити Aws cli

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

Якщо ви використовуєте IAM замість явних облікових даних, використовуйте ці дозволи IAM:

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

Я отримував "Ви не маєте права виконувати цю операцію" aws ec2 describe-tags. Мені потрібно було додати цей IAM до вбудованої політики моєї ролі IAM. Дякую!
Віктор Д.

Дуже невелика оптимізація МІГ бути , щоб замінити | cut -f5з --query="Tags[0].Value".
Річард А Квадлінг

47

Після того, як ви отримали ec2-metadataта ec2-describe-tagsвстановили (як згадується у відповіді Раньєрі вище ), ось приклад команди оболонки, щоб отримати "ім'я" поточного екземпляра, якщо припустити, що на ньому є тег "Ім'я = Foo".

Передбачає, що встановлені змінні середовища EC2_PRIVATE_KEY та EC2_CERT.

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

Це повертається Foo.


17
Було б добре, якби мої процеси могли отримати теги для поточного екземпляра без необхідності мати EC2_PRIVATE_KEY і на екземплярі. :-(
Вільям Пейн

1
@ william-payne Так, це справді кульгаво. Можливо, використовуючи IAM Amazon, ви могли принаймні використовувати користувача з дуже обмеженим доступом до чого-небудь. FWIW, я більше не використовую цей підхід і просто використовую зовнішні сценарії для установки вікна.
передумати

12
@WilliamPayne Ви можете налаштувати роль IAM за допомогою політики "Amazon EC2 Access Only Read" та створити екземпляр, що виконує цю роль. Можна також створити власну політику, яка має лише привілей "DescribeTags", якщо ви хочете бути більш детальним.
roverwolf

@WilliamPayne Мені сподобалася пропозиція roverwolf. Це працювало чудово. Насправді я відповів на ще одне запитання з деталями, якщо ви хочете його побачити: stackoverflow.com/questions/9950586/…
Тоні

2
Зауважте, що ec2-describe-tagsза замовчуванням до us-east-2. Будь ласка, передайте --regionпрапор, щоб використовувати інший регіон.
авансування

15

Ви можете додати цей сценарій до своїх хмарних даних користувача для завантаження тегів EC2 у локальний файл:

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

Вам потрібні інструменти AWS CLI, встановлені у вашій системі: ви можете встановити їх з packagesрозділом у файлі хмарного конфігурації перед сценарієм, використовувати AMI, який вже включає їх, або додати команду aptабо yumкоманду на початку сценарію.

Для доступу до тегів EC2 вам потрібна політика, подібна цій, у ролі IAM вашого екземпляра:

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

Теги EC2 примірника доступні /etc/ec2-tagsу такому форматі:

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

Ви можете включити файл як є у сценарій оболонки, використовуючи . /etc/ec2-tags, наприклад:

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

Теги завантажуються під час ініціалізації екземпляра, тому вони не відображатимуть подальші зміни.


Сценарій та політика IAM засновані на відповіді itaifrenkel.


a + віддайте перевагу цьому методу
Cmag

дуже погано, це ламається для тегів, створених групами автомасштабування:aws:autoscaling:groupName
Cmag

2
Потім спробуйте це:aws ec2 describe-tags --region $REGION --filter "Name=resource-id,Values=$INSTANCE_ID" --output=text | sed -r 's/TAGS\t(.*)\t.*\t.*\t(.*)/EC2_TAG_\1="\2"/' |sed -r 's/aws:autoscaling:/aws_autoscaling_/' > /etc/ec2-tags
Райан Гулер

10

Якщо ви не знаходитесь у зоні доступності за замовчуванням, результати переосмислення повернуться порожніми.

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)

Якщо ви хочете додати фільтр, щоб отримати певний тег (elasticbeanstalk: середовище-ім'я в моєму випадку), ви можете це зробити.

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

І щоб отримати лише значення для тегу, який я відфільтрував, ми трубимо вирізати і отримаємо п’яте поле.

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

чудова робота, дякую, наявність різних примірників даних dns для мене не працює, останнє, якщо вам потрібно замінити тег Name elasticbeanstalk:environment-nameнаName
detzu

5

Для 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)

Легіт. Читачі зазначають, що для базової місцевої інформації вам навіть не потрібні облікові дані, простоinstance_metadata = utils.get_instance_metadata(timeout=0.5, num_retries=1)
Bartvds

Крім того, це чудово грає з ролями IAM - якщо ви встановите роль екземпляра, boto автоматично виявить ідентифікатор та ключ.
dbn

5

Ви також можете скористатися describe-instancesклипом, а не describe-tags:

Цей приклад показує, як отримати значення тегу 'my-tag-name' для примірника:

aws ec2 describe-instances \
  --instance-id $(curl -s http://169.254.169.254/latest/meta-data/instance-id) \
  --query "Reservations[*].Instances[*].Tags[?Key=='my-tag-name'].Value" \
  --region ap-southeast-2 --output text

Змініть регіон відповідно до місцевих обставин. Це може бути корисно, коли ваш екземпляр має привілеї descri-instances, але не теги description у політиці профілю екземпляра


3

Використовуючи API AWS 'data data' та 'meta data', можна написати сценарій, який обертає маріонетку, щоб запустити маріонетковий запуск зі спеціальним ім'ям cert.

Спочатку запустіть aws-екземпляр із користувацькими даними користувача: "роль: веб-сервер"

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

Це називає маріонетку з ім'ям certname, як "webserver.i-hfg453.aws", тоді ви можете створити маніфест вузла під назвою "веб-сервер", а маріонетки "нечітке узгодження вузла" означатиме, що він використовується для надання всіх веб-серверів.

Цей приклад передбачає, що ви будуєте на базовому зображенні з встановленою маріонеткою тощо.

Переваги:

1) Вам не потрібно передавати свої повноваження

2) Ви можете бути настільки детальними, як вам подобається, за допомогою конфігурацій ролей.


3

Я зібрав наступне, що, сподіваємось, простіше і зрозуміліше, ніж деякі з існуючих відповідей, і використовує лише CLI AWS і ніяких додаткових інструментів.

Цей приклад коду показує, як отримати значення тегу 'myTag' для поточного екземпляра EC2:

Використання тегів опису :

export AWS_DEFAULT_REGION=us-east-1
instance_id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
aws ec2 describe-tags \
  --filters "Name=resource-id,Values=$instance_id" 'Name=key,Values=myTag' \
  --query 'Tags[].Value' --output text

Або, альтернативно, за допомогою опису-екземплярів :

aws ec2 describe-instances --instance-id $instance_id \
  --query 'Reservations[].Instances[].Tags[?Key==`myTag`].Value' --output text

2

Варіація деяких відповідей вище, але ось як я отримав значення конкретного тегу із сценарію даних користувача на екземплярі

REGION=$(curl http://instance-data/latest/meta-data/placement/availability-zone | sed 's/.$//')

INSTANCE_ID=$(curl -s http://instance-data/latest/meta-data/instance-id)

TAG_VALUE=$(aws ec2 describe-tags --region $REGION --filters "Name=resource-id,Values=$INSTANCE_ID" "Name=key,Values='<TAG_NAME_HERE>'" | jq -r '.Tags[].Value')

1

Встановіть 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

Отримайте теги для поточного екземпляра:

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

Виходи:

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

Використовуйте трохи perl для вилучення тегів:

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

Повернення:

Webserver

ec2metadataне в aws-cli, але його можна замінити на curl --silent http://169.254.169.254/latest/meta-data/instance-id. також, jqможна простіше проаналізувати json, або інший формат виводу ще простіший.
tedder42

Це працює, однак мені потрібно додати наступне: sudo apt-get -y install pythonаexport AWS_DEFAULT_REGION=us-west-1
Євген

Це не буде працювати ... 1. ec2metadata - це неправильна команда. 2. ec2-метадані - ідентифікатор речовини повернетьсяinstance-id: i-07f59f3564618f148
Daniel Hornik

1

Завантажте та запустіть автономний виконуваний файл для цього.

Іноді не можна встановити awscli, що залежить від python. Докер також може бути поза картиною.

Ось моя реалізація в golang: https://github.com/hmalphettes/go-ec2-describe-tags


1

Jq + ec2metaдані роблять це трохи приємніше. Я використовую cf і маю доступ до регіону. Інакше ви можете схопити його в баш.

aws ec2 describe-tags --region $REGION \
--filters "Name=resource-id,Values=`ec2metadata --instance-id`" | jq --raw-output \
'.Tags[] | select(.Key=="TAG_NAME") | .Value'

0

Для тих, хто досить божевільний, щоб використовувати Fish shell на EC2, ось зручний фрагмент для вашого /home/ec2-user/.config/fish/config.fish. Команда hostdata тепер перелічить усі ваші теги, а також загальнодоступні IP-адреси та ім’я хоста.

set -x INSTANCE_ID (wget -qO- http://instance-data/latest/meta-data/instance-id)
set -x REGION (wget -qO- http://instance-data/latest/meta-data/placement/availability-zone | sed 's/.$//')

function hostdata
    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"/'
    ec2-metadata | grep public-hostname
    ec2-metadata | grep public-ipv4
end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.