Ответ 1
Вы можете использовать комбинацию инструментария метаданных AWS (для получения идентификатора вашего экземпляра) и новый API тегов для получения тегов для текущего экземпляра.
Amazon недавно добавила замечательную возможность пометки экземпляров EC2 парами ключ-значение, чтобы немного упростить управление большим количеством виртуальных машин.
Есть ли способ запросить эти теги так же, как и некоторые другие пользовательские данные? Например:
$ curl http://169.254.169.254/latest/meta-data/placement/availability-zone
us-east-1d
Есть ли похожий способ запроса тегов?
Вы можете использовать комбинацию инструментария метаданных AWS (для получения идентификатора вашего экземпляра) и новый API тегов для получения тегов для текущего экземпляра.
После того, как вы установили ec2-metadata
и ec2-describe-tags
(как упоминалось в ответ Ranieri выше), здесь приведен пример команды оболочки, чтобы получить "имя", текущего экземпляра, предполагая, что на нем есть тег "Name = 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
.
Следующий bash script возвращает Имя текущего экземпляра 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": ["*"]
}
]
}
Вы можете добавить этот script в свои пользовательские данные cloud-init, чтобы загрузить теги 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
Вам нужны инструменты AWI CLI, установленные в вашей системе: вы можете установить их с помощью раздела packages
в файле облачной конфигурации перед script, использовать AMI, который уже включает их, или добавить apt
или yum
в начале script.
Чтобы получить доступ к тегам 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"
Вы можете включить файл как есть в оболочке script с помощью . /etc/ec2-tags
, например:
#!/bin/sh
. /etc/ec2-tags
echo $Name
Теги загружаются во время инициализации экземпляра, поэтому они не будут отражать последующие изменения.
Политика script и IAM основана на ответе itaifrenkel.
Если вы не находитесь в зоне доступности по умолчанию, результаты от overthink вернутся пустым.
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
Для 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)
Используя API-интерфейсы AWS 'user data' и 'meta data', можно написать script, который обертывает марионетку, чтобы запустить марионетку с пользовательским именем сертификата.
Сначала запустите экземпляр aws с пользовательскими данными пользователя: '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
Это вызывает марионетку с таким именем, как "webserver.i-hfg453.aws", после чего вы можете создать манифест node, называемый "веб-сервер", а нечеткое node совпадение кукол будет означать, что оно используется для предоставления всех веб-серверов,
В этом примере предполагается, что вы строите базовое изображение с установленной марионеткой и т.д.
Преимущества:
1) Вам не нужно передавать свои учетные данные
2) Вы можете быть такими же гранулярными, как вы, с конфигурациями ролей.
В качестве альтернативы вы можете использовать cli-вызов description 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
Измените регион в соответствии с вашими местными условиями. Это может быть полезно, если у вашего экземпляра есть привилегия description-instances, но нет тегов description в политике профиля экземпляра.
Установите 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
Загрузите и запустите автономный исполняемый файл, чтобы сделать это.
Иногда нельзя установить awscli, зависящий от python. docker также может быть вне изображения.
Вот моя реализация в golang: https://github.com/hmalphettes/go-ec2-describe-tags
Я собрал воедино следующее, которое, надеюсь, проще и чище, чем некоторые из существующих ответов, и использует только интерфейс командной строки 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
Jq + ec2metadata делает его немного лучше. Я использую cf и имею доступ к региону. В противном случае вы можете получить его в bash.
aws ec2 describe-tags --region $REGION \
--filters "Name=resource-id,Values='ec2metadata --instance-id'" | jq --raw-output \
'.Tags[] | select(.Key=="TAG_NAME") | .Value'