Kueri tag EC2 dari dalam instance


96

Amazon baru-baru ini menambahkan fitur luar biasa untuk menandai instans EC2 dengan pasangan nilai kunci untuk membuat pengelolaan sejumlah besar VM menjadi sedikit lebih mudah.

Adakah cara untuk menanyakan tag ini dengan cara yang sama seperti beberapa data kumpulan pengguna lainnya? Sebagai contoh:

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

Apakah ada cara yang mirip untuk menanyakan tag?

Jawaban:


35

Anda dapat menggunakan kombinasi alat metadata AWS (untuk mengambil ID instans Anda) dan API Tag baru untuk mengambil tag untuk instans saat ini.


Oke, saya mengikuti tautan itu, dan sepertinya itu adalah dokumentasi API. Apakah tidak ada alat yang dapat saya gunakan, atau apakah saya perlu membaca dokumentasi API dan menulis alat saya sendiri?
Edward Falk

3
Apakah perintah ec2-description-tags mudah tersedia? Seharusnya ada dalam paket ec2-api-tools, tapi saya hanya mendapatkan 404 ketika saya mencoba untuk menginstalnya.
Edward Falk

2
berikan contoh, dapatkan nilai peran tag: aws ec2 deskripsikan-tag --filters Name = resource-id, Values ​​= ec2metadata --instance-id--out = json | jq '.Tags [] | pilih (.Key == "role") | .Value '
jolestar

12
Ini adalah penunjuk ke jawaban tapi bukan jawaban itu sendiri
Roy Truelove

3
The ec2metadataalat sudah ditinggalkan. Sekarang Anda meminta URL 'ajaib' di 169.254.169.254/latest/meta-data - tekan dengan cURL dan itu memberi Anda titik akhir ajaib yang dapat Anda gunakan untuk mendapatkan berbagai bit data. Dalam hal ini, curl http://169.254.169.254/latest/meta-data/instance-iddapatkan ID instans Anda
Asfand Qazi

52

Skrip bash berikut mengembalikan Nama instance ec2 Anda saat ini (nilai tag "Nama"). Ubah TAG_NAME untuk kasus khusus Anda.

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

Untuk memasang aws cli

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

Jika Anda menggunakan IAM dan bukan kredensial eksplisit, gunakan izin IAM ini:

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

Saya mendapatkan pesan "Anda tidak diizinkan untuk melakukan operasi ini" dengan aws ec2 describe-tags. Saya perlu menambahkan IAM ini ke kebijakan sebaris peran IAM saya. Terima kasih!
Victor D.

Pengoptimalan yang sangat sedikit DAPAT menggantikan | cut -f5dengan --query="Tags[0].Value".
Richard A Quadling

47

Setelah Anda mendapatkan ec2-metadatadan ec2-describe-tagsmenginstal (seperti yang disebutkan dalam jawaban Ranieri di atas ), berikut adalah contoh perintah shell untuk mendapatkan "nama" dari instance saat ini, dengan asumsi Anda memiliki tag "Name = Foo" di atasnya.

Mengasumsikan variabel lingkungan EC2_PRIVATE_KEY dan EC2_CERT telah ditetapkan.

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

Ini kembali Foo.


17
Alangkah baiknya jika proses saya bisa mendapatkan tag untuk instance saat ini tanpa harus memiliki EC2_PRIVATE_KEY di instance tersebut juga. :-(
William Payne

1
@ william-payne Ya, itu benar-benar payah. Mungkin menggunakan IAM Amazon Anda setidaknya dapat menggunakan pengguna dengan akses yang sangat terbatas ke apa pun. FWIW, saya tidak menggunakan pendekatan ini lagi dan hanya menggunakan skrip eksternal untuk menyiapkan kotak.
terlalu memikirkan

12
@WilliamPayne Anda dapat mengatur Peran IAM dengan kebijakan "Akses Hanya Baca Amazon EC2" dan membuat instans yang memiliki peran tersebut. Anda juga dapat membuat kebijakan khusus yang hanya memiliki hak istimewa "DescribeTags" jika Anda ingin lebih terperinci.
roverwolf

@WilliamPne Saya menyukai saran roverwolf. Ini bekerja dengan baik. Saya sebenarnya menjawab pertanyaan lain dengan detail jika Anda ingin melihatnya: stackoverflow.com/questions/9950586/…
Tony

2
Perhatikan bahwa ec2-describe-tagsdefaultnya adalah us-east-2. Harap berikan --regionbendera untuk menggunakan wilayah lain.
advait

15

Anda dapat menambahkan skrip ini ke data pengguna cloud-init Anda untuk mengunduh tag EC2 ke file lokal:

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

Anda memerlukan alat AWS CLI yang diinstal pada sistem Anda: Anda dapat menginstalnya dengan packagesbagian di file konfigurasi cloud sebelum skrip, menggunakan AMI yang sudah menyertakannya, atau menambahkan perintah aptatau yumdi awal skrip.

Untuk mengakses tag EC2, Anda memerlukan kebijakan seperti ini dalam peran IAM instans Anda:

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

Tag EC2 instans akan tersedia dalam /etc/ec2-tagsformat ini:

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

Anda dapat memasukkan file apa adanya dalam skrip shell menggunakan . /etc/ec2-tags, misalnya:

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

Tag didownload selama inisialisasi instance, jadi tag tidak akan mencerminkan perubahan selanjutnya.


Skrip dan kebijakan IAM didasarkan pada jawaban itaifrenkel.


a + lebih suka metode ini
Cmag

aws:autoscaling:groupName
sayang

2
Kemudian coba ini: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

10

Jika Anda tidak berada di zona ketersediaan default, hasil dari overthink akan kembali kosong.

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)

Jika Anda ingin menambahkan filter untuk mendapatkan tag tertentu (elasticbeanstalk: nama-lingkungan dalam kasus saya) maka Anda dapat melakukan ini.

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

Dan untuk mendapatkan hanya nilai untuk tag yang saya filter, kami menyalurkan untuk memotong dan mendapatkan bidang kelima.

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

Kerja bagus, terima kasih, memiliki instance-data dns yang berbeda tidak berfungsi untuk saya, untuk yang terakhir jika Anda perlu mengganti Tag nama elasticbeanstalk:environment-namedenganName
detzu

5

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

Sah. Pembaca mencatat untuk info lokal dasar Anda bahkan tidak memerlukan kredensial, hanyainstance_metadata = utils.get_instance_metadata(timeout=0.5, num_retries=1)
Bartvds

Selain itu, ini berfungsi dengan baik dengan peran IAM - jika Anda menetapkan peran instance, boto akan secara otomatis mendeteksi ID dan kunci.
dbn

5

Sebagai alternatif, Anda dapat menggunakan describe-instancespanggilan cli daripada describe-tags:

Contoh ini menunjukkan bagaimana mendapatkan nilai dari tag 'my-tag-name' sebagai contoh:

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

Ubah wilayah agar sesuai dengan keadaan lokal Anda. Ini mungkin berguna jika instance Anda memiliki hak istimewa deskripsikan-instance tetapi tidak tag-deskripsi dalam kebijakan profil instance


3

Menggunakan 'data pengguna' dan 'meta data' AWS API memungkinkan untuk menulis skrip yang membungkus boneka untuk memulai permainan boneka dengan nama sertifikat khusus.

Pertama mulai instance aws dengan data pengguna khusus: '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 

Ini memanggil boneka dengan nama sertifikat seperti 'webserver.i-hfg453.aws' Anda kemudian dapat membuat manifes node yang disebut 'webserver' dan boneka 'fuzzy node matching' akan berarti digunakan untuk menyediakan semua server web.

Contoh ini mengasumsikan Anda membangun di atas gambar dasar dengan boneka terpasang, dll.

Manfaat:

1) Anda tidak harus menyerahkan kredensial Anda

2) Anda dapat dibuat sedetail mungkin dengan konfigurasi peran.


3

Saya telah mengumpulkan yang berikut ini yang semoga lebih sederhana dan lebih bersih daripada beberapa jawaban yang ada dan hanya menggunakan AWS CLI dan tidak ada alat tambahan.

Contoh kode ini menunjukkan bagaimana mendapatkan nilai tag 'myTag' untuk contoh EC2 saat ini:

Menggunakan description-tag :

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

Atau, sebagai alternatif, menggunakan deskripsikan-instance :

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

2

Jq + ec2metadata membuatnya sedikit lebih bagus. Saya menggunakan cf dan memiliki akses ke wilayah tersebut. Jika tidak, Anda bisa mengambilnya dengan pesta.

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

2

Variasi pada beberapa jawaban di atas tetapi inilah cara saya mendapatkan nilai tag tertentu dari skrip data pengguna pada sebuah contoh

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

Instal 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

Dapatkan tag untuk instance saat ini:

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

Keluaran:

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

Gunakan sedikit perl untuk mengekstrak tag:

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

Pengembalian:

Webserver

ec2metadatatidak dalam aws-cli, tetapi dapat diganti dengan curl --silent http://169.254.169.254/latest/meta-data/instance-id. juga, jqdapat mengurai json lebih mudah, atau format keluaran yang berbeda bahkan lebih mudah.
tedder42

Ini berfungsi, namun saya perlu menambahkan berikut ini: sudo apt-get -y install pythondanexport AWS_DEFAULT_REGION=us-west-1
Eugene

Ini tidak akan berhasil ... 1. ec2metadata adalah perintah yang salah. 2. ec2-metadata --instance-id akan kembaliinstance-id: i-07f59f3564618f148
Daniel Hornik


0

Bagi mereka yang cukup gila untuk menggunakan Fish shell di EC2, berikut cuplikan praktis untuk /home/ec2-user/.config/fish/config.fish Anda. Perintah hostdata sekarang akan mencantumkan semua tag Anda serta IP publik dan nama host.

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.