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 .

Gary Richardson
fuente
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

dannosaur
fuente
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
mgarman
fuente
¿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.

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

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

ec2metadata --availability-zone | sed 's/.$//'
Jose Alban
fuente
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']"
Jaeyoung Chun
fuente
¡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]+"
Daniel Kuppitz
fuente
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/.$//'
Francesco Gualazzi
fuente
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}
Ravi Kumar
fuente
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

Arbab Nazar
fuente
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]$//'
mohrt
fuente
6

Use JQ:

curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region
Spanky
fuente
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
Kelly Setzer
fuente
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.

Steve Jansen
fuente
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}
Gil Zellner
fuente
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
húmedo
fuente
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:]])}"}
flácido
fuente
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
Alan
fuente
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]$//'
Tyler Kellogg
fuente
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
cwa
fuente
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.

Ajax
fuente
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),

sheki
fuente
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
Surya Prakash Patel
fuente
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).

GViz
fuente
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]')

Chart96
fuente
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'
denken
fuente
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)"
SteveGoob
fuente
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
Артем Косенко
fuente