Trova la regione all'interno di un'istanza EC2


131

C'è un modo per cercare la regione di un'istanza all'interno dell'istanza?

Sto cercando qualcosa di simile al metodo di ricerca dell'ID istanza .



8
Risposta breve per chiunque non si preoccupi di tutti gli script della shell: ottenere la zona di disponibilità http://169.254.169.254/latest/meta-data/placement/availability-zonee rimuovere l'ultimo carattere.
Sarsaparilla,

Risposte:


148

Quell'URL ( http://169.254.169.254/latest/dynamic/instance-identity/document ) non sembra funzionare più. Ottengo un 404 quando ho provato a usarlo. Ho il seguente codice che sembra funzionare però:

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

Spero che questo ti aiuti.

EDIT: migliorato in sedbase ai commenti


4
Questo deve essere eseguito all'interno dell'istanza EC2 ed è alimentato dai backend di AWS. Non funzionerà in nessun altro posto (essenzialmente perché quell'IP è un APIPA). Inoltre, non è possibile ottenere queste informazioni direttamente dall'istanza senza collegarsi a una fonte di metadati. Ciò presuppone che l'API 169.254.169.254 sia disponibile e che lo script dovrebbe gestire gli errori di rete di conseguenza. ec2-metadataè solo un wrapper per questa API, ma essenzialmente fa la stessa cosa.
dannosaur

1
Questo è qualcosa documentato? Puoi spiegare come l'hai trovato?
meawoppl,

2
In tutta onestà, quando mi sono inventato quel 2-liner, stavo solo cercando l'API alla ricerca di qualsiasi cosa che potessi usare per identificare la regione corretta. L'API dei metadati AWS è completamente documentata qui: docs.aws.amazon.com/AWSEC2/latest/UserGuide/…
dannosaur

12
Il comando di sostituzione di sed è molto più semplice di quello fornito per EC2_REGION:sed 's/[a-z]$//
tre giorni

2
Se è presente in uno script di avvio, il servizio metadati potrebbe non essere ancora istanziato - in tal caso, attendere e riprovare. Ho visto che sono necessari 10-15 secondi dopo l'avvio per rendere disponibile la posizione dei metadati.
vacri

81

C'è un altro modo per ottenerlo:

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

echo $REGION

us-east-1

Dovrebbe funzionare in qualsiasi regione / az (e su qualsiasi AMI)? Sto 404 - Not Foundprovando a GETquell'URL da una macchina in us-east-1a.
Adam Monsen,

@AdamMonsen forse è stato un errore temporaneo. Sono su us-east-1a e funziona benissimo.
Florin Andrei,

Grazie @FlorinAndrei. Funziona anche per me adesso.
Adam Monsen,

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

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

38

Se si utilizza OK jq, è possibile eseguire quanto segue:

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

Immagino sia il modo più pulito.


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

Per i sistemi basati su Debian, il comando è senza trattino.

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

6
Ottieni una stringa pura con solo il nome della regione:ec2-metadata --availability-zone | sed 's/placement: \(.*\).$/\1/'
nahsh

ec2-metadatanon sembra essere qualcosa che è disponibile di default - puoi includere le istruzioni di installazione?
Tim Malone,

23

Se vuoi evitare l'espressione regolare, ecco un one-liner che puoi fare con 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']"

Questa risposta dovrebbe essere più alta!
Kostas Demiris,

@KostasDemiris Sono d'accordo, piuttosto preferisco leggere il valore dalla struttura JSON piuttosto che un'espressione regolare.
lasec0203,

1
Sono d'accordo che questo sembra essere il modo migliore per farlo se non hai installato jq. Ti aspetteresti davvero che AWS esponga questo come qualcosa del 169.254.169.254/latest/meta-data/placement/region ...
Krenair

17

Puoi usare i metadati ec2:

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

2
Con questo, se sei dentro eu-central-1sei fregato.
dannosauro

2
centralnon esisteva quando inizialmente ho scritto la mia risposta. È stato aggiunto ora.
Daniel Kuppitz,

22
Una sceneggiatura che si interrompe ogni volta che AWS aggiunge una nuova regione non mi sembra una soluzione particolarmente efficace.
Ryan B. Lynch,

1
Invece di grep, awk '{split($2,arr,"-"); print arr[1]"-"arr[2]}'manterranno solo i primi due componenti del nome AZ.
dskrvk,

@dskrvk Se mantieni i primi due componenti, come fai a distinguere tra eu-west-1, eu-west-2e eu-west-3(anche us-west-1e us-west-2) @OP: solo la corrispondenza '[a-z][a-z]-[a-z]*-[0-9][0-9]*'sembra più sicura (che è una regex di base, può essere accorciata con un RE esteso). (L'attuale regex si spezzerà nella caregione, nelle afregioni e nella meregione)
Gert van den Berg

15

Il più semplice che ho trovato finora

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

1
Questo ha il vantaggio di non avere dipendenze non predefinite ed è solo una singola linea.
Mark Stosberg,

14

una fodera molto semplice

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

4
Sono due righe
Christian

1
Ma questo non funziona nella regione us-west-1. Restituisce curl: (6) Could not resolve host: instance-data; Name or service not knownerrore.
SK Venkat,

1
@SKVenkat Questo è probabilmente correlato alle impostazioni DNS del tuo VPC ... L'uso dell'IP per i metadati-api sembra più sicuro (la metà delle altre risposte lo fa)
Gert van den Berg

@GertvandenBerg, l'ho secondo ..
SK Venkat

9

Se hai installato jq , puoi anche procedere (probabilmente il metodo più "grazioso") in questo modo:

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

Ciò restituisce semplicemente il valore grezzo di "regione" senza alcuna stampa carina o altra formattazione. Riferimento: AWS Forum


7

Ottieni la regione dalla zona di disponibilità, togli la sua ultima lettera.

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

6

Usa JQ:

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


4

Questa è la soluzione più pulita che ho trovato:

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

Per esempio,

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

  • Non effettua una chiamata API, utilizza i metadati dell'istanza EC2
  • Utilizza solo curl e sed di base, quindi nessuna dipendenza da SDK o strumenti che probabilmente non verranno installati.
  • Non tenta di analizzare il nome della zona di disponibilità, quindi non preoccuparti se AWS modifica il formato del nome AZ / regione

Sì perfetto, grazie. Questo risultato può essere facilmente deserializzato in un oggetto json.
dynamiclynk,

Sto ricevendo una virgola alla fine.
Craig,

4

Grazie a https://unix.stackexchange.com/a/144330/135640 , con bash 4.2+ possiamo semplicemente rimuovere l'ultimo carattere dalla zona di disponibilità:

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

Ciò presuppone che AWS continui a utilizzare un singolo carattere per le zone di disponibilità aggiunte alla regione.


5
Siamo sempre stati in grado di eliminare l'ultimo personaggio in shell:region=${region%?}
David Jones,

4

2 liner che funziona fintanto che stai usando ec2.internal come dominio di ricerca:

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

4

Per chiunque voglia farlo con un buon vecchio 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

Oppure non rendere Ubuntu o questo strumento un requisito e semplicemente:

: "${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
Nota che questo funziona solo perché attualmente la zona di disponibilità è sempre il nome della regione con una lettera minuscola allegata (ad es. La regione è "us-west-1", la zona è "us-west-1a"). Se Amazon interromperà mai questo modello, la logica sopra non funzionerà più.
Matt Solnit,

3

Se lavori con json, usa gli strumenti giusti. molto potente in questo caso.

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

3

Funziona con eu-central-1 e con le varie zone di lettere. (Non ho abbastanza rappresentante per rispondere alla risposta sed sopra)

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

Dovrebbe essere ec2metadata --availability-zone | sed 's/.$//'(senza trattino)
Vladimir Kondratyev il

3

Se si esegue Windows, è possibile utilizzare questo one-liner PowerShell:

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

1

Stavo anche cercando una soluzione per trovare la regione dall'istanza ed ecco la mia soluzione Bash pura:

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

a meno che non ci siano regioni in cui l'AZ ha più di due lettere, di cui non sono a conoscenza.


0

Per trovare informazioni sull'EC2 a cui si è effettuato l'accesso, è possibile utilizzare lo strumento metadati ec2.

Puoi installare lo strumento seguendo questo link. Dopo aver installato lo strumento, è possibile eseguire

# ec2-metadata -z

per scoprire la regione.

Questo strumento viene installato con le ultime (10.10) Ubuntu AMI,


4
Questo non è corretto ec2-metadata -zmostra solo la zona di disponibilità, non la regione.
Matt Solnit,

0

Se stai cercando di ottenere una regione usando JS, questo dovrebbe funzionare:

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

Questa era la mappatura trovata da AWS DOCS, in risposta alla chiamata API dei metadati, basta tagliare l'ultimo carattere che dovrebbe funzionare.

  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(senza trattino) è il comando corrente per fornirti tutte le informazioni di hosting di aws sulla tua ec2 box. questo è l'approccio più elegante e sicuro. ( ec2-metadataè il vecchio comando non più valido.)


Ciò potrebbe dipendere dal tipo di scatola virtuale che hai selezionato. Mi attengo a Linux.
GViz

0

Un metodo che utilizza solo egrep, che dovrebbe funzionare sulla maggior parte delle istanze di Linux senza che sia necessario installare alcun tool aggiuntivo. Ho provato questo contro un elenco di tutte le regioni AWS correnti e tutte corrispondono.

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

Spiegazione del REGEX:

  • "(\ w) +" Corrisponde a qualsiasi numero di lettere
  • "-" corrisponde a un solo trattino
  • "[0-9]" corrisponde a 1 numero qualsiasi

Se vuoi questo in una variabile fai:

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


0

Per la soluzione sed and curl sembra che il formato sia leggermente cambiato. Per me funziona

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

0

Ad un certo punto da quando sono state pubblicate molte di queste risposte, AWS ha fatto la cosa ragionevole e ha implementato un nuovo percorso: latest/meta-data/placement/region .

Ciò significa che ottenere la regione dovrebbe essere semplice come

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

0

È possibile ottenere la regione dell'istanza utilizzando questa richiesta di arricciatura

$ curl http://169.254.169.254/latest/meta-data/placement/region
us-east-1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.