Tìm khu vực từ trong một ví dụ EC2


131

Có cách nào để tra cứu khu vực của một thể hiện từ trong thể hiện không?

Tôi đang tìm kiếm một cái gì đó tương tự như phương pháp tìm id cá thể .



8
Câu trả lời ngắn gọn cho bất kỳ ai không quan tâm đến tất cả các tập lệnh shell: lấy vùng khả dụng từ http://169.254.169.254/latest/meta-data/placement/availability-zonevà xóa ký tự cuối cùng.
Sarsaparilla

Điều này có trả lời câu hỏi của bạn không? Làm cách nào để lấy id cá thể từ bên trong một thể hiện ec2?
dWinder

Câu trả lời:


147

URL đó ( http://169.254.169.254/latest/dynamic/instance-identity/document ) sẽ không còn hoạt động nữa. Tôi nhận được 404 khi tôi cố gắng sử dụng nó. Tôi có đoạn mã sau có vẻ hoạt động:

EC2_AVAIL_ZONE=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`
EC2_REGION="`echo \"$EC2_AVAIL_ZONE\" | sed 's/[a-z]$//'`"

Hi vọng điêu nay co ich.

EDIT: Cải thiện seddựa trên ý kiến


4
Điều này sẽ được chạy bên trong thể hiện EC2 và được cung cấp bởi các phụ trợ của AWS. Nó sẽ không hoạt động ở bất cứ nơi nào khác (về cơ bản vì IP đó là một APIPA). Ngoài ra, không có cách nào để có được thông tin này trực tiếp từ bên trong thể hiện mà không kết nối với nguồn siêu dữ liệu. Điều này giả định rằng API 169.254.169.254 có sẵn và tập lệnh của bạn sẽ xử lý các lỗi mạng tương ứng. ec2-metadatachỉ là một trình bao bọc cho API này, nhưng về cơ bản cũng làm điều tương tự.
dannizard

1
Đây có phải là một cái gì đó tài liệu? Bạn có thể giải thích làm thế nào bạn tìm thấy nó?
meawoppl

2
Thành thật mà nói khi tôi đưa ra 2-liner đó, tôi chỉ chọc vào API tìm kiếm bất cứ thứ gì tôi có thể sử dụng để xác định đúng khu vực. API siêu dữ liệu AWS được ghi lại đầy đủ tại đây: docs.aws.amazon.com/AWSEC2/latest/UserGuide/ Kẻ
dannizard

12
Lệnh thay thế sed đơn giản hơn nhiều so với lệnh được cung cấp cho EC2_REGION:sed 's/[a-z]$//
bajeez 13/08/2015

2
Nếu đây là trong một bản khởi động, dịch vụ siêu dữ liệu có thể chưa được khởi tạo - nếu vậy, hãy chờ và thử lại. Tôi đã thấy phải mất 10-15 giây sau khi khởi động để vị trí siêu dữ liệu có sẵn.
vacri

81

Có một cách nữa để đạt được điều đó:

REGION=`curl http://169.254.169.254/latest/dynamic/instance-identity/document|grep region|awk -F\" '{print $4}'`

echo $REGION

us-east-1

Điều này có nên hoạt động trong bất kỳ khu vực / az (và trên bất kỳ AMI)? Tôi đang 404 - Not Foundcố gắng truy cập GETURL đó từ một máy us-east-1a.
Adam Monsen

@AdamMonsen có lẽ đó là một lỗi thoáng qua. Tôi ở trên chúng tôi-đông-1a và nó hoạt động rất tốt.
Florin Andrei

Cảm ơn @FlorinAndrei. Làm việc cho tôi bây giờ quá.
Adam Monsen

3
Với jq:curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region
Yaron

4
Với awk:curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | awk -F\" '/region/ {print $4}'
Yaron

38

Nếu bạn ổn với việc sử dụng jq, bạn có thể chạy như sau:

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq .region -r

Tôi đoán đó là cách sạch nhất.


31
ec2-metadata --availability-zone | sed 's/.$//'

Đối với các hệ thống dựa trên debian, lệnh không có dấu gạch ngang.

ec2metadata --availability-zone | sed 's/.$//'

6
Nhận chuỗi thuần chỉ với tên khu vực:ec2-metadata --availability-zone | sed 's/placement: \(.*\).$/\1/'
nahsh

ec2-metadatadường như không phải là thứ có sẵn theo mặc định - bạn có thể bao gồm các hướng dẫn cài đặt không?
Tim Malone

23

Nếu bạn muốn tránh biểu thức chính quy, đây là một lớp lót bạn có thể làm với Python:

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | python -c "import json,sys; print json.loads(sys.stdin.read())['region']"

Câu trả lời này nên cao hơn!
Kostas Demiris

@KostasDemiris Tôi đồng ý, thay vì đọc giá trị từ cấu trúc JSON hơn là một biểu thức thông thường.
lasec0203

1
Tôi đồng ý đây có vẻ là cách tốt nhất để làm điều đó nếu bạn chưa cài đặt jq. Bạn thực sự mong đợi AWS sẽ phơi bày điều này giống như 169.254.169.254/latest/meta-data/plocation/region ...
Krenair

17

Bạn có thể sử dụng siêu dữ liệu ec2:

ec2-metadata -z | grep -Po "(us|sa|eu|ap)-(north|south|central)?(east|west)?-[0-9]+"

2
Với điều này, nếu bạn đang ở trong tình trạng khó khăn eu-central-1.
dannizard

2
centralđã không tồn tại khi tôi ban đầu viết câu trả lời của mình. Nó được thêm vào bây giờ.
Daniel Kuppitz

22
Một kịch bản phá vỡ mỗi khi AWS thêm một khu vực mới dường như không phải là một giải pháp đặc biệt mạnh mẽ đối với tôi.
Ryan B. Lynch

1
Thay vì grep, awk '{split($2,arr,"-"); print arr[1]"-"arr[2]}'sẽ chỉ giữ hai thành phần đầu tiên của tên AZ.
dskrvk

@dskrvk Nếu bạn chỉ cần giữ hai thành phần đầu tiên, làm thế nào để bạn distringuish giữa eu-west-1, eu-west-2eu-west-3(Ngoài ra us-west-1us-west-2) @OP: chỉ cần phù hợp '[a-z][a-z]-[a-z]*-[0-9][0-9]*'dường như an toàn hơn (có nghĩa là một regex cơ bản, nó có thể được thực hiện ngắn hơn với RE mở rộng). (Regex hiện tại sẽ phá vỡ cakhu vực, afkhu vực và mekhu vực)
Gert van den Berg

15

Dễ nhất tôi tìm thấy cho đến nay

 curl -s 169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/.$//'

1
Điều này có lợi ích không có phụ thuộc không mặc định và nó chỉ là một dòng duy nhất.
Mark Stosberg

14

rất đơn giản

export AVAILABILITY_ZONE=`wget -qO- http://instance-data/latest/meta-data/placement/availability-zone`
export REGION_ID=${AVAILABILITY_ZONE:0:${#AVAILABILITY_ZONE} - 1}

4
Đó là hai dòng
Christian

1
Nhưng điều này không hoạt động trên khu vực phía tây-1 của chúng tôi. Trả về curl: (6) Could not resolve host: instance-data; Name or service not knownlỗi.
SK Venkat

1
@SKVenkat Điều đó có khả năng liên quan đến cài đặt DNS của VPC của bạn ... Sử dụng IP cho siêu dữ liệu-api có vẻ an toàn hơn (một nửa trong số các câu trả lời khác làm điều đó)
Gert van den Berg

@GertvandenBerg, tôi thứ hai ..
SK Venkat

9

Nếu bạn đã cài đặt jq , bạn cũng có thể thực hiện theo cách này (có thể là phương pháp "duyên dáng" nhất) theo cách này:

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -c -r .region

Điều này chỉ đơn giản trả về giá trị thô của "vùng" mà không có bất kỳ định dạng in đẹp hoặc định dạng nào khác. Tham khảo: Diễn đàn AWS


7

Lấy khu vực từ vùng sẵn có, loại bỏ chữ cái cuối cùng của nó.

ec2-metadata -z | awk '{print $2}' | sed 's/[a-z]$//'

6

Sử dụng JQ:

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region


4

Đây là giải pháp sạch nhất tôi tìm thấy:

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document |sed -n 's/  "region" : "\(.*\)"/\1/p'

Ví dụ,

export REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document |sed -n 's/  "region" : "\(.*\)"/\1/p')

  • Không thực hiện cuộc gọi API, sử dụng dữ liệu meta của thể hiện EC2
  • Chỉ sử dụng curl và sed cơ bản, vì vậy không phụ thuộc vào SDK hoặc công cụ không có khả năng được cài đặt.
  • Không cố phân tích tên Vùng khả dụng, do đó, không phải lo lắng nếu AWS thay đổi định dạng tên AZ / Vùng

Đúng, cảm ơn. Kết quả này có thể dễ dàng được khử lưu huỳnh thành một đối tượng json.
Dynamiclynk

Tôi đang nhận được một dấu phẩy ở cuối.
Craig

4

Cảm ơn https://unix.stackexchange.com/a/144330/135640 , với bash 4.2+, chúng tôi chỉ có thể tách char cuối cùng khỏi vùng khả dụng:

$ region=`curl -s 169.254.169.254/latest/meta-data/placement/availability-zone`
$ region=${region::-1}
$ echo $region
us-east-1

Điều này giả định AWS tiếp tục sử dụng một ký tự cho các vùng khả dụng được gắn vào khu vực.


5
Chúng tôi luôn có thể lột bỏ nhân vật cuối cùng trong vỏ:region=${region%?}
David Jones

4

2 lớp lót hoạt động miễn là bạn đang sử dụng ec2.iternal làm miền tìm kiếm của bạn:

az=$(curl -s http://instance-data/latest/meta-data/placement/availability-zone)
region=${az:0:${#az} - 1}

4

Đối với bất cứ ai muốn làm điều này với ol powershell tốt

$var = (curl http://169.254.169.254/latest/dynamic/instance-identity/document | Select-String-Pattern "Zone" | ConvertFrom-Json | Select-Object -ExpandProperty "region")
echo $var

3

Hoặc không làm cho Ubuntu hoặc công cụ này là một yêu cầu và chỉ cần làm:

: "${EBS_VOLUME_AVAILABILITY_ZONE:=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)}"
: ${EBS_VOLUME_REGION:="${EBS_VOLUME_AVAILABILITY_ZONE%%*([![:digit:]])}"}

2
Lưu ý rằng điều này chỉ hoạt động vì hiện tại vùng khả dụng luôn là tên khu vực có chữ cái viết thường được thêm vào nó (ví dụ: vùng là "us-west-1", vùng là "us-west-1a"). Nếu Amazon từng phá vỡ mô hình này, thì logic ở trên sẽ không còn hoạt động nữa.
Matt Solnit

3

Nếu bạn làm việc với json - sử dụng đúng công cụ. jq mạnh mẽ trong trường hợp này.

# curl -s curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r '.region'
eu-west-1

3

Điều này hoạt động cho eu-trung tâm-1 cũng như các khu vực chữ cái khác nhau. (Tôi không có đủ đại diện để trả lời câu trả lời sed ở trên)

ec2-metadata --availability-zone | sed 's/[a-z]$//'

Nó phải là ec2metadata --availability-zone | sed 's/.$//'(không có dấu gạch ngang)
Vladimir Kondratyev

3

Nếu bạn đang chạy trên windows, bạn có thể sử dụng quyền hạn này:

$region=(Invoke-RestMethod "http://169.254.169.254/latest/dynamic/instance-identity/document").region

1

Cũng đang tìm kiếm một giải pháp để tìm khu vực từ ví dụ và đây là giải pháp Bash thuần túy của tôi:

az=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
region=${az:0:${#az}-1}

trừ khi có những vùng mà AZ có nhiều hơn hai chữ cái mà tôi không biết.


0

Để tìm hiểu thông tin về EC2 mà bạn đã đăng nhập, bạn có thể sử dụng công cụ siêu dữ liệu ec2.

Bạn có thể cài đặt công cụ bằng cách theo liên kết này. Sau khi cài đặt công cụ, bạn có thể chạy

# ec2-metadata -z

để tìm ra khu vực.

Công cụ này được cài đặt với Ubuntu AMIs mới nhất (10.10),


4
Điều này là không đúng. ec2-metadata -zChỉ hiển thị vùng sẵn có, không phải khu vực.
Matt Solnit

0

Nếu bạn đang tìm kiếm để có được khu vực bằng cách sử dụng JS, điều này sẽ hoạt động:

meta.request("/latest/meta-data/placement/availability-zone",function(err,data){
        if(err)
                console.log(err);
        else{
                console.log(data);
                str = data.substring(0, data.length - 1);
                AWS.config.update({region:str});
                ec2 = new AWS.EC2();
            }
     });

Đây là ánh xạ được tìm thấy từ AWS DOCS, để đáp lại lệnh gọi API siêu dữ liệu, chỉ cần cắt bớt ký tự cuối cùng sẽ hoạt động.

  eu-west-1a :eu-west-1
  eu-west-1b :eu-west-1
  eu-west-1c :eu-west-1
  us-east-1a :us-east-1
  us-east-1b :us-east-1
  us-east-1c :us-east-1
  us-east-1d :us-east-1
  ap-northeast-1a :ap-northeast-1
  ap-northeast-1b :ap-northeast-1
  us-west-1a :us-west-1
  us-west-1b :us-west-1
  us-west-1c :us-west-1
  ap-southeast-1a :ap-southeast-1
  ap-southeast-1b :ap-southeast-1

0

ec2metadata(không có dấu gạch ngang) là lệnh hiện tại để cung cấp cho bạn tất cả thông tin lưu trữ aws về hộp ec2 của bạn. đây là cách tiếp cận thanh lịch và an toàn nhất ( ec2-metadatalà lệnh cũ, không còn hợp lệ.)


Điều này có thể phụ thuộc vào loại hộp ảo bạn đã chọn. Tôi gắn bó với Linux.
GViz

0

Một phương thức chỉ sử dụng egrep, sẽ hoạt động trên hầu hết mọi phiên bản linux xuất hiện mà không phải cài đặt bất kỳ công cụ bổ sung nào. Tôi đã thử nghiệm điều này với một danh sách tất cả các khu vực AWS hiện tại và tất cả chúng đều khớp.

curl http://169.254.169.254/latest/meta-data/placement/availability-zone | egrep -o '(\w)+-(\w)+-[0-9]'

Giải thích về REGEX:

  • "(\ w) +" Điều này khớp với bất kỳ số lượng chữ cái nào
  • "-" chỉ khớp với một dấu gạch ngang
  • "[0-9]" khớp với bất kỳ 1 số nào

Nếu bạn muốn điều này thành một biến, hãy làm:

region=$(curl http://169.254.169.254/latest/meta-data/placement/availability-zone | egrep -o '(\w)+-(\w)+-[0-9]')


0

Đối với giải pháp sed và curl, có vẻ như định dạng đã thay đổi một chút. Đối với tôi làm việc

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | sed -n 's/ "region" : "\(.*\)"[,]/\1/p'

0

Tại một số điểm vì hầu hết các câu trả lời này đã được đăng, AWS đã làm điều hợp lý và thực hiện một đường dẫn mới : latest/meta-data/placement/region.

Điều này có nghĩa là có được khu vực nên đơn giản như

REGION="$(wget -q -O - http://169.254.169.254/latest/meta-data/placement/region)"

0

Bạn có thể nhận được khu vực ví dụ bằng cách sử dụng yêu cầu curl này

$ curl http://169.254.169.254/latest/meta-data/placement/region
us-east-1
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.