Localizar região de dentro de uma instância do EC2


131

Existe uma maneira de procurar a região de uma instância de dentro da instância?

Estou procurando algo semelhante ao método de encontrar o ID da instância .



8
Resposta curta para quem não se importa com todos os scripts de shell: obtenha a zona de disponibilidade http://169.254.169.254/latest/meta-data/placement/availability-zonee remova o último caractere.
Sarsaparilla

Respostas:


147

Esse URL ( http://169.254.169.254/latest/dynamic/instance-identity/document ) parece não funcionar mais. Recebo um 404 quando tentei usá-lo. Eu tenho o seguinte 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 isto ajude.

EDIT: Melhorado com sedbase nos comentários


4
Isso é para ser executado dentro da instância EC2 e é alimentado por backends da AWS. Não funcionará em nenhum outro lugar (essencialmente porque esse IP é um APIPA). Além disso, não há como obter essas informações diretamente de dentro da instância sem conectar-se a uma fonte de metadados. Isso pressupõe que a API 169.254.169.254 esteja disponível e seu script deve manipular falhas de rede de acordo. ec2-metadataé apenas um invólucro para esta API, mas essencialmente faz a mesma coisa.
Dannosaur

1
Isso é algo documentado? Você pode explicar como o encontrou?
06 de

2
Com toda a honestidade, quando criei esse liner de duas linhas, eu estava apenas cutucando a API procurando por qualquer coisa que pudesse usar para identificar a região correta. Os metadados API AWS está totalmente documentado aqui: docs.aws.amazon.com/AWSEC2/latest/UserGuide/...
dannosaur

12
Muito mais simples sed substituir o comando do que o previsto para o EC2_REGION:sed 's/[a-z]$//
threejeez

2
Se isso estiver em um script de inicialização, o serviço de metadados ainda não será instanciado - se assim for, aguarde e tente novamente. Vi que demoram 10 a 15 segundos após a inicialização para que o local dos metadados fique disponível.
Vacri

81

Há mais uma maneira de conseguir isso:

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

echo $REGION

us-east-1

Isso deve funcionar em qualquer região / az (e em qualquer AMI)? Estou 404 - Not Foundtentando GETacessar esse URL a partir de uma máquina us-east-1a.
Adam Monsen

@AdamMonsen talvez tenha sido um erro transitório. Estou na us-east-1a e funciona muito bem.
Florin Andrei

Obrigado @FlorinAndrei. Funciona para mim agora também.
Adam Monsen

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

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

38

Se você estiver bem com o uso jq, execute o seguinte:

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

Eu acho que é o caminho mais limpo.


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

Para sistemas baseados em debian, o comando é sem traço.

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

6
Obtenha string pura apenas com o nome da região:ec2-metadata --availability-zone | sed 's/placement: \(.*\).$/\1/'
nahsh 06/06

ec2-metadatanão parece ser algo disponível por padrão - você pode incluir instruções de instalação?
Tim Malone

23

Se você deseja evitar a expressão regular, aqui está uma lista que você pode fazer com o 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 resposta deve ser maior!
Kostas Demiris

@KostasDemiris Concordo, é melhor ler o valor da estrutura JSON do que uma expressão regular.
precisa saber é o seguinte

1
Concordo que essa parece ser a melhor maneira de fazer isso se você não tiver o jq instalado. Você seria realmente esperar AWS para expor isso como algo como 169.254.169.254/latest/meta-data/placement/region ...
Krenair

17

Você pode usar os metadados ec2:

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

2
Com isso, se eu-central-1você estiver ferrado.
Dannosaur

2
centralnão existia quando escrevi minha resposta inicialmente. Foi adicionado agora.
Daniel Kuppitz

22
Um script que é interrompido toda vez que a AWS adiciona uma nova região não me parece uma solução particularmente forte.
Ryan B. Lynch

1
Em vez de grep, awk '{split($2,arr,"-"); print arr[1]"-"arr[2]}'manterá apenas os dois primeiros componentes do nome AZ.
dskrvk

@dskrvk Se você apenas manter os dois primeiros componentes, como você distringuish entre eu-west-1, eu-west-2e eu-west-3(também us-west-1e us-west-2@OP): apenas correspondência '[a-z][a-z]-[a-z]*-[0-9][0-9]*'parece mais seguro (que é uma expressão regular básica, pode ser feita mais curta com um RE estendida). (O regex atual quebrará na caregião, nas afregiões e na meregião)
Gert van den Berg

15

Mais fácil que encontrei até agora

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

1
Isso tem o benefício de nenhuma dependência não padrão e é apenas uma única linha.
Mark Stosberg

14

forro muito simples

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

4
Isso é duas linhas
Christian

1
Mas isso não está funcionando na região us-west-1. Retorna curl: (6) Could not resolve host: instance-data; Name or service not knownerro.
SK Venkat 04/04

1
@SKVenkat Isso provavelmente está relacionado às configurações de DNS da sua VPC ... Usar o IP para os metadados-api parece mais seguro (metade das outras respostas faz isso)
Gert van den Berg -

@GertvandenBerg, I second it ..
SK Venkat

9

Se você tiver o jq instalado, também poderá fazê-lo (provavelmente o método mais "gracioso") desta maneira:

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

Isso simplesmente retorna o valor bruto da "região" sem nenhuma impressão bonita ou outra formatação. Referência: Fórum da AWS


7

Obtenha a região da zona de disponibilidade, retire a última letra dela.

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 é a solução mais limpa que encontrei:

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

Por exemplo,

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

  • Não faz uma chamada de API, usa metadados da instância do EC2
  • Usa apenas curl e sed básico, portanto, não é provável que dependências nos SDKs ou ferramentas sejam instaladas.
  • Não tenta analisar o nome da Zona de Disponibilidade; portanto, não se preocupe se a AWS alterar o formato de nome de AZ / Região

Sim perfeito, obrigado. Esse resultado pode ser facilmente desserializado em um objeto json.
dynamiclynk

Estou recebendo uma vírgula no final.
Craig

4

Graças a https://unix.stackexchange.com/a/144330/135640 , com o bash 4.2+, podemos simplesmente retirar o último caractere da zona de disponibilidade:

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

Isso pressupõe que a AWS continue usando um único caractere para as zonas de disponibilidade anexadas à região.


5
Sempre conseguimos descascar o último caractere com casca:region=${region%?}
David Jones

4

Liner 2 que funciona desde que você esteja usando ec2.internal como seu domínio de pesquisa:

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

4

Para quem quiser fazer isso com o bom 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

Ou não faça do Ubuntu ou desta ferramenta um requisito e simplesmente faça:

: "${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
Observe que isso só funciona porque atualmente a zona de disponibilidade é sempre o nome da região com uma letra minúscula anexada a ela (por exemplo, região é "us-west-1", zona é "us-west-1a"). Se a Amazon quebrar esse padrão, a lógica acima não funcionará mais.
Matt Solnit

3

Se você trabalha com json - use as ferramentas certas. jq muito poderoso neste caso.

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

3

Isso funciona para eu-central-1 e para as várias zonas de letras. (Não tenho representante suficiente para responder à resposta sed acima)

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

Deve ser ec2metadata --availability-zone | sed 's/.$//'(sem traço)
Vladimir Kondratyev

3

Se você estiver executando no Windows, poderá usar esta linha de comandos do PowerShell:

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

1

Também estava procurando uma solução para encontrar a região da instância e aqui está minha solução Bash pura:

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

a menos que haja regiões em que o AZ tenha mais de duas letras, das quais não conheço.


0

Para descobrir informações sobre o EC2 no qual você está conectado, use a ferramenta ec2-metadata.

Você pode instalar a ferramenta seguindo este link. Após instalar a ferramenta, você pode executar

# ec2-metadata -z

para descobrir a região.

Essas ferramentas são instaladas com as mais recentes AMIs do Ubuntu (10.10),


4
Isto está incorreto. ec2-metadata -zmostra apenas a zona de disponibilidade, não a região.
Matt Solnit

0

Se você deseja obter uma região usando JS, isso deve 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();
            }
     });

Esse foi o mapeamento encontrado no AWS DOCS, em resposta à chamada da API de metadados, basta aparar o último caractere que deve 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(sem traço) é o comando atual para fornecer todas as informações de hospedagem do aws sobre sua caixa ec2. esta é a abordagem mais elegante e segura. ( ec2-metadataé o comando antigo, não é mais válido.)


Isso pode depender do tipo de caixa virtual que você selecionou. Eu fico com o Linux.
GViz

0

Um método que usa apenas egrep, que deve funcionar na maioria das instâncias do linux, sem a necessidade de instalar ferramentas extras. Eu testei isso em uma lista de todas as regiões atuais da AWS e todas elas correspondem.

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

Explicação do REGEX:

  • "(\ w) +" Corresponde a qualquer número de letras
  • "-" corresponde apenas a um único traço
  • "[0-9]" corresponde a qualquer número 1

Se você quiser isso em uma variável, faça:

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


0

Para a solução sed e curl, parece que o formato mudou um pouco. Para mim trabalha

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

0

Em algum momento, uma vez que esta maioria destas respostas foram postadas, AWS fez a coisa razoável e implementado um novo caminho: latest/meta-data/placement/region.

Isso significa que a região deve ser tão simples quanto

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

0

Você pode obter a região da instância usando esta solicitação de ondulação

$ curl http://169.254.169.254/latest/meta-data/placement/region
us-east-1
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.