从实例中查询EC2标签

Jos*_*sey 92 amazon-ec2 amazon-web-services

亚马逊最近添加标记EC2实例与键值对,使大量虚拟机的管理更容易一点的奇妙功能.

是否有某种方式来查询相同的方式将这些标签的一些其它用户设置的数据?例如:

$ curl http://169.254.169.254/latest/meta-data/placement/availability-zone
us-east-1d
Run Code Online (Sandbox Code Playgroud)

是否有一些类似的方式来查询标签?

ove*_*ink 46

一旦你得到ec2-metadataec2-describe-tags安装了(如上面Ranieri的回答所述),这里有一个示例shell命令来获取当前实例的"名称",假设你有一个"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
Run Code Online (Sandbox Code Playgroud)

这回来了Foo.

  • 如果我的进程可以获取当前实例的标记而不必在实例上具有EC2_PRIVATE_KEY,那将是很好的.:-( (17认同)
  • @WilliamPayne您可以使用"Amazon EC2只读访问"策略设置IAM角色,并创建具有该角色的实例.如果您想要更精细,也可以创建仅具有"DescribeTags"特权的自定义策略. (11认同)
  • 请注意,“ ec2-describe-tags”默认为“ us-east-2”。请通过--region标志来使用其他区域。 (2认同)

ita*_*kel 46

以下bash脚本返回当前ec2实例的名称("Name"标记的值).根据您的具体情况修改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`"
Run Code Online (Sandbox Code Playgroud)

安装aws cli

sudo apt-get install python-pip -y
sudo pip install awscli
Run Code Online (Sandbox Code Playgroud)

如果您使用IAM而不是显式凭据,请使用以下IAM权限:

{
  "Version": "2012-10-17",
  "Statement": [
    {    
      "Effect": "Allow",
      "Action": [ "ec2:DescribeTags"],
      "Resource": ["*"]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

  • 一个非常小的优化可以是替换`| 用 `--query="Tags[0].Value"` 剪切 -f5`。 (3认同)

drx*_*zcl 36

您可以结合使用AWS元数据工具(以检索实例ID)和新的Tag API来检索当前实例的标记.

  • 这是一个指向答案的指针,但不是答案本身 (9认同)
  • ec2-describe-tags命令是否易于使用?据说它是在ec2-api-tools软件包中,但是当我尝试安装它时,我只得到了404. (3认同)
  • 举个例子,获取标签角色的值: aws ec2 describe-tags --filters Name=resource-id,Values=`ec2metadata --instance-id` --out=json|jq '.Tags[]| select(.Key == "role")|.Value' (2认同)
  • 不推荐使用“ ec2metadata”工具。现在,您可以在http://169.254.169.254/latest/meta-data/上查询“魔术” URL-用cURL对其进行点击,它为您提供了魔术端点,可用于获取各种数据。在这种情况下,“ curl http://169.254.169.254/latest/meta-data/instance-id”会获取您的实例ID (2认同)

And*_*rea 13

您可以将此脚本添加到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
Run Code Online (Sandbox Code Playgroud)

您需要在系统上安装AWS CLI工具:您可以packages在脚本之前使用cloud-config文件中的部分安装它们,使用已包含它们的AMI,或者在脚本开头添加aptyum命令.

要访问EC2标记,您需要在您的实例的IAM角色中使用类似这样的策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1409309287000",
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeTags"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

实例的EC2标签将以/etc/ec2-tags这种格式提供:

FOO="Bar"
Name="EC2 tags with cloud-init"
Run Code Online (Sandbox Code Playgroud)

您可以使用以下方式将文件原样包含在shell脚本中. /etc/ec2-tags,例如:

#!/bin/sh
. /etc/ec2-tags
echo $Name
Run Code Online (Sandbox Code Playgroud)

标签在实例初始化期间下载,因此它们不会反映后续更改.


脚本和IAM策略基于itaifrenkel的答案.

  • 然后试试这个:'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` (2认同)

Mic*_*nor 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)
Run Code Online (Sandbox Code Playgroud)

如果你想添加一个过滤器来获取一个特定的标签(在我的例子中是elasticbeanstalk:environment-name),你可以这样做.

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
Run Code Online (Sandbox Code Playgroud)

并且只获取我过滤的标签的值,我们管道切割并获得第五个字段.

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
Run Code Online (Sandbox Code Playgroud)


sho*_*ser 8

您也可以使用describe-instancescli 调用而不是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
Run Code Online (Sandbox Code Playgroud)

更改区域以适合您当地的情况。当您的实例在实例配置文件策略中具有 describe-instances 权限但没有 describe-tags 时,这可能很有用


Ari*_*iav 8

从 2022 年 1 月开始,这也应该可以直接通过 ec2 元数据 api(如果启用)获得。

curl http://169.254.169.254/latest/meta-data/tags/instance
Run Code Online (Sandbox Code Playgroud)

https://aws.amazon.com/about-aws/whats-new/2022/01/instance-tags-amazon-ec2-instance-metadata-service/


Ale*_*vey 6

我拼凑了以下内容,希望它们比一些现有答案更简单、更清晰,并且仅使用 AWS CLI 而没有其他工具。

此代码示例显示了如何获取当前 EC2 实例的标签“myTag”的值:

使用描述标签

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
Run Code Online (Sandbox Code Playgroud)

或者,或者,使用describe-instances

aws ec2 describe-instances --instance-id $instance_id \
  --query 'Reservations[].Instances[].Tags[?Key==`myTag`].Value' --output text
Run Code Online (Sandbox Code Playgroud)


小智 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)
Run Code Online (Sandbox Code Playgroud)