Suchen Sie die Region innerhalb einer EC2-Instanz


131

Gibt es eine Möglichkeit, die Region einer Instanz innerhalb der Instanz nachzuschlagen?

Ich suche nach etwas ähnlichem wie die Methode zum Finden der Instanz-ID .



8
Kurze Antwort für alle, die sich nicht für alle Shell-Skripte interessieren: Rufen Sie die Verfügbarkeitszone ab http://169.254.169.254/latest/meta-data/placement/availability-zoneund entfernen Sie das letzte Zeichen.
Sarsaparilla

Antworten:


147

Diese URL ( http://169.254.169.254/latest/dynamic/instance-identity/document ) scheint nicht mehr zu funktionieren. Ich bekomme eine 404, als ich versuchte, sie zu benutzen. Ich habe den folgenden Code, der jedoch zu funktionieren scheint:

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

Hoffe das hilft.

BEARBEITEN: Verbessert sedbasierend auf Kommentaren


4
Dies soll innerhalb der EC2-Instanz ausgeführt werden und wird von den AWS-Backends unterstützt. Es wird nirgendwo anders funktionieren (im Wesentlichen, weil diese IP eine APIPA ist). Es gibt auch keine Möglichkeit, diese Informationen direkt aus der Instanz abzurufen, ohne eine Verbindung zu einer Metadatenquelle herzustellen. Dies setzt voraus, dass die API 169.254.169.254 verfügbar ist und Ihr Skript Netzwerkfehler entsprechend behandeln sollte. ec2-metadataist nur ein Wrapper für diese API, macht aber im Wesentlichen das Gleiche.
Dannosaurier

1
Ist das etwas dokumentiert? Können Sie erklären, wie Sie es gefunden haben?
Meawoppl

2
Um ehrlich zu sein, als ich diesen 2-Liner entwickelte, stöberte ich nur in der API nach etwas, mit dem ich die richtige Region identifizieren konnte. Die AWS-Metadaten-API ist hier vollständig dokumentiert: docs.aws.amazon.com/AWSEC2/latest/UserGuide/…
dannosaur

12
Viel einfacher sed ersetzungsbefehl als der für die EC2_REGION vorgesehene:sed 's/[a-z]$//
threejeez

2
Wenn dies in einem Bootsskript enthalten ist, wird der Metadatendienst möglicherweise noch nicht instanziiert. Wenn ja, warten Sie und versuchen Sie es erneut. Ich habe gesehen, dass es 10-15 Sekunden nach dem Booten dauert, bis der Metadaten-Speicherort verfügbar ist.
Vacri

81

Es gibt noch einen weiteren Weg, dies zu erreichen:

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

echo $REGION

us-east-1

Sollte dies in einer Region / az (und auf einem AMI) funktionieren? Ich 404 - Not Foundversuche, GETdiese URL von einem Computer in zu erreichen us-east-1a.
Adam Monsen

@AdamMonsen vielleicht war es ein vorübergehender Fehler. Ich bin auf uns-Ost-1a und es funktioniert großartig.
Florin Andrei

Danke @FlorinAndrei. Funktioniert jetzt auch für mich.
Adam Monsen

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

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

38

Wenn Sie mit der Verwendung einverstanden sind jq, können Sie Folgendes ausführen:

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

Ich denke, es ist der sauberste Weg.


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

Bei Debian-basierten Systemen ist der Befehl ohne Bindestrich.

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

6
Holen Sie sich reine Zeichenfolge nur mit dem Namen der Region:ec2-metadata --availability-zone | sed 's/placement: \(.*\).$/\1/'
nahsh

ec2-metadatascheint nicht standardmäßig verfügbar zu sein - können Sie Installationsanweisungen hinzufügen?
Tim Malone

23

Wenn Sie reguläre Ausdrücke vermeiden möchten, können Sie mit Python einen Einzeiler verwenden:

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

Diese Antwort sollte höher sein!
Kostas Demiris

@KostasDemiris Ich stimme zu, lese lieber den Wert aus der JSON-Struktur als einen regulären Ausdruck.
lasec0203

1
Ich bin damit einverstanden, dass dies der beste Weg ist, wenn Sie jq nicht installiert haben. Sie würden wirklich erwarten, dass AWS dies als etwas wie 169.254.169.254/latest/meta-data/placement/region
herausstellt

17

Sie können ec2-Metadaten verwenden:

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

2
Wenn Sie dabei sind, sind eu-central-1Sie fertig.
Dannosaurier

2
centralexistierte nicht, als ich meine Antwort schrieb. Es ist jetzt hinzugefügt.
Daniel Kuppitz

22
Ein Skript, das jedes Mal unterbrochen wird, wenn AWS eine neue Region hinzufügt, scheint mir keine besonders starke Lösung zu sein.
Ryan B. Lynch

1
Anstelle von grep awk '{split($2,arr,"-"); print arr[1]"-"arr[2]}'werden nur die ersten beiden Komponenten des AZ-Namens beibehalten.
dskrvk

@dskrvk Wenn Sie nur die ersten beiden Komponenten halten, wie distringuish Sie zwischen eu-west-1, eu-west-2und eu-west-3(auch us-west-1und us-west-2) @OP: nur passende '[a-z][a-z]-[a-z]*-[0-9][0-9]*'scheint sicherer (die eine grundlegende Regex ist, kann es kürzer mit einem erweiterten RE werden). (Die aktuelle Regex wird für die caRegion, die afRegionen und die meRegion brechen )
Gert van den Berg

15

Am einfachsten fand ich bisher

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

1
Dies hat den Vorteil, dass keine nicht standardmäßigen Abhängigkeiten bestehen und es sich nur um eine einzelne Zeile handelt.
Mark Stosberg

14

sehr einfacher Einzeiler

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

4
Das sind zwei Zeilen
Christian

1
Dies funktioniert jedoch nicht in der Region us-west-1. Gibt einen curl: (6) Could not resolve host: instance-data; Name or service not knownFehler zurück.
SK Venkat

1
@SKVenkat Das hängt wahrscheinlich mit den DNS-Einstellungen Ihrer VPC zusammen ... Die Verwendung der IP für die Metadaten-API scheint sicherer zu sein (die Hälfte der anderen Antworten tut dies)
Gert van den Berg

@GertvandenBerg, ich stimme zu ..
SK Venkat

9

Wenn Sie jq installiert haben, können Sie dies auch folgendermaßen tun (wahrscheinlich die "anmutigste" Methode):

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

Dies gibt einfach den Rohwert von "region" ohne hübschen Druck oder andere Formatierungen zurück. Referenz: AWS Forum


7

Holen Sie sich die Region aus der Verfügbarkeitszone und entfernen Sie den letzten Buchstaben.

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

6

Verwenden Sie JQ:

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


4

Dies ist die sauberste Lösung, die ich gefunden habe:

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

Z.B,

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

  • Führt keinen API-Aufruf durch, verwendet Metadaten der EC2-Instanz
  • Verwendet nur Curl und Basic Sed, sodass keine Abhängigkeiten von SDKs oder Tools wahrscheinlich nicht installiert werden.
  • Es wird nicht versucht, den Namen der Verfügbarkeitszone zu analysieren. Machen Sie sich also keine Sorgen, wenn AWS das Format des AZ / Region-Namens ändert

Ja perfekt, danke. Dieses Ergebnis kann leicht in ein JSON-Objekt deserialisiert werden.
Dynamiclynk

Ich bekomme am Ende ein Komma.
Craig

4

Dank https://unix.stackexchange.com/a/144330/135640 können wir mit bash 4.2+ einfach das letzte Zeichen aus der Verfügbarkeitszone entfernen:

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

Dies setzt voraus, dass AWS weiterhin ein einzelnes Zeichen für an die Region angehängte Verfügbarkeitszonen verwendet.


5
Wir konnten immer den letzten Charakter in der Shell entfernen:region=${region%?}
David Jones

4

2 Liner, der funktioniert, solange Sie ec2.internal als Suchdomäne verwenden:

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

4

Für alle, die dies mit guter alter Powershell tun wollen

$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

Oder machen Sie Ubuntu oder dieses Tool nicht zur Voraussetzung und tun Sie einfach:

: "${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
Beachten Sie, dass dies nur funktioniert, da die Verfügbarkeitszone derzeit immer der Regionsname ist, an den ein Kleinbuchstabe angehängt ist (z. B. Region ist "us-west-1", Zone ist "us-west-1a"). Wenn Amazon dieses Muster jemals durchbricht, funktioniert die obige Logik nicht mehr.
Matt Solnit

3

Wenn Sie mit json arbeiten, verwenden Sie die richtigen Tools. jq in diesem Fall sehr mächtig.

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

3

Dies funktioniert sowohl für eu-central-1 als auch für die verschiedenen Buchstabenzonen. (Ich habe nicht genug Repräsentanten, um auf die oben genannte Antwort zu antworten.)

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

Es sollte ec2metadata --availability-zone | sed 's/.$//'(ohne Bindestrich) sein
Vladimir Kondratyev

3

Wenn Sie unter Windows arbeiten, können Sie diesen PowerShell-Einzeiler verwenden:

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

1

Ich habe auch nach einer Lösung gesucht, um eine Region aus der Instanz zu finden, und hier ist meine reine Bash-Lösung:

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

es sei denn, es gibt Regionen, in denen AZ mehr als zwei Buchstaben hat, die mir nicht bekannt sind.


0

Um Informationen zu dem EC2 zu erhalten, bei dem Sie angemeldet sind, können Sie das Tool ec2-metadata verwenden.

Sie können das Tool installieren, indem Sie diesem Link folgen . Nach der Installation des Tools können Sie ausführen

# ec2-metadata -z

um die Region herauszufinden.

Dieses Tool wird mit den neuesten (10.10) Ubuntu AMIs installiert.


4
Das ist falsch. ec2-metadata -zZeigt nur die Verfügbarkeitszone an, nicht die Region.
Matt Solnit

0

Wenn Sie eine Region mit JS abrufen möchten, sollte dies funktionieren:

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

Dies war die Zuordnung, die von AWS DOCS als Antwort auf einen Metadaten-API-Aufruf gefunden wurde. Schneiden Sie einfach das letzte Zeichen, das funktionieren soll.

  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(kein Bindestrich) ist der aktuelle Befehl, mit dem Sie alle aws-Hosting-Informationen zu Ihrer ec2-Box erhalten. Dies ist der eleganteste und sicherste Ansatz. ( ec2-metadataist der alte, nicht mehr gültige Befehl.)


Dies kann vom ausgewählten Typ der virtuellen Box abhängen. Ich bleibe bei Linux.
GViz

0

Eine Methode, die nur egrep verwendet und auf den meisten Linux-Instanzen funktionieren sollte, die ohne zusätzliche Tools gestartet wurden. Ich habe dies anhand einer Liste aller aktuellen AWS-Regionen getestet, die alle übereinstimmen.

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

Erklärung des REGEX:

  • "(\ w) +" Dies entspricht einer beliebigen Anzahl von Buchstaben
  • "-" entspricht nur einem Strich
  • "[0-9]" entspricht einer beliebigen Zahl

Wenn Sie dies in eine Variable umwandeln möchten, gehen Sie wie folgt vor:

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


0

Für die Sed- und Curl-Lösung scheint sich das Format etwas geändert zu haben. Für mich funktioniert

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

0

Irgendwann, seitdem die meisten dieser Antworten veröffentlicht wurden, hat AWS das Vernünftige getan und einen neuen Pfad implementiert : latest/meta-data/placement/region.

Dies bedeutet, dass das Abrufen der Region so einfach wie möglich sein sollte

REGION="$(wget -q -O - http://169.254.169.254/latest/meta-data/placement/region)"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.