Buscar región desde una instancia EC2


131

¿Hay alguna manera de buscar la región de una instancia desde dentro de la instancia?

Estoy buscando algo similar al método para encontrar la identificación de la instancia .



8
Respuesta corta para cualquiera que no se preocupe por todos los scripts de shell: obtenga la zona de disponibilidad http://169.254.169.254/latest/meta-data/placement/availability-zoney elimine el último carácter.
Zarzaparrilla

Respuestas:


147

Esa URL ( http://169.254.169.254/latest/dynamic/instance-identity/document ) ya no parece funcionar. Recibo un 404 cuando intenté usarlo. Sin embargo, tengo el siguiente código que parece funcionar:

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

Espero que esto ayude.

EDITAR: Mejorado en sedbase a comentarios


44
Esto se debe ejecutar dentro de la instancia EC2 y funciona con los backends de AWS. No funcionará en ningún otro lugar (esencialmente porque esa IP es una APIPA). Además, no hay forma de obtener esta información directamente desde el interior de la instancia sin conectarse a una fuente de metadatos. Esto supone que la API 169.254.169.254 está disponible, y su script debe manejar las fallas de la red en consecuencia. ec2-metadataes solo un contenedor para esta API, pero esencialmente hace lo mismo.
dannosaur

1
¿Es esto algo documentado? ¿Puedes explicar cómo lo encontraste?
meawoppl

2
Honestamente, cuando se me ocurrió esa línea de 2 líneas, solo estaba hurgando en la API buscando cualquier cosa que pudiera usar para identificar la región correcta. La API de metadatos de AWS está completamente documentada aquí: docs.aws.amazon.com/AWSEC2/latest/UserGuide/…
dannosaur

12
Comando de reemplazo de sed mucho más simple que el provisto para EC2_REGION:sed 's/[a-z]$//
threejeez

2
Si esto está en un arranque, el servicio de metadatos aún no se puede instanciar; si es así, espere e intente nuevamente. Lo he visto tomar 10-15 segundos después del arranque para que la ubicación de metadatos esté disponible.
vacri

81

Hay una forma más de lograr eso:

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

echo $REGION

us-east-1

¿Debería funcionar en cualquier región / az (y en cualquier AMI)? Estoy 404 - Not Foundtratando de acceder a GETesa URL desde una máquina us-east-1a.
Adam Monsen

@AdamMonsen quizás fue un error transitorio. Estoy en us-east-1a y funciona muy bien.
Florin Andrei

Gracias @FlorinAndrei. Funciona para mí ahora también.
Adam Monsen

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

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

38

Si está de acuerdo con el uso jq, puede ejecutar lo siguiente:

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

Supongo que es la forma más limpia.


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

Para sistemas basados ​​en Debian, el comando no tiene guión.

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

66
Obtenga una cadena pura con solo el nombre de la región:ec2-metadata --availability-zone | sed 's/placement: \(.*\).$/\1/'
nahsh

ec2-metadatano parece ser algo que esté disponible por defecto, ¿puede incluir instrucciones de instalación?
Tim Malone

23

Si desea evitar la expresión regular, aquí hay una línea que puede hacer 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']"

¡Esta respuesta debería ser más alta!
Kostas Demiris

@KostasDemiris Estoy de acuerdo, prefiero leer el valor de la estructura JSON que una expresión regular.
lasec0203

1
Estoy de acuerdo en que esta parece ser la mejor manera de hacerlo si no tiene instalado jq. Realmente esperarías que AWS exponga esto como algo así como 169.254.169.254/latest/meta-data/placement/region ...
Krenair

17

Puede usar metadatos ec2:

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

2
Con esto, si estás dentro eu-central-1estás jodido.
dannosaur

2
centralno existía cuando inicialmente escribí mi respuesta. Se agregó ahora.
Daniel Kuppitz

22
Para mí, un script que se rompe cada vez que AWS agrega una nueva región no parece una solución particularmente sólida.
Ryan B. Lynch

1
En lugar de grep, awk '{split($2,arr,"-"); print arr[1]"-"arr[2]}'mantendrá solo los dos primeros componentes del nombre AZ.
dskrvk

@dskrvk Si solo conserva los dos primeros componentes, ¿cómo se distribuye entre eu-west-1, eu-west-2y eu-west-3(También us-west-1y us-west-2) @OP: solo la coincidencia '[a-z][a-z]-[a-z]*-[0-9][0-9]*'parece más segura (es una expresión regular básica, se puede acortar con un RE extendido). (La expresión regular actual se romperá en la caregión, las afregiones y la meregión)
Gert van den Berg

15

Más fácil que encontré hasta ahora

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

1
Esto tiene el beneficio de no tener dependencias no predeterminadas y es solo una línea.
Mark Stosberg

14

un forro muy simple

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

44
Son dos líneas
Christian el

1
Pero esto no está funcionando en la región us-west-1. Devuelve curl: (6) Could not resolve host: instance-data; Name or service not knownerror.
SK Venkat

1
@SKVenkat Eso probablemente esté relacionado con la configuración de DNS de su VPC ... Usar la IP para la API de metadatos parece más seguro (la mitad de las otras respuestas lo hacen)
Gert van den Berg

@GertvandenBerg, lo secundo ..
SK Venkat

9

Si tiene instalado jq , también puede hacerlo (probablemente el método más "elegante") de esta manera:

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

Esto simplemente devuelve el valor bruto de "región" sin ninguna impresión bonita u otro formato. Referencia: Foro de AWS


7

Obtenga la región de la zona de disponibilidad, elimine la última letra de la misma.

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

6

Use JQ:

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


4

Esta es la solución más limpia que encontré:

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

P.ej,

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

  • No realiza una llamada API, utiliza metadatos de instancia EC2
  • Solo usa curl y sed básico, por lo que no es probable que se instalen dependencias en SDK o herramientas.
  • No intenta analizar el nombre de la Zona de disponibilidad, por lo que no se preocupe si AWS cambia el formato de nombre AZ / Región

Sí perfecto, gracias. Este resultado puede deserializarse fácilmente en un objeto json.
dynamiclynk

Recibo una coma al final.
Craig

4

Gracias a https://unix.stackexchange.com/a/144330/135640 , con bash 4.2+ podemos eliminar el último carácter de la zona de disponibilidad:

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

Esto supone que AWS continúa utilizando un solo carácter para las zonas de disponibilidad agregadas a la región.


55
Siempre hemos podido despojar al último personaje de la concha:region=${region%?}
David Jones

4

2 liner que funciona siempre que esté usando ec2.internal como su dominio de búsqueda:

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

4

Para cualquiera que quiera hacer esto con buen 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

3

O no haga de Ubuntu o esta herramienta un requisito y simplemente haga:

: "${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
Tenga en cuenta que esto solo funciona porque actualmente la zona de disponibilidad es siempre el nombre de la región con una letra minúscula adjunta (por ejemplo, la región es "us-west-1", la zona es "us-west-1a"). Si Amazon alguna vez rompe este patrón, entonces la lógica anterior ya no funcionará.
Matt Solnit

3

Si trabaja con json, use las herramientas adecuadas. jq mucho poderoso en este caso.

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

3

Esto funciona para eu-central-1, así como para las diversas zonas de letras. (No tengo suficiente representante para responder a la respuesta sed anterior)

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

Debería ser ec2metadata --availability-zone | sed 's/.$//'(sin guión)
Vladimir Kondratyev

3

Si está ejecutando en Windows, puede usar este one-liner de PowerShell:

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

1

También estaba buscando una solución para encontrar la región desde la instancia y aquí está mi solución Bash pura:

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

a menos que haya regiones donde AZ tenga más de dos letras, de las cuales no estoy al tanto.


0

Para obtener información sobre el EC2 en el que ha iniciado sesión, puede utilizar la herramienta de metadatos ec2.

Puede instalar la herramienta siguiendo este enlace. Después de instalar la herramienta, puede ejecutar

# ec2-metadata -z

para descubrir la región

Esta herramienta viene instalada con las últimas AMI de Ubuntu (10.10),


44
Esto es incorrecto. ec2-metadata -zsolo muestra la zona de disponibilidad, no la región.
Matt Solnit

0

Si está buscando obtener una región utilizando JS, esto debería funcionar:

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

Este fue el mapeo encontrado en AWS DOCS, en respuesta a la llamada a la API de metadatos, simplemente recorte el último carácter que debería funcionar.

  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(sin guión) es el comando actual para proporcionarle toda la información de hosting aws sobre su caja ec2. Este es el enfoque más elegante y seguro. ( ec2-metadataes el comando antiguo, que ya no es válido).


Esto podría depender del tipo de caja virtual que haya seleccionado. Me quedo con Linux.
GViz

0

Un método que usa solo egrep, que debería funcionar en la mayoría de las instancias de Linux sin tener que instalar ninguna herramienta adicional. Probé esto contra una lista de todas las regiones actuales de AWS y todas coinciden.

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

Explicación del REGEX:

  • "(\ w) +" Esto coincide con cualquier número de letras
  • "-" coincide con un solo guión
  • "[0-9]" coincide con cualquier número 1

Si quieres esto en una variable haz:

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


0

Para la solución sed y curl, parece que el formato ha cambiado un poco. Para mi trabaja

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

0

En algún momento, ya que esto la mayoría de estas respuestas han sido escritos, AWS hizo lo razonable y puso en práctica un nuevo camino: latest/meta-data/placement/region.

Esto significa que obtener la región debería ser tan simple como

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

0

Puede obtener una región de instancia utilizando esta solicitud curl

$ curl http://169.254.169.254/latest/meta-data/placement/region
us-east-1
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.