Rechercher une région à partir d'une instance EC2


131

Existe-t-il un moyen de rechercher la région d'une instance à partir de l'instance?

Je recherche quelque chose de similaire à la méthode de recherche de l'ID d'instance .



8
Réponse courte pour tous ceux qui ne se soucient pas de tous les scripts shell: obtenir la zone de disponibilité http://169.254.169.254/latest/meta-data/placement/availability-zoneet supprimer le dernier caractère.
Salsepareille

Réponses:


148

Cette URL ( http://169.254.169.254/latest/dynamic/instance-identity/document ) ne semble plus fonctionner. J'obtiens un 404 quand j'essaye de l'utiliser. J'ai le code suivant qui semble fonctionner cependant:

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

J'espère que cela t'aides.

EDIT: Amélioré en sedfonction des commentaires


4
Cela doit être exécuté dans l'instance EC2 et est alimenté par les backends d'AWS. Cela ne fonctionnera nulle part ailleurs (essentiellement parce que cette IP est un APIPA). De plus, il n'y a aucun moyen d'obtenir ces informations directement à partir de l'instance sans se connecter à une source de métadonnées. Cela suppose que l'API 169.254.169.254 est disponible et que votre script doit gérer les pannes de réseau en conséquence. ec2-metadataest juste un wrapper pour cette API, mais fait essentiellement la même chose.
dannosaure

1
Est-ce quelque chose de documenté? Pouvez-vous expliquer comment vous l'avez trouvé?
meawoppl

2
En toute honnêteté, lorsque j'ai trouvé ce 2 lignes, je cherchais simplement l'API à la recherche de tout ce que je pourrais utiliser pour identifier la bonne région. L'API de métadonnées AWS est entièrement documentée ici: docs.aws.amazon.com/AWSEC2/latest/UserGuide/…
dannosaur

12
Commande sed replace beaucoup plus simple que celle fournie pour l'EC2_REGION:sed 's/[a-z]$//
threejeez

2
S'il s'agit d'un script de démarrage, le service de métadonnées peut ne pas encore être instancié - si tel est le cas, attendez et réessayez. J'ai vu qu'il fallait 10 à 15 secondes après le démarrage pour que l'emplacement des métadonnées devienne disponible.
vacri

81

Il existe un autre moyen d'y parvenir:

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

echo $REGION

us-east-1

Cela devrait-il fonctionner dans n'importe quelle région / az (et sur n'importe quelle AMI)? J'essaye d'accéder 404 - Not Foundà GETcette URL depuis une machine dans us-east-1a.
Adam Monsen

@AdamMonsen était peut-être une erreur passagère. Je suis sur nous-east-1a et cela fonctionne très bien.
Florin Andrei

Merci @FlorinAndrei. Fonctionne aussi pour moi maintenant.
Adam Monsen

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

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

38

Si vous êtes d'accord avec l'utilisation jq, vous pouvez exécuter ce qui suit:

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

Je suppose que c'est le moyen le plus propre.


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

Pour les systèmes basés sur Debian, la commande est sans tiret.

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

6
Obtenez une chaîne pure avec uniquement le nom de la région:ec2-metadata --availability-zone | sed 's/placement: \(.*\).$/\1/'
nahsh

ec2-metadatane semble pas être disponible par défaut - pouvez-vous inclure des instructions d'installation?
Tim Malone

23

Si vous voulez éviter les expressions régulières, voici une ligne unique que vous pouvez faire avec 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']"

Cette réponse devrait être plus élevée!
Kostas Demiris

@KostasDemiris Je suis d'accord, je préfère plutôt lire la valeur de la structure JSON qu'une expression régulière.
lasec0203

1
Je suis d'accord que cela semble être la meilleure façon de le faire si vous n'avez pas installé jq. Vous vous attendriez vraiment à ce qu'AWS expose cela comme quelque chose comme 169.254.169.254/latest/meta-data/placement/region ...
Krenair

17

Vous pouvez utiliser ec2-metadata:

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

2
Avec ça, si vous êtes dedans, eu-central-1vous êtes foutu.
dannosaure

2
centraln'existait pas lorsque j'ai écrit ma réponse. C'est ajouté maintenant.
Daniel Kuppitz

22
Un script qui se rompt à chaque fois qu'AWS ajoute une nouvelle région ne me semble pas être une solution particulièrement efficace.
Ryan

1
Au lieu de grep, awk '{split($2,arr,"-"); print arr[1]"-"arr[2]}'ne conservera que les deux premiers composants du nom AZ.
dskrvk le

@dskrvk Si vous ne gardez que les deux premiers composants, comment faire la distinction entre eu-west-1, eu-west-2et eu-west-3(Aussi us-west-1et us-west-2) @OP: juste la correspondance '[a-z][a-z]-[a-z]*-[0-9][0-9]*'semble plus sûre (c'est-à-dire une expression régulière de base, elle peut être raccourcie avec une RE étendue). (La regex actuelle se cassera sur la carégion, les afrégions et la merégion)
Gert van den Berg

15

Le plus simple que j'ai trouvé jusqu'à présent

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

1
Cela a l'avantage de ne pas avoir de dépendances non par défaut et il ne s'agit que d'une seule ligne.
Mark Stosberg

14

une doublure très simple

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

4
C'est deux lignes
Christian

1
Mais cela ne fonctionne pas sur la région us-west-1. Renvoie une curl: (6) Could not resolve host: instance-data; Name or service not knownerreur.
SK Venkat

1
@SKVenkat Cela est probablement lié aux paramètres DNS de votre VPC ... L'utilisation de l'adresse IP pour les métadonnées-api semble plus sûre (la moitié des autres réponses le font)
Gert van den Berg

@GertvandenBerg, je l'appuie ..
SK Venkat le

9

Si jq est installé, vous pouvez également vous y prendre (probablement la méthode la plus "gracieuse") de cette façon:

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

Cela renvoie simplement la valeur brute de "region" sans aucune jolie impression ou autre formatage. Référence: AWS Forum


7

Récupérez la région dans la zone de disponibilité, supprimez-en la dernière lettre.

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

6

Utilisez JQ:

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


4

C'est la solution la plus propre que j'ai trouvée:

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

Par exemple,

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

  • Ne passe pas d'appel API, utilise les métadonnées d'instance EC2
  • N'utilise que curl et sed de base, donc aucune dépendance sur les SDK ou les outils peu susceptibles d'être installés.
  • N'essaye pas d'analyser le nom de la zone de disponibilité, donc ne vous inquiétez pas si AWS modifie le format du nom AZ / Région

Ouais parfait, merci. Ce résultat peut facilement être désérialisé en un objet json.
dynamiclynk

J'obtiens une virgule à la fin.
Craig le

4

Grâce à https://unix.stackexchange.com/a/144330/135640 , avec bash 4.2+, nous pouvons simplement supprimer le dernier caractère de la zone de disponibilité:

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

Cela suppose qu'AWS continue d'utiliser un seul caractère pour les zones de disponibilité ajoutées à la région.


5
Nous avons toujours pu dépouiller le dernier personnage de la coquille:region=${region%?}
David Jones

4

2 doublure qui fonctionne tant que vous utilisez ec2.internal comme domaine de recherche:

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

4

Pour tous ceux qui veulent faire ça avec le bon vieux 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

Ou ne faites pas d'Ubuntu ou de cet outil une exigence et faites simplement:

: "${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
Notez que cela ne fonctionne que parce qu'actuellement, la zone de disponibilité est toujours le nom de la région avec une lettre minuscule en plus (par exemple, la région est "us-west-1", la zone est "us-west-1a"). Si Amazon rompt ce modèle, la logique ci-dessus ne fonctionnera plus.
Matt Solnit le

3

Si vous travaillez avec json, utilisez les bons outils. jq bien puissant dans ce cas.

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

3

Cela fonctionne pour eu-central-1 ainsi que pour les différentes zones de lettres. (Je n'ai pas assez de représentants pour répondre à la réponse sed ci-dessus)

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

Ça devrait être ec2metadata --availability-zone | sed 's/.$//'(sans tiret)
Vladimir Kondratyev

3

Si vous utilisez Windows, vous pouvez utiliser ce PowerShell One-Liner:

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

1

Je cherchais également une solution pour trouver la région à partir de l'instance et voici ma solution pure Bash:

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

à moins qu'il y ait des régions où AZ a plus de deux lettres, dont je ne suis pas au courant.


0

Pour obtenir des informations sur l'EC2 auquel vous êtes connecté, vous pouvez utiliser l'outil ec2-metadata.

Vous pouvez installer l'outil en suivant ce lien. Après avoir installé l'outil, vous pouvez exécuter

# ec2-metadata -z

pour découvrir la région.

Cet outil est installé avec les dernières AMI Ubuntu (10.10),


4
Ceci est une erreur. ec2-metadata -zaffiche uniquement la zone de disponibilité, pas la région.
Matt Solnit le

0

Si vous cherchez à obtenir une région à l'aide de JS, cela devrait fonctionner:

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

C'était le mappage trouvé à partir d'AWS DOCS, en réponse à l'appel d'API de métadonnées, il suffit de couper le dernier caractère pour fonctionner.

  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(pas de tiret) est la commande actuelle pour vous fournir toutes les informations d'hébergement aws sur votre box ec2. c'est l'approche la plus élégante et la plus sûre. ( ec2-metadataest l'ancienne commande qui n'est plus valide.)


Cela peut dépendre du type de boîte virtuelle que vous avez sélectionné. Je m'en tiens à Linux.
GViz

0

Une méthode utilisant uniquement egrep, qui devrait fonctionner sur la plupart des instances Linux lancées sans avoir à installer d'outils supplémentaires. J'ai testé cela par rapport à une liste de toutes les régions AWS actuelles et elles correspondent toutes.

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

Explication du REGEX:

  • "(\ w) +" Cela correspond à n'importe quel nombre de lettres
  • "-" ne correspond qu'à un seul tiret
  • "[0-9]" correspond à 1 nombre quelconque

Si vous voulez cela dans une variable, faites:

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


0

Pour la solution sed et curl, il semble que le format ait un peu changé. Pour moi fonctionne

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

0

À un moment donné depuis ce la plupart de ces réponses ont été affichées, AWS a fait la chose raisonnable et mis en œuvre un nouveau chemin: latest/meta-data/placement/region.

Cela signifie que l'obtention de la région doit être aussi simple que

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

0

Vous pouvez obtenir la région de l'instance à l'aide de cette requête curl

$ curl http://169.254.169.254/latest/meta-data/placement/region
us-east-1
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.