Znajdź region z poziomu instancji EC2


136

Czy istnieje sposób na wyszukanie regionu instancji z poziomu instancji?

Szukam czegoś podobnego do metody znajdowania identyfikatora instancji .



9
Krótka odpowiedź dla każdego, kto nie przejmuje się wszystkimi skryptami powłoki: pobierz strefę dostępności z http://169.254.169.254/latest/meta-data/placement/availability-zonei usuń ostatni znak.
Sarsaparilla


2
Dla tych, którzy czytają post w połowie 2020 roku, możesz teraz użyćhttp://169.254.169.254/latest/meta-data/placement/region
d4nyll

Odpowiedzi:


152

Ten adres URL ( http://169.254.169.254/latest/dynamic/instance-identity/document ) już nie działa. Otrzymuję kod 404, gdy próbowałem go użyć. Mam następujący kod, który jednak wydaje się działać:

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

Mam nadzieję że to pomoże.

EDYCJA: Ulepszona sedna podstawie komentarzy


4
Ma to zostać uruchomione wewnątrz instancji EC2 i jest zasilane przez backendy AWS. Nie będzie działać nigdzie indziej (zasadniczo dlatego, że ten adres IP to APIPA). Nie ma również możliwości uzyskania tych informacji bezpośrednio z wnętrza instancji bez połączenia ze źródłem metadanych. Zakłada się, że interfejs API 169.254.169.254 jest dostępny, a skrypt powinien odpowiednio obsługiwać awarie sieci. ec2-metadatajest tylko opakowaniem tego interfejsu API, ale zasadniczo robi to samo.
dannosaur

1
Czy to jest coś udokumentowanego? Czy możesz wyjaśnić, jak to znalazłeś?
meawoppl

2
Szczerze mówiąc, kiedy wymyśliłem ten 2-liniowy, właśnie grzebałem w API szukając czegokolwiek, co mógłbym użyć do zidentyfikowania właściwego regionu. Interfejs API metadanych AWS jest w pełni udokumentowany tutaj: docs.aws.amazon.com/AWSEC2/latest/UserGuide/ ...
dannosaur

12
Znacznie prostsza komenda zamiany seda niż ta przewidziana dla EC2_REGION:sed 's/[a-z]$//
threejeez

2
Jeśli jest to w skrypcie startowym, może nie zostać jeszcze utworzona instancja usługi metadanych - jeśli tak, poczekaj i spróbuj ponownie. Widziałem, że lokalizacja metadanych staje się dostępna po 10-15 sekundach od uruchomienia.
vacri

83

Jest jeszcze jeden sposób, aby to osiągnąć:

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

echo $REGION

us-east-1

Czy to powinno działać w dowolnym regionie / az (i na dowolnym AMI)? Dostaję 404 - Not Foundpróbuje GETtego adresu URL z automatu w us-east-1a.
Adam Monsen,

@AdamMonsen być może był to przejściowy błąd. Jestem na us-east-1a i działa świetnie.
Florin Andrei

Dzięki @FlorinAndrei. U mnie też teraz działa.
Adam Monsen

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

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

40

Jeśli nie przeszkadza Ci używanie jq, możesz uruchomić:

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

Myślę, że to najczystszy sposób.


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

W przypadku systemów opartych na Debianie polecenie jest bez myślnika.

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

6
Zdobądź czysty ciąg z ec2-metadata --availability-zone | sed 's/placement: \(.*\).$/\1/'
samą

ec2-metadatanie wygląda na coś, co jest dostępne domyślnie - czy możesz dołączyć instrukcje dotyczące instalacji?
Tim Malone


23

Jeśli chcesz uniknąć wyrażeń regularnych, oto jedna linijka, którą możesz zrobić w Pythonie:

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

Ta odpowiedź powinna być wyższa!
Kostas Demiris,

@KostasDemiris Zgadzam się, raczej odczytaj wartość ze struktury JSON niż z wyrażenia regularnego.
lasec0203

1
Zgadzam się, że to najlepszy sposób na zrobienie tego, jeśli nie masz zainstalowanego jq. Naprawdę można by oczekiwać, że AWS
ujawni

17

Możesz użyć ec2-metadata:

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

2
Z tym, jeśli jesteś w eu-central-1środku, masz przerąbane.
dannosaur

2
centralnie istniało, kiedy początkowo pisałem odpowiedź. Jest teraz dodany.
Daniel Kuppitz

22
Skrypt, który psuje się za każdym razem, gdy AWS dodaje nowy region, nie wydaje mi się szczególnie mocnym rozwiązaniem.
Ryan B. Lynch

1
Zamiast grep awk '{split($2,arr,"-"); print arr[1]"-"arr[2]}'zachowuje tylko pierwsze dwa składniki nazwy AZ.
dskrvk

@dskrvk Jeśli zachowasz tylko pierwsze dwa składniki, jak rozróżnić pomiędzy eu-west-1, eu-west-2a eu-west-3(także us-west-1i us-west-2) @OP: samo dopasowanie '[a-z][a-z]-[a-z]*-[0-9][0-9]*'wydaje się bezpieczniejsze (to jest podstawowe wyrażenie regularne, można je skrócić za pomocą rozszerzonego RE). (Bieżące wyrażenie regularne zostanie przerwane na caregion, afregiony i meregion)
Gert van den Berg

15

Najłatwiejsze, jakie znalazłem do tej pory

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

1
Ma to tę zaletę, że nie ma żadnych innych niż domyślne zależności i jest to tylko jedna linia.
Mark Stosberg

14

bardzo prosta jedna wkładka

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

6
To dwie linijki
Christian

1
Ale to nie działa w regionie us-west-1. Zwraca curl: (6) Could not resolve host: instance-data; Name or service not knownbłąd.
SK Venkat

1
@SKVenkat Jest to prawdopodobnie związane z ustawieniami DNS twojego VPC ... Używanie adresu IP dla metadata-API wydaje się bezpieczniejsze (połowa innych odpowiedzi tak robi)
Gert van den Berg

9

Jeśli masz zainstalowany jq , możesz to zrobić (prawdopodobnie najbardziej wdzięczna metoda) w ten sposób:

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

Zwraca to po prostu nieprzetworzoną wartość „regionu” bez żadnego ładnego nadruku lub innego formatowania. Źródła: AWS Forum


7

Pobierz region ze strefy dostępności, usuń jego ostatnią literę.

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

6

Użyj JQ:

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


4

To najczystsze rozwiązanie, jakie znalazłem:

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

Na przykład,

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

  • Nie wywołuje API, używa metadanych instancji EC2
  • Używa tylko curl i podstawowego seda, więc nie ma zależności od SDK lub narzędzi, które prawdopodobnie nie zostaną zainstalowane.
  • Nie próbuje analizować nazwy strefy dostępności, więc nie martw się, jeśli AWS zmieni format nazwy AZ / regionu

Tak doskonale, dzięki. Ten wynik można łatwo zdeserializować do obiektu JSON.
dynamiclynk

Na końcu dostaję przecinek.
Craig

4

Dzięki https://unix.stackexchange.com/a/144330/135640 przy bash 4.2+ możemy po prostu usunąć ostatni znak ze strefy dostępności:

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

Zakłada się, że AWS nadal używa jednego znaku dla stref dostępności dołączonych do regionu.


5
Zawsze byliśmy w stanie usunąć ostatnią postać w skorupie:region=${region%?}
David Jones

4

2 liner, który działa tak długo, jak używasz ec2.internal jako domeny wyszukiwania:

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

4

Dla każdego, kto chce to zrobić z dobrym 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

4

W pewnym momencie, ponieważ większość z tych odpowiedzi zostały zamieszczone, AWS zrobił coś rozsądnego i wdrożono nową drogę: latest/meta-data/placement/region.

Oznacza to, że pobranie regionu powinno być tak proste, jak

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

EDYCJA: Warto również wspomnieć, że ten punkt końcowy został udostępniony w wersji API metadanych 2019-10-01. Przed użyciem upewnij się, że Twoja instancja obsługuje tę lub nowszą wersję, zaznaczając http://169.254.169.254/.


3

Lub nie wymagaj Ubuntu lub tego narzędzia i po prostu zrób:

: "${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
Zauważ, że działa to tylko dlatego, że obecnie strefa dostępności jest zawsze nazwą regionu z dołączoną małą literą (np. Region to „us-west-1”, strefa to „us-west-1a”). Jeśli Amazon kiedykolwiek złamie ten wzór, powyższa logika przestanie działać.
Matt Solnit

3

Jeśli pracujesz z json - używaj odpowiednich narzędzi. jq jest w tym przypadku bardzo potężny.

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

3

Działa to dla eu-central-1, jak również dla różnych stref literowych. (Nie mam wystarczającej liczby przedstawicieli, aby odpowiedzieć na powyższą odpowiedź seda)

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

Powinno być ec2metadata --availability-zone | sed 's/.$//'(bez kreski)
Vladimir Kondratyev

3

Jeśli korzystasz z systemu Windows, możesz użyć jednej linijki PowerShell:

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

1

Aby znaleźć informacje o EC2, do którego jesteś zalogowany, możesz skorzystać z narzędzia ec2-metadata.

Narzędzie można zainstalować, korzystając z tego łącza. Po zainstalowaniu narzędzia możesz uruchomić

# ec2-metadata -z

poznać region.

To narzędzie jest instalowane z najnowszym (10.10) systemem AMI Ubuntu,


4
To jest niepoprawne. ec2-metadata -zpokazuje tylko strefę dostępności, a nie region.
Matt Solnit

1

Szukałem również rozwiązania, aby znaleźć region z instancji, a oto moje czyste rozwiązanie Bash:

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

chyba że są regiony, w których AZ ma więcej niż dwie litery, o których nie wiem.


0

Jeśli chcesz uzyskać region za pomocą JS, powinno to działać:

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

To było mapowanie znalezione z AWS DOCS, w odpowiedzi na wywołanie API metadanych, wystarczy przyciąć ostatni znak.

  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(bez myślnika) to bieżące polecenie, które zapewnia wszystkie informacje o hostingu aws dotyczące twojego ec2 box. jest to najbardziej eleganckie i bezpieczne podejście. ( ec2-metadatajest starym, już nieważnym poleceniem).


Może to zależeć od wybranego typu wirtualnego pudełka. Trzymam się Linuksa.
GViz

0

Metoda wykorzystująca tylko egrep, która powinna działać na większości uruchomionych instancji Linuksa bez konieczności instalowania jakichkolwiek dodatkowych narzędzi. Przetestowałem to na liście wszystkich obecnych regionów AWS i wszystkie pasują.

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

Wyjaśnienie REGEX:

  • „(\ w) +” Odpowiada dowolnej liczbie liter
  • „-” odpowiada tylko pojedynczemu myślnikowi
  • „[0-9]” odpowiada dowolnej 1 liczbie

Jeśli chcesz to do zmiennej, wykonaj:

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


0

W przypadku rozwiązań sed i curl wygląda na to, że format nieco się zmienił. U mnie działa

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.