Truy vấn thẻ EC2 từ bên trong phiên bản


96

Amazon gần đây đã thêm tính năng tuyệt vời là gắn thẻ các phiên bản EC2 với các cặp khóa-giá trị để giúp quản lý số lượng lớn máy ảo dễ dàng hơn một chút.

Có cách nào để truy vấn các thẻ này theo cùng một cách với một số dữ liệu do người dùng đặt khác không? Ví dụ:

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

Có một số cách tương tự để truy vấn các thẻ không?

Câu trả lời:


36

Bạn có thể sử dụng kết hợp công cụ siêu dữ liệu AWS (để truy xuất ID phiên bản của bạn) và API thẻ mới để truy xuất các thẻ cho phiên bản hiện tại.


OK, tôi đã theo liên kết đó và có vẻ như đó là tài liệu API. Không có công cụ nào mà tôi có thể sử dụng hoặc tôi cần đọc tài liệu API và viết công cụ của riêng mình?
Edward Falk

3
Lệnh ec2-description-tags có dễ sử dụng không? Được cho là nó nằm trong gói ec2-api-tools, nhưng tôi không nhận được gì ngoài 404 khi cố cài đặt nó.
Edward Falk

2
cho một ví dụ, lấy giá trị của vai trò thẻ: aws ec2 description-tags --filters Name = resource-id, Values ​​= ec2metadata --instance-id--out = json | jq '.Tags [] | select (.Key == "role") |
.Value

11
Đây là một con trỏ đến một câu trả lời nhưng không phải là một câu trả lời trong-và-của chính nó
Roy Truelove

3
Công ec2metadatacụ này không được dùng nữa. Bây giờ bạn truy vấn URL 'ma thuật' tại 169.254.169.254/latest/meta-data - nhấn nó bằng cURL và nó cung cấp cho bạn các điểm cuối ma thuật mà bạn có thể sử dụng để lấy các bit dữ liệu khác nhau. Trong trường hợp này curl http://169.254.169.254/latest/meta-data/instance-idđược bạn ID dụ của bạn
Asfand Qazi

52

Tập lệnh bash sau đây trả về Tên của phiên bản ec2 hiện tại của bạn (giá trị của thẻ "Tên"). Sửa đổi TAG_NAME cho trường hợp cụ thể của bạn.

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

Để cài đặt aws cli

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

Trong trường hợp bạn sử dụng IAM thay vì thông tin xác thực rõ ràng, hãy sử dụng các quyền IAM sau:

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

Tôi nhận được "Bạn không được phép thực hiện thao tác này" với aws ec2 describe-tags. Tôi cần thêm IAM này vào các chính sách nội bộ của vai trò IAM của mình. Cảm ơn!
Victor D.

Một tối ưu hóa rất nhỏ NÊN thay thế | cut -f5bằng --query="Tags[0].Value".
Richard A Quadling

47

Khi bạn đã có ec2-metadataec2-describe-tagscài đặt (như đã đề cập trong câu trả lời của Ranieri ở trên ), đây là lệnh shell ví dụ để lấy "tên" của phiên bản hiện tại, giả sử bạn có thẻ "Name = Foo" trên đó.

Giả sử các biến môi trường EC2_PRIVATE_KEY và EC2_CERT được đặt.

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

Điều này trở lại Foo.


17
Sẽ thật tuyệt nếu các quy trình của tôi có thể lấy các thẻ cho phiên bản hiện tại mà không cần phải có EC2_PRIVATE_KEY trên phiên bản đó. :-(
William Payne

1
@ william-payne Vâng, điều đó thực sự khập khiễng. Có lẽ khi sử dụng IAM của Amazon, ít nhất bạn có thể sử dụng một người dùng có quyền truy cập rất hạn chế vào bất kỳ thứ gì. FWIW, tôi không sử dụng phương pháp này nữa và chỉ sử dụng các tập lệnh bên ngoài để thiết lập hộp.
overthink

12
@WilliamPayne Bạn có thể thiết lập Vai trò IAM với chính sách "Quyền truy cập chỉ đọc của Amazon EC2" và tạo phiên bản có vai trò đó. Cũng có thể tạo chính sách tùy chỉnh chỉ có đặc quyền "DescribeTags" nếu bạn muốn chi tiết hơn.
roverwolf

@WilliamPayne Tôi thích đề xuất của roverwolf. Nó hoạt động tuyệt vời. Tôi thực sự đã trả lời một câu hỏi khác với các chi tiết nếu bạn muốn xem: stackoverflow.com/questions/9950586/…
Tony

2
Lưu ý rằng ec2-describe-tagsmặc định là us-east-2. Vui lòng chuyển --regioncờ để sử dụng một khu vực khác.
advait

15

Bạn có thể thêm tập lệnh này vào dữ liệu người dùng cloud-init của mình để tải các thẻ EC2 xuống tệp cục bộ:

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

Bạn cần cài đặt các công cụ AWS CLI trên hệ thống của mình: bạn có thể cài đặt chúng bằng một packagesphần trong tệp cấu hình đám mây trước tập lệnh, sử dụng AMI đã bao gồm chúng hoặc thêm một apthoặc yumlệnh vào đầu tập lệnh.

Để truy cập các thẻ EC2, bạn cần một chính sách như thế này trong vai trò IAM của phiên bản của bạn:

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

Các thẻ EC2 của phiên bản sẽ có sẵn ở /etc/ec2-tagsđịnh dạng sau:

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

Bạn có thể bao gồm tệp nguyên gốc trong tập lệnh shell bằng cách sử dụng . /etc/ec2-tags, ví dụ:

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

Các thẻ được tải xuống trong quá trình khởi tạo phiên bản, vì vậy chúng sẽ không phản ánh các thay đổi tiếp theo.


Tập lệnh và chính sách IAM dựa trên câu trả lời của itaifrenkel.


a + thích phương pháp này
Cmag

quá tệ, điều này bị hỏng đối với các thẻ được tạo bởi các nhóm tự động định tỷ lệ:aws:autoscaling:groupName
Cmag

2
Sau đó, hãy thử điều này: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

Nếu bạn không ở trong vùng khả dụng mặc định, kết quả từ overthink sẽ trả về trống.

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)

Nếu bạn muốn thêm một bộ lọc để lấy một thẻ cụ thể (trong trường hợp của tôi là co giãnbeanstalk: tên môi trường) thì bạn có thể thực hiện việc này.

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

Và để chỉ lấy giá trị cho thẻ mà tôi đã lọc, chúng tôi cắt và lấy trường thứ năm.

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

công việc tuyệt vời, cảm ơn bạn, có một dns dụ dữ liệu khác nhau không được làm việc cho tôi, cho người cuối cùng nếu bạn cần tag Tên thay thế elasticbeanstalk:environment-namevớiName
detzu

5

Đối với 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)

Hợp pháp. Độc giả lưu ý để biết thông tin địa phương cơ bản, bạn thậm chí không cần thông tin đăng nhập, chỉ cầninstance_metadata = utils.get_instance_metadata(timeout=0.5, num_retries=1)
Bartvds

Ngoài ra, điều này hoạt động tốt với các vai trò IAM - nếu bạn đặt một vai trò cá thể, boto sẽ tự động phát hiện ID và khóa.
dbn

5

Ngoài ra, bạn có thể sử dụng describe-instancescuộc gọi cli thay vì describe-tags:

Ví dụ này cho thấy cách lấy giá trị của thẻ 'my-tag-name' cho ví dụ:

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

Thay đổi khu vực cho phù hợp với hoàn cảnh địa phương của bạn. Điều này có thể hữu ích khi phiên bản của bạn có đặc quyền về phiên bản mô tả nhưng không có thẻ mô tả trong chính sách cấu hình cá thể


3

Việc sử dụng API 'dữ liệu người dùng' và 'dữ liệu siêu dữ liệu' AWS có thể viết một tập lệnh bao bọc con rối để bắt đầu một lần chạy con rối với tên chứng chỉ tùy chỉnh.

Trước tiên hãy bắt đầu một phiên bản aws với dữ liệu người dùng tùy chỉnh: '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 

Điều này gọi con rối với tên cert như 'webserver.i-hfg453.aws', sau đó, bạn có thể tạo tệp kê khai nút được gọi là 'máy chủ web' và con rối 'đối sánh nút mờ' sẽ có nghĩa là nó được sử dụng để cung cấp tất cả các máy chủ web.

Ví dụ này giả sử bạn xây dựng trên một hình ảnh cơ sở có cài đặt con rối, v.v.

Những lợi ích:

1) Bạn không cần phải vượt qua thông tin đăng nhập của mình

2) Bạn có thể chi tiết tùy thích với các cấu hình vai trò.


3

Tôi đã tổng hợp những câu sau đây hy vọng đơn giản và gọn gàng hơn một số câu trả lời hiện có và chỉ sử dụng AWS CLI và không có công cụ bổ sung.

Ví dụ mã này cho thấy cách lấy giá trị của thẻ 'myTag' cho phiên bản EC2 hiện tại:

Sử dụng thẻ mô tả :

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

Hoặc, cách khác, sử dụng các trường hợp mô tả :

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

2

Một biến thể của một số câu trả lời ở trên nhưng đây là cách tôi lấy giá trị của một thẻ cụ thể từ tập lệnh dữ liệu người dùng trên một phiên bản

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

Cài đặt 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

Nhận các thẻ cho phiên bản hiện tại:

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

Kết quả đầu ra:

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

Sử dụng một chút perl để trích xuất các thẻ:

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

Lợi nhuận:

Webserver

ec2metadatakhông có trong aws-cli, nhưng nó có thể được thay thế bằng curl --silent http://169.254.169.254/latest/meta-data/instance-id. cũng jqcó thể phân tích cú pháp json dễ dàng hơn hoặc một định dạng đầu ra khác thậm chí còn dễ dàng hơn.
tedder42

Điều này hoạt động, tuy nhiên tôi cần thêm những điều sau đây: sudo apt-get -y install pythonexport AWS_DEFAULT_REGION=us-west-1
Eugene

Điều này sẽ không hoạt động ... 1. ec2metadata là lệnh không chính xác. 2. siêu dữ liệu ec2 --instance-id sẽ trở lạiinstance-id: i-07f59f3564618f148
Daniel Hornik


1

Jq + ec2metadata làm cho nó đẹp hơn một chút. Tôi đang sử dụng cf và có quyền truy cập vào khu vực. Nếu không, bạn có thể lấy nó trong bash.

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

0

Đối với những người đủ điên rồ để sử dụng Fish shell trên EC2, đây là đoạn mã hữu ích cho /home/ec2-user/.config/fish/config.fish của bạn. Lệnh hostdata bây giờ sẽ liệt kê tất cả các thẻ của bạn cũng như IP công khai và tên máy chủ.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.