ค้นหาแท็ก EC2 จากภายในอินสแตนซ์


99

เมื่อเร็ว ๆ นี้ Amazon ได้เพิ่มคุณสมบัติที่ยอดเยี่ยมในการติดแท็กอินสแตนซ์ EC2 ด้วยคู่คีย์ - ค่าเพื่อให้การจัดการ VM จำนวนมากง่ายขึ้นเล็กน้อย

มีวิธีใดบ้างในการสืบค้นแท็กเหล่านี้ในลักษณะเดียวกับข้อมูลชุดผู้ใช้อื่น ๆ ตัวอย่างเช่น:

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

มีวิธีคล้ายกันในการค้นหาแท็กหรือไม่?

คำตอบ:


36

คุณสามารถใช้เครื่องมือ AWS metadataร่วมกัน(เพื่อดึง ID อินสแตนซ์ของคุณ) และTag API ใหม่เพื่อดึงแท็กสำหรับอินสแตนซ์ปัจจุบัน


ตกลงฉันไปตามลิงค์นั้นและดูเหมือนว่าจะเป็นเอกสาร API ไม่มีเครื่องมือใดที่ฉันสามารถใช้ได้หรือฉันจำเป็นต้องอ่านเอกสารประกอบ API และเขียนเครื่องมือของตัวเอง
Edward Falk

3
คำสั่ง ec2-description-tags สามารถใช้ได้อย่างง่ายดายหรือไม่ สมมติว่ามันอยู่ในแพ็คเกจ ec2-api-tools แต่ฉันไม่ได้อะไรเลยนอกจาก 404 เมื่อฉันพยายามติดตั้ง
Edward Falk

2
ยกตัวอย่างรับค่าบทบาทของแท็ก: aws ec2 description-tags --filters Name = resource-id, Values ​​= ec2metadata --instance-id--out = json | jq '.Tags [] | select (.Key == "role") | .Value '
jolestar

13
นี่คือตัวชี้คำตอบ แต่ไม่ใช่คำตอบในตัวของมันเอง
Roy Truelove

3
ec2metadataเครื่องมือที่จะเลิก ตอนนี้คุณค้นหา URL 'magic' ที่169.254.169.254/latest/meta-data - ตีด้วย cURL และจะให้จุดสิ้นสุดเวทย์มนตร์ที่คุณสามารถใช้เพื่อรับข้อมูลบิตต่างๆ ในกรณีนี้ให้curl http://169.254.169.254/latest/meta-data/instance-idรับรหัสอินสแตนซ์ของคุณ
Asfand Qazi

58

bash script ต่อไปนี้ส่งคืนชื่อของอินสแตนซ์ 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": ["*"]
    }
  ]
}

ผมได้รับ "คุณไม่ได้รับอนุญาตให้ดำเนินการนี้" aws ec2 describe-tagsกับ ฉันต้องการเพิ่ม IAM นี้ในนโยบายอินไลน์ของบทบาท IAM ของฉัน ขอบคุณ!
Victor D.

1
เพิ่มประสิทธิภาพเล็กน้อยมากอาจจะแทนที่ด้วย| cut -f5 --query="Tags[0].Value"
Richard A Quadling

47

เมื่อคุณติดตั้ง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นี้


17
คงจะดีไม่น้อยถ้ากระบวนการของฉันสามารถรับแท็กสำหรับอินสแตนซ์ปัจจุบันได้โดยไม่ต้องมี EC2_PRIVATE_KEY บนอินสแตนซ์ด้วย :-(
William Payne

1
@ william-payne ใช่ว่าจะง่อยจริงๆ บางทีการใช้ IAM ของ Amazon อย่างน้อยคุณก็สามารถใช้ผู้ใช้ที่มีสิทธิ์เข้าถึงอะไรก็ได้อย่าง จำกัด FWIW ฉันไม่ได้ใช้แนวทางนี้อีกต่อไปและแค่ใช้สคริปต์ภายนอกเพื่อตั้งค่ากล่อง
คิดมาก

12
@WilliamPayne คุณสามารถตั้งค่า IAM Role ด้วยนโยบาย "Amazon EC2 Read Only Access" และสร้างอินสแตนซ์ที่มีบทบาทนั้น นอกจากนี้ยังเป็นไปได้ที่จะสร้างนโยบายที่กำหนดเองโดยมีสิทธิ์ "DescribeTags" เท่านั้นหากคุณต้องการให้ละเอียดยิ่งขึ้น
roverwolf

@WilliamPayne ฉันชอบคำแนะนำของ roverwolf มันทำงานได้ดี ฉันตอบคำถามอื่นพร้อมรายละเอียดถ้าคุณต้องการดู: stackoverflow.com/questions/9950586/…
Tony

2
โปรดทราบว่าเริ่มต้นที่ec2-describe-tags us-east-2โปรดส่งผ่าน--regionธงเพื่อใช้ภูมิภาคอื่น
advait

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
Ryan Gooler

11

หากคุณไม่ได้อยู่ในโซนความพร้อมใช้งานเริ่มต้นผลลัพธ์จากการคิดมากจะกลับมาว่างเปล่า

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: 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

และเพื่อให้ได้เฉพาะค่าสำหรับแท็กที่ฉันกรองเราไปป์เพื่อตัดและรับฟิลด์ที่ห้า

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 ที่แตกต่างกันไม่ได้ผลสำหรับฉันสำหรับอันสุดท้ายหากคุณต้องการให้แท็กชื่อแทนที่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 จะตรวจหา ID และคีย์โดยอัตโนมัติ
dbn

5

คุณสามารถใช้describe-instancescli call แทน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

เปลี่ยนภูมิภาคให้เหมาะกับสถานการณ์ในท้องถิ่นของคุณ สิ่งนี้อาจมีประโยชน์เมื่ออินสแตนซ์ของคุณมีสิทธิ์อธิบายอินสแตนซ์ แต่ไม่มีแท็กอธิบายในนโยบายโปรไฟล์อินสแตนซ์


4

ฉันได้ปะติดปะต่อสิ่งต่อไปนี้ซึ่งหวังว่าจะง่ายและสะอาดกว่าคำตอบบางคำที่มีอยู่และใช้เฉพาะ AWS CLI และไม่มีเครื่องมือเพิ่มเติม

ตัวอย่างโค้ดนี้แสดงวิธีรับค่าของแท็ก '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

3

การใช้ API 'ข้อมูลผู้ใช้' และ 'ข้อมูลเมตา' ของ AWS ทำให้สามารถเขียนสคริปต์ที่ห่อหุ้มหุ่นเพื่อเริ่มการทำงานของหุ่นเชิดด้วยชื่อใบรับรองที่กำหนดเอง

เริ่มต้นอินสแตนซ์ 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' จากนั้นคุณสามารถสร้างรายการโหนดที่เรียกว่า 'เว็บเซิร์ฟเวอร์' และ 'การจับคู่โหนดที่คลุมเครือ' ของหุ่นเชิดจะหมายความว่ามันถูกใช้เพื่อจัดเตรียมเว็บเซิร์ฟเวอร์ทั้งหมด

ตัวอย่างนี้สมมติว่าคุณสร้างบนอิมเมจพื้นฐานที่ติดตั้งหุ่นเป็นต้น

สิทธิประโยชน์:

1) คุณไม่จำเป็นต้องผ่านข้อมูลรับรองของคุณ

2) คุณสามารถกำหนดรายละเอียดได้ตามต้องการด้วยการกำหนดค่าบทบาท


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

2

Jq + ec2metadata ทำให้ดีขึ้นเล็กน้อย ฉันใช้ cf และสามารถเข้าถึงภูมิภาคได้ มิฉะนั้นคุณสามารถคว้ามันได้ในการทุบตี

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

ไม่มี jq.

aws ec2 describe-tags --region us-west-2 \
--filters "Name=resource-id,Values=`ec2-metadata --instance-id | cut -d " " -f 2`" \
--query 'Tags[?Key==`Name`].Value' \
--output text

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-metadata --instance-id จะกลับมาinstance-id: i-07f59f3564618f148
Daniel Hornik

1

ดาวน์โหลดและเรียกใช้ปฏิบัติการแบบสแตนด์อโลนเพื่อดำเนินการดังกล่าว

บางครั้งเราไม่สามารถติดตั้ง awscli ที่ขึ้นอยู่กับ python ได้ นักเทียบท่าอาจจะไม่อยู่ในภาพด้วย

นี่คือการใช้งานของฉันใน golang: https://github.com/hmalphettes/go-ec2-describe-tags


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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.