programing

인스턴스 내에서 EC2 태그 쿼리

nasanasas 2020. 9. 1. 07:35
반응형

인스턴스 내에서 EC2 태그 쿼리


Amazon은 최근에 많은 수의 VM을 좀 더 쉽게 관리 할 수 ​​있도록 키-값 쌍으로 EC2 인스턴스에 태그를 지정하는 멋진 기능을 추가했습니다.

다른 사용자 설정 데이터와 동일한 방식으로 이러한 태그를 쿼리하는 방법이 있습니까? 예를 들면 :

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

태그를 쿼리하는 유사한 방법이 있습니까?


AWS 메타 데이터 도구 (인스턴스 ID 검색)와 새 Tag API 의 조합을 사용 하여 현재 인스턴스의 태그를 검색 할 수 있습니다.


당신이있어 일단 ec2-metadataec2-describe-tags(에 언급 한 바와 같이 설치 위 라니에리의 대답 ), 여기 당신이 그것을에 "이름 = 푸"태그를 가정, 현재 인스턴스의 "이름"을 얻기 위해 예를 들어 쉘 명령입니다.

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 스크립트는 현재 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`"

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": ["*"]
    }
  ]
}

이 스크립트를 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

시스템에 AWS CLI 도구가 설치되어 있어야 packages합니다. 스크립트 앞에 클라우드 구성 파일 섹션을 사용하여 설치하거나 이미 포함 된 AMI를 사용 apt하거나 yum스크립트 시작 부분에 또는 명령을 추가 할 수 있습니다.

EC2 태그에 액세스하려면 인스턴스의 IAM 역할에 다음과 같은 정책이 필요합니다.

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

The instance's EC2 tags will available in /etc/ec2-tags in this format:

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

You can include the file as-is in a shell script using . /etc/ec2-tags, for example:

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

The tags are downloaded during instance initialization, so they will not reflect subsequent changes.


The script and IAM policy are based on itaifrenkel's answer.


If you are not in the default availability zone the results from overthink would return empty.

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)

If you want to add a filter to get a specific tag (elasticbeanstalk:environment-name in my case) then you can do this.

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

And to get only the value for the tag that I filtered on, we pipe to cut and get the fifth field.

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

For 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)

You can alternatively use the describe-instances cli call rather than describe-tags:

This example shows how to get the value of tag 'my-tag-name' for the instance:

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

Change the region to suit your local circumstances. This may be useful where your instance has the describe-instances privilege but not describe-tags in the instance profile policy


Using the AWS 'user data' and 'meta data' APIs its possible to write a script which wraps puppet to start a puppet run with a custom cert name.

First start an aws instance with custom user data: '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 

This calls puppet with a certname like 'webserver.i-hfg453.aws' you can then create a node manifest called 'webserver' and puppets 'fuzzy node matching' will mean it is used to provision all webservers.

This example assumes you build on a base image with puppet installed etc.

Benefits:

1) You don't have to pass round your credentials

2) You can be as granular as you like with the role configs.


Install 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

Get the tags for the current instance:

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

Outputs:

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

Use a bit of perl to extract the tags:

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

Returns:

Webserver

I have pieced together the following that is hopefully simpler and cleaner than some of the existing answers and uses only the AWS CLI and no additional tools.

This code example shows how to get the value of tag 'myTag' for the current EC2 instance:

Using describe-tags:

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

Or, alternatively, using describe-instances:

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

Download and run a standalone executable to do that.

Sometimes one cannot install awscli that depends on python. docker might be out of the picture too.

Here is my implementation in golang: https://github.com/hmalphettes/go-ec2-describe-tags


Jq + ec2metadata makes it a little nicer. I'm using cf and have access to the region. Otherwise you can grab it in bash.

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

참고URL : https://stackoverflow.com/questions/3883315/query-ec2-tags-from-within-instance

반응형