Temukan wilayah dari dalam instance EC2


131

Apakah ada cara untuk mencari wilayah instance dari dalam instance?

Saya mencari sesuatu yang mirip dengan metode menemukan instance id .


1
kemungkinan duplikat dari Cari tahu id instan dari dalam mesin EC2
Hingga

8
Jawaban singkat untuk siapa saja yang tidak peduli dengan semua skrip shell: dapatkan zona ketersediaan dari http://169.254.169.254/latest/meta-data/placement/availability-zonedan hapus karakter terakhir.
Sarsaparilla

Jawaban:


147

URL itu ( http://169.254.169.254/latest/dynamic/instance-identity/document ) tampaknya tidak berfungsi lagi. Saya mendapatkan 404 ketika saya mencoba menggunakannya. Saya memiliki kode berikut yang tampaknya berfungsi:

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]$//'`"

Semoga ini membantu.

EDIT: Ditingkatkan sedberdasarkan komentar


4
Ini harus dijalankan di dalam instance EC2 dan didukung oleh backend AWS. Ini tidak akan berfungsi di tempat lain (pada dasarnya karena IP itu adalah APIPA). Juga tidak ada cara untuk mendapatkan informasi ini secara langsung dari dalam instance tanpa menghubungkan ke sumber metadata. Ini mengasumsikan bahwa API 169.254.169.254 tersedia, dan skrip Anda harus menangani kegagalan jaringan. ec2-metadatahanyalah pembungkus untuk API ini, tetapi pada dasarnya melakukan hal yang sama.
dannosaur

1
Apakah ini sesuatu yang didokumentasikan? Bisakah Anda jelaskan bagaimana Anda menemukannya?
meawoppl

2
Dalam semua kejujuran ketika saya datang dengan 2-liner saya hanya menyodok tentang API mencari apa pun yang bisa saya gunakan untuk mengidentifikasi daerah yang benar. API metadata AWS sepenuhnya didokumentasikan di sini: docs.aws.amazon.com/AWSEC2/latest/UserGuide/…
dannosaur

12
Jauh lebih sederhana daripada mengganti perintah daripada yang disediakan untuk EC2_REGION:sed 's/[a-z]$//
threejeez

2
Jika ini dalam skrip boots, layanan metadata mungkin belum dipakai - jika demikian, tunggu dan coba lagi. Saya telah melihatnya butuh 10-15 detik setelah boot untuk lokasi metadata tersedia.
vacri

81

Ada satu cara lagi untuk mencapai itu:

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

echo $REGION

us-east-1

Haruskah ini bekerja di wilayah / az (dan pada AMI apa pun)? Saya sedang 404 - Not Foundmencoba GETURL itu dari mesin di us-east-1a.
Adam Monsen

@AdamMonsen mungkin itu adalah kesalahan sementara. Saya di us-east-1a dan itu bekerja dengan baik.
Florin Andrei

Terima kasih @FlorinAndrei. Bekerja untuk saya sekarang juga.
Adam Monsen

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

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

38

Jika Anda setuju menggunakan jq, Anda dapat menjalankan yang berikut:

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

Saya kira itu cara terbersih.


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

Untuk sistem berbasis debian, perintahnya adalah tanpa tanda hubung.

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

6
Dapatkan string murni hanya dengan nama wilayah:ec2-metadata --availability-zone | sed 's/placement: \(.*\).$/\1/'
nahsh

ec2-metadatatampaknya tidak menjadi sesuatu yang tersedia secara default - dapatkah Anda memasukkan instruksi instalasi?
Tim Malone

23

Jika Anda ingin menghindari ekspresi reguler, berikut adalah satu-liner yang dapat Anda lakukan dengan 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']"

Jawaban ini harus lebih tinggi!
Kostas Demiris

@KostasDemiris Saya setuju, lebih suka membaca nilai dari struktur JSON daripada ekspresi reguler.
lasec0203

1
Saya setuju ini tampaknya menjadi cara terbaik untuk melakukannya jika Anda tidak menginstal jq. Anda benar-benar berharap AWS akan mengekspos ini sebagai sesuatu seperti 169.254.169.254/latest/meta-data/placement/region ...
Krenair

17

Anda dapat menggunakan ec2-metadata:

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

2
Dengan ini, jika Anda di dalam eu-central-1Anda sedang kacau.
dannosaur

2
centraltidak ada ketika saya awalnya menulis jawaban saya. Sudah ditambahkan sekarang.
Daniel Kuppitz

22
Sebuah skrip yang rusak setiap kali AWS menambahkan wilayah baru sepertinya bukan solusi yang sangat kuat, bagi saya.
Ryan B. Lynch

1
Alih-alih grep, awk '{split($2,arr,"-"); print arr[1]"-"arr[2]}'hanya akan menyimpan dua komponen pertama dari nama AZ.
dskrvk

@dskrvk Jika Anda hanya menyimpan dua komponen pertama, bagaimana Anda membedakan antara eu-west-1, eu-west-2dan eu-west-3(Juga us-west-1dan us-west-2) @OP: hanya mencocokkan '[a-z][a-z]-[a-z]*-[0-9][0-9]*'tampaknya lebih aman (itu adalah regex dasar, itu dapat dibuat lebih pendek dengan RE diperpanjang). (Regex saat ini akan menembus cawilayah, wilayah, afdan mewilayah)
Gert van den Berg

15

Paling mudah saya temukan sejauh ini

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

1
Ini memiliki manfaat tidak ada dependensi non-default dan hanya satu baris.
Mark Stosberg

14

sangat sederhana satu liner

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

4
Itu dua baris
Christian

1
Tapi ini tidak berfungsi di wilayah us-west-1. Pengembalian curl: (6) Could not resolve host: instance-data; Name or service not knownkesalahan.
SK Venkat

1
@SKVenkat Itu kemungkinan terkait dengan pengaturan DNS VPC Anda ... Menggunakan IP untuk metadata-api tampaknya lebih aman (setengah dari jawaban lain melakukannya)
Gert van den Berg

@GertvandenBerg, saya yang kedua ..
SK Venkat

9

Jika Anda telah menginstal jq , Anda juga dapat melakukannya (mungkin metode yang paling "anggun") dengan cara ini:

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

Ini hanya mengembalikan nilai mentah "wilayah" tanpa pencetakan cantik atau format lainnya. Referensi: Forum AWS


7

Dapatkan wilayah dari zona ketersediaan, lepaskan huruf terakhirnya.

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

6

Gunakan JQ:

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


4

Ini adalah solusi terbersih yang saya temukan:

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

Misalnya,

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

  • Tidak melakukan panggilan API, menggunakan meta-data instance EC2
  • Hanya menggunakan curl, dan sed dasar, jadi tidak ada ketergantungan pada SDK atau alat yang tidak mungkin dipasang.
  • Tidak mencoba mem-parsing nama Zona Ketersediaan, jadi jangan khawatir jika AWS mengubah format nama AZ / Wilayah

Yap sempurna, terima kasih. Hasil ini dapat dengan mudah deserialized menjadi objek json.
dynamiclynk

Saya mendapatkan koma di akhir.
Craig

4

Berkat https://unix.stackexchange.com/a/144330/135640 , dengan bash 4.2+ kami hanya dapat menghapus karakter terakhir dari zona ketersediaan:

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

Ini mengasumsikan AWS terus menggunakan satu karakter untuk zona ketersediaan ditambahkan ke wilayah tersebut.


5
Kami selalu dapat menghapus karakter terakhir di shell:region=${region%?}
David Jones

4

2 liner yang berfungsi selama Anda menggunakan ec2.internal sebagai domain pencarian Anda:

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

4

Bagi siapa pun yang ingin melakukan ini dengan PowerShell yang baik

$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

Atau jangan menjadikan Ubuntu atau alat ini persyaratan dan cukup lakukan:

: "${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
Perhatikan bahwa ini hanya berfungsi karena saat ini zona ketersediaan selalu merupakan nama kawasan dengan huruf kecil ditambahkan ke dalamnya (mis. Wilayah adalah "us-west-1", zone adalah "us-west-1a"). Jika Amazon pernah mematahkan pola ini, maka logika di atas tidak akan lagi berfungsi.
Matt Solnit

3

Jika Anda bekerja dengan json - gunakan alat yang tepat. jq jauh lebih kuat dalam hal ini.

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

3

Ini berfungsi untuk eu-central-1 serta berbagai zona huruf. (Saya tidak punya cukup perwakilan untuk membalas jawaban sed di atas)

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

Seharusnya ec2metadata --availability-zone | sed 's/.$//'(tanpa tanda hubung)
Vladimir Kondratyev

3

Jika Anda menjalankan di windows, Anda dapat menggunakan powershell one-liner ini:

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

1

Sedang mencari solusi untuk menemukan wilayah dari instance dan di sini adalah solusi Bash murni saya:

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

kecuali ada daerah di mana AZ memiliki lebih dari dua huruf, yang saya tidak sadari.


0

Untuk mengetahui informasi tentang EC2 yang Anda masuki, Anda dapat menggunakan alat ec2-metadata.

Anda dapat menginstal alat dengan mengikuti tautan ini. Setelah menginstal alat, Anda dapat menjalankan

# ec2-metadata -z

untuk mengetahui wilayah tersebut.

Alat ini diinstal dengan AMI Ubuntu terbaru (10,10),


4
Ini salah. ec2-metadata -zhanya menunjukkan zona ketersediaan, bukan wilayah.
Matt Solnit

0

Jika Anda ingin mendapatkan wilayah menggunakan JS, ini harusnya berfungsi:

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();
            }
     });

Ini adalah pemetaan yang ditemukan dari AWS DOCS, sebagai respons terhadap panggilan API metadata, cukup pangkas karakter terakhir yang seharusnya berfungsi.

  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(no dash) adalah perintah saat ini untuk memberikan Anda semua info hosting aws tentang kotak EC2 Anda. ini adalah pendekatan yang paling elegan dan aman. ( ec2-metadataadalah perintah lama, tidak lagi valid.)


Ini bisa bergantung pada jenis kotak virtual yang Anda pilih. Saya tetap menggunakan Linux.
GViz

0

Metode yang hanya menggunakan egrep, yang seharusnya bisa digunakan pada kebanyakan instance linux yang berputar tanpa harus menginstal tooling tambahan apa pun. Saya menguji ini terhadap daftar semua wilayah AWS saat ini dan semuanya cocok.

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

Penjelasan dari REGEX:

  • "(\ w) +" Ini cocok dengan sejumlah huruf apa pun
  • "-" hanya cocok dengan satu tanda hubung
  • "[0-9]" cocok dengan 1 angka

Jika Anda ingin ini menjadi variabel lakukan:

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


0

Untuk solusi sed dan curl sepertinya format telah sedikit berubah. Bagi saya bekerja

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

0

Pada titik tertentu karena sebagian besar jawaban ini telah diposting, AWS melakukan hal yang masuk akal dan menerapkan jalur baru: latest/meta-data/placement/region .

Ini berarti mendapatkan wilayah harus sesederhana

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

0

Anda mungkin mendapatkan wilayah contoh menggunakan permintaan ikal ini

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