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


131

มีวิธีค้นหาพื้นที่ของอินสแตนซ์จากภายในอินสแตนซ์หรือไม่

ฉันกำลังมองหาสิ่งที่คล้ายกับวิธีการหารหัสอินสแตนซ์



8
คำตอบสั้น ๆ สำหรับผู้ที่ไม่สนใจเชลล์สคริปต์ทั้งหมด: รับโซนความพร้อมใช้งานhttp://169.254.169.254/latest/meta-data/placement/availability-zoneและลบอักขระสุดท้าย
Sarsaparilla


สำหรับผู้ที่อ่านโพสต์กลางปี ​​2020 คุณสามารถใช้http://169.254.169.254/latest/meta-data/placement/region
d4nyll เมื่อ

คำตอบ:


148

URL นั้น ( http://169.254.169.254/latest/dynamic/instance-identity/document ) ไม่ทำงานอีกต่อไป ฉันได้รับ 404 เมื่อฉันพยายามใช้มัน ฉันมีรหัสต่อไปนี้ซึ่งดูเหมือนจะใช้งานได้:

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

หวังว่านี่จะช่วยได้

แก้ไข:ปรับปรุงsedตามความคิดเห็น


4
สิ่งนี้จะทำงานภายในอินสแตนซ์ EC2 และขับเคลื่อนโดยแบ็กเอนด์ของ AWS มันจะไม่ทำงานที่อื่น (โดยพื้นฐานแล้วเนื่องจาก IP นั้นเป็น APIPA) นอกจากนี้ยังไม่มีวิธีรับข้อมูลนี้โดยตรงจากภายในอินสแตนซ์โดยไม่ต้องเชื่อมต่อกับแหล่งข้อมูลเมตา สิ่งนี้ถือว่า 169.254.169.254 API พร้อมใช้งานและสคริปต์ของคุณควรจัดการกับความล้มเหลวของเครือข่ายตามนั้น ec2-metadataเป็นเพียง Wrapper สำหรับ API นี้ แต่โดยพื้นฐานแล้วจะทำสิ่งเดียวกัน
dannosaur

1
นี่เป็นเอกสารหรือไม่? คุณสามารถอธิบายว่าคุณพบมันได้อย่างไร?
meawoppl

2
ด้วยความสัตย์จริงทั้งหมดเมื่อฉันสร้าง 2 ซับฉันแค่จิ้มเกี่ยวกับ API เพื่อค้นหาสิ่งที่ฉันสามารถใช้เพื่อระบุภูมิภาคที่ถูกต้อง API ข้อมูลเมตาของ AWS มีเอกสารครบถ้วนที่นี่: docs.aws.amazon.com/AWSEC2/latest/UserGuide/…
dannosaur

12
คำสั่ง sed แทนที่ง่ายกว่าคำสั่งที่ให้ไว้สำหรับ EC2_REGION:sed 's/[a-z]$//
threejeez

2
หากสิ่งนี้อยู่ใน bootscript บริการข้อมูลเมตาอาจยังไม่ได้รับการสร้างอินสแตนซ์หากเป็นเช่นนั้นให้รอและลองอีกครั้ง ฉันเคยเห็นว่าใช้เวลา 10-15 วินาทีหลังจากบูตเพื่อให้ตำแหน่งข้อมูลเมตาพร้อมใช้งาน
vacri

81

มีอีกวิธีหนึ่งในการบรรลุเป้าหมายดังกล่าว:

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

echo $REGION

us-east-1

สิ่งนี้ควรทำงานในภูมิภาค / az (และใน AMI ใด ๆ ) หรือไม่ ฉันได้รับ404 - Not Foundการพยายามที่จะGETURL us-east-1aที่จากเครื่องใน
Adam Monsen

@AdamMonsen อาจเป็นข้อผิดพลาดชั่วคราว ฉันอยู่ที่ us-east-1a และใช้งานได้ดี
Florin Andrei

ขอบคุณ @FlorinAndrei ใช้ได้ผลกับฉันด้วย
Adam Monsen

3
ด้วย jq:curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region
Yaron

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

38

หากคุณพอใจกับการใช้jqงานคุณสามารถเรียกใช้สิ่งต่อไปนี้:

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

ฉันเดาว่ามันเป็นวิธีที่สะอาดที่สุด


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

สำหรับระบบที่ใช้เดเบียนคำสั่งจะไม่มีเส้นประ

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

6
รับสตริงบริสุทธิ์ที่มีเฉพาะชื่อภูมิภาค:ec2-metadata --availability-zone | sed 's/placement: \(.*\).$/\1/'
nahsh

ec2-metadataดูเหมือนจะไม่ใช่สิ่งที่มีให้โดยค่าเริ่มต้นคุณสามารถใส่คำแนะนำในการติดตั้งได้หรือไม่
Tim Malone

23

หากคุณต้องการหลีกเลี่ยงนิพจน์ทั่วไปนี่คือหนึ่งซับที่คุณสามารถทำได้กับ 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']"

คำตอบนี้ควรจะสูงกว่านี้!
Kostas Demiris

@KostasDemiris ฉันเห็นด้วยค่อนข้างอ่านค่าจากโครงสร้าง JSON มากกว่านิพจน์ทั่วไป
lasec0203

1
ฉันยอมรับว่านี่เป็นวิธีที่ดีที่สุดหากคุณไม่ได้ติดตั้ง jq คุณคงคาดหวังว่า AWS จะเปิดเผยสิ่งนี้เป็น169.254.169.254/latest/meta-data/placement/region ...
Krenair

17

คุณสามารถใช้ ec2-metadata:

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

2
ด้วยสิ่งนี้หากeu-central-1คุณกำลังเมา
dannosaur

2
centralไม่มีอยู่ตอนแรกที่ฉันเขียนคำตอบ เพิ่มแล้ว
Daniel Kuppitz

22
สคริปต์ที่พังทุกครั้งที่ AWS เพิ่มภูมิภาคใหม่ดูเหมือนจะไม่ใช่วิธีแก้ปัญหาที่แข็งแกร่งเป็นพิเศษสำหรับฉัน
Ryan B. Lynch

1
แทนที่จะเป็น grep awk '{split($2,arr,"-"); print arr[1]"-"arr[2]}'จะเก็บไว้เพียงสององค์ประกอบแรกของชื่อ AZ
dskrvk

@dskrvk หากคุณเพียงแค่ให้ส่วนประกอบที่สองครั้งแรกที่คุณจะทำอย่างไรระหว่าง distringuish eu-west-1, eu-west-2และeu-west-3(นอกจากนี้us-west-1และus-west-2) @OP: เพียงแค่การจับคู่'[a-z][a-z]-[a-z]*-[0-9][0-9]*'ดูเหมือนว่าปลอดภัยมากขึ้น (นั่นคือ regex พื้นฐานก็สามารถทำสั้นกับ RE ขยาย) (regex ปัจจุบันจะแตกในcaภูมิภาคafภูมิภาคและmeภูมิภาค)
Gert van den Berg

15

ง่ายที่สุดที่ฉันพบจนถึงตอนนี้

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

1
สิ่งนี้มีประโยชน์ของการไม่มีการอ้างอิงที่ไม่ใช่ค่าเริ่มต้นและเป็นเพียงบรรทัดเดียว
Mark Stosberg

14

ง่ายมากหนึ่งซับ

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

4
นั่นคือสองบรรทัด
Christian

1
แต่สิ่งนี้ใช้ไม่ได้กับภูมิภาค us-west-1 ส่งกลับcurl: (6) Could not resolve host: instance-data; Name or service not knownข้อผิดพลาด
SK Venkat

1
@SKVenkat ที่น่าจะเกี่ยวข้องกับการตั้งค่า DNS ของ VPC ของคุณ ... การใช้ IP สำหรับ metadata-api ดูเหมือนจะปลอดภัยกว่า (คำตอบอื่น ๆ ครึ่งหนึ่งทำเช่นนั้น)
Gert van den Berg

@GertvandenBerg ฉันสองมัน ..
SK Venkat

9

หากคุณติดตั้งjqคุณสามารถใช้วิธีนี้ (อาจเป็นวิธีที่ "สง่างาม" ที่สุด) ด้วยวิธีนี้:

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

สิ่งนี้จะส่งคืนค่าดิบของ "ภูมิภาค" โดยไม่ต้องพิมพ์สวยหรือจัดรูปแบบอื่น ๆ ข้อมูลอ้างอิง: AWS Forum


7

รับภูมิภาคจากโซนความพร้อมใช้งานตัดตัวอักษรตัวสุดท้ายออก

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



4

นี่เป็นวิธีที่สะอาดที่สุดที่ฉันพบ:

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

เช่น,

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

  • ไม่ทำการเรียก API ใช้ข้อมูลเมตาอินสแตนซ์ EC2
  • ใช้เฉพาะ curl และ sed ขั้นพื้นฐานดังนั้นจึงไม่มีการพึ่งพา SDK หรือเครื่องมือที่ไม่น่าจะติดตั้ง
  • ไม่พยายามแยกวิเคราะห์ชื่อ Availability Zone จึงไม่ต้องกังวลหาก AWS เปลี่ยนรูปแบบชื่อ AZ / ภูมิภาค

ใช่สมบูรณ์ขอบคุณ ผลลัพธ์นี้สามารถ deserialized ลงในวัตถุ json ได้อย่างง่ายดาย
dynamiclynk

ฉันได้รับเครื่องหมายจุลภาคในตอนท้าย
Craig

4

ขอบคุณhttps://unix.stackexchange.com/a/144330/135640ด้วย bash 4.2+ เราสามารถถอดถ่านตัวสุดท้ายออกจากโซนว่าง:

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

สิ่งนี้ถือว่า AWS ยังคงใช้อักขระตัวเดียวสำหรับโซนความพร้อมใช้งานที่ต่อท้ายภูมิภาค


5
เราสามารถถอดตัวละครสุดท้ายออกจากเปลือกได้เสมอ:region=${region%?}
David Jones

4

2 ซับที่ใช้งานได้ตราบเท่าที่คุณใช้ ec2.internal เป็นโดเมนการค้นหาของคุณ:

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

4

สำหรับใครก็ตามที่ต้องการทำสิ่งนี้ด้วย ol powershell ที่ดี

$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

หรืออย่าทำให้ Ubuntu หรือเครื่องมือนี้เป็นข้อกำหนดและทำ:

: "${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
โปรดทราบว่าสิ่งนี้ใช้ได้เฉพาะเนื่องจากในขณะนี้โซนความพร้อมใช้งานจะเป็นชื่อภูมิภาคที่มีตัวอักษรตัวพิมพ์เล็กต่อท้ายเสมอ (เช่นภูมิภาคคือ "us-west-1" โซนคือ "us-west-1a") หาก Amazon เคยทำลายรูปแบบนี้ตรรกะข้างต้นจะไม่ทำงานอีกต่อไป
Matt Solnit

3

หากคุณทำงานกับ json - ใช้เครื่องมือที่เหมาะสม jq มีประสิทธิภาพมากในกรณีนี้

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

3

ใช้งานได้กับ eu-central-1 เช่นเดียวกับโซนตัวอักษรต่างๆ (ฉันมีตัวแทนไม่เพียงพอที่จะตอบกลับคำตอบด้านบน)

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

ควรจะเป็นec2metadata --availability-zone | sed 's/.$//'(ไม่มีเส้นประ)
Vladimir Kondratyev

3

หากคุณใช้ Windows คุณสามารถใช้ PowerShell one-Liner:

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

1

กำลังมองหาวิธีแก้ปัญหาเพื่อค้นหาภูมิภาคจากอินสแตนซ์และนี่คือโซลูชัน Bash ที่แท้จริงของฉัน:

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

เว้นแต่จะมีภูมิภาคที่ AZ มีตัวอักษรมากกว่าสองตัวซึ่งฉันไม่ทราบ


1

เมื่อถึงจุดหนึ่งเนื่องจากมีการโพสต์คำตอบเหล่านี้ส่วนใหญ่ AWS ได้ทำสิ่งที่สมเหตุสมผลและใช้เส้นทางใหม่: latest/meta-data/placement/regionทำสิ่งที่เหมาะสมและดำเนินการเส้นทางใหม่:

ซึ่งหมายความว่าการรับภูมิภาคควรจะง่ายพอ ๆ

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

0

สำหรับการค้นหาข้อมูลเกี่ยวกับ EC2 ที่คุณลงชื่อเข้าใช้คุณสามารถใช้เครื่องมือ ec2-metadata

คุณสามารถติดตั้งเครื่องมือได้ตามลิงค์นี้ หลังจากติดตั้งเครื่องมือคุณสามารถเรียกใช้

# ec2-metadata -z

เพื่อค้นหาภูมิภาค

เครื่องมือนี้มาพร้อมกับ Ubuntu AMI ล่าสุด (10.10)


4
สิ่งนี้ไม่ถูกต้อง ec2-metadata -zแสดงเฉพาะโซนความพร้อมใช้งานไม่ใช่ภูมิภาค
Matt Solnit

0

หากคุณต้องการรับภูมิภาคโดยใช้ JS สิ่งนี้ควรได้ผล:

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

นี่คือการแมปที่พบจาก AWS DOCS เพื่อตอบสนองต่อการเรียก API ข้อมูลเมตาเพียงแค่ตัดทอนอักขระสุดท้ายก็น่าจะใช้ได้

  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(ไม่มีเส้นประ) เป็นคำสั่งปัจจุบันเพื่อให้ข้อมูลโฮสติ้ง aws เกี่ยวกับกล่อง ec2 ของคุณ นี่คือแนวทางที่สง่างามและปลอดภัยที่สุด ( ec2-metadataเป็นคำสั่งเก่าที่ไม่ถูกต้องอีกต่อไป)


สิ่งนี้อาจขึ้นอยู่กับประเภทกล่องเสมือนที่คุณเลือก ฉันติดลินุกซ์
GViz

0

วิธีการที่ใช้เฉพาะ egrep ซึ่งควรใช้ได้กับอินสแตนซ์ linux ส่วนใหญ่ที่หมุนโดยไม่ต้องติดตั้งเครื่องมือเพิ่มเติมใด ๆ ฉันทดสอบสิ่งนี้กับรายการของภูมิภาค AWS ปัจจุบันทั้งหมดและทั้งหมดตรงกัน

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

คำอธิบายของ REGEX:

  • "(\ w) +" ตรงกับตัวอักษรจำนวนเท่าใดก็ได้
  • "-" จะจับคู่เพียงขีดเดียว
  • "[0-9]" จะจับคู่หมายเลขใดก็ได้

หากคุณต้องการให้สิ่งนี้เป็นตัวแปรทำ:

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


0

สำหรับโซลูชัน sed และ curl ดูเหมือนว่ารูปแบบจะเปลี่ยนไปเล็กน้อย สำหรับฉันได้ผล

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

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