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.