Como obter o ID da instância de uma instância ec2?

379

Como posso descobrir o instance idde uma instância ec2 de dentro da instância ec2?

flybywire
fonte

Respostas:

534

Veja a documentação do EC2 sobre o assunto .

Corre:

wget -q -O - http://169.254.169.254/latest/meta-data/instance-id

Se você precisar de acesso programático ao ID da instância a partir de um script,

die() { status=$1; shift; echo "FATAL: $*"; exit $status; }
EC2_INSTANCE_ID="`wget -q -O - http://169.254.169.254/latest/meta-data/instance-id || die \"wget instance-id has failed: $?\"`"

Um exemplo de uso mais avançado (recuperar o ID da instância, bem como a zona e região de disponibilidade, etc.):

EC2_INSTANCE_ID="`wget -q -O - http://169.254.169.254/latest/meta-data/instance-id || die \"wget instance-id has failed: $?\"`"
test -n "$EC2_INSTANCE_ID" || die 'cannot obtain instance-id'
EC2_AVAIL_ZONE="`wget -q -O - http://169.254.169.254/latest/meta-data/placement/availability-zone || die \"wget availability-zone has failed: $?\"`"
test -n "$EC2_AVAIL_ZONE" || die 'cannot obtain availability-zone'
EC2_REGION="`echo \"$EC2_AVAIL_ZONE\" | sed -e 's:\([0-9][0-9]*\)[a-z]*\$:\\1:'`"

Você também pode usar em curlvez de wget, dependendo do que está instalado na sua plataforma.

vladr
fonte
@ Leopd, você obviamente conhece melhor do que as pessoas da Amazon que implementaram o EC2 e escreveram os documentos. Aliás, ninguém o impede de criar um alias para 169.254.169.254, /etc/hostsse isso faz você se sentir mais seguro, você deve ... se importar.
vladr
2
E o Java SDK? Existe alguma maneira de conseguir isso sem ter que fazer um GET nesse URL? Parece estranho, se não é no SDK
Kevin M
11
Muito útil, obrigado. Para outros que tentam descobrir a expressão regular na última linha, eis o que eu criei: No final da linha ( $), encontre um ou mais dígitos seguidos por uma ou mais letras minúsculas. Substitua apenas pelos dígitos. (Parênteses contrabarra + diga sed se lembrar de uma substring, que é recordada com \1.) Eu achei um pouco mais fácil de ler - as únicas barras invertidas são os exigidos pela sed: EC2_REGION="$(echo "$EC2_AVAIL_ZONE" | sed -e 's:\([0-9][0-9]*\)[a-z]*$:\1:')".
Mark Berry
66
Você pode eliminar os números mágicos usando http://instance-data/em vez de169.254.169.254
Jay P.
20
Eu verifiquei isso em 04/02/2016. Descobri que o nome do host "data-instance" não é (a) listado nessa documentação e (b) não funciona (para mim) em um novo host EC2. A documentação - docs.aws.amazon.com/AWSEC2/latest/UserGuide/… - menciona apenas o endereço 169.254 e não menciona o nome do host "instance-data". ou seja, use 169.254.169.254/latest/meta-data/instance-id
JDS 4/16
138

Nas AMIs do Amazon Linux, você pode:

$ ec2-metadata -i
instance-id: i-1234567890abcdef0

Ou, no Ubuntu e em alguns outros tipos de Linux, ec2metadata --instance-id(este comando pode não ser instalado por padrão no ubuntu, mas você pode adicioná-lo sudo apt-get install cloud-utils)

Como o próprio nome sugere, você pode usar o comando para obter outros metadados úteis.

James
fonte
3
Se você estiver pensando em usar isso, este artigo é lido uma pena (TLDR: foi ferramentas de linha de comando são java, java e tem um tempo de inicialização de comprimento)
James
A melhor resposta
Chuck Le Butt
@Marc Nope. Não -depois ec2. Éec2metadata --instance-id
Dawny33
5
O comando é diferente em diferentes Linux: no Amazon Linux ec2-metadata, no Ubuntu, parece ec2metadata.
James
Certo James, eu encontrei os mesmos ec2metadata para trabalhar no Ubuntu.
pyAddict
69

No Ubuntu você pode:

sudo apt-get install cloud-utils

E então você pode:

EC2_INSTANCE_ID=$(ec2metadata --instance-id)

Você pode obter a maioria dos metadados associados à instância desta maneira:

ec2metadata --help
Sintaxe: / usr / bin / ec2metadata [opções]

Consulta e exibição de metadados do EC2.

Se nenhuma opção for fornecida, todas as opções serão exibidas

Opções:
    -h - ajuda a mostrar esta ajuda

    --kernel-id exibe o ID do kernel
    --ramdisk-id exibe o ID do ramdisk
    --reservation-id exibe o ID da reserva

    --ami-id exibe o ami id
    --ami-launch-index exibe o índice ami launch
    --ami-manifest-path exibe o caminho do manifesto ami
    --ancestor-ami-ids exibe o ID do ancestral ami
    --product-codes exibe os códigos de produto associados a ami
    --availability-zone exibe a zona de posicionamento do ami

    --instance-id exibe o ID da instância
    --instance-type exibe o tipo de instância

    --local-hostname exibe o nome do host local
    --public-hostname exibe o nome do host público

    --local-ipv4 exibe o endereço IP local do ipv4
    --public-ipv4 exibe o endereço IP público do ipv4

    --block-device-mapping exibe o ID do dispositivo de bloco
    --security-groups exibe os grupos de segurança

    --mac exibe o endereço mac da instância
    --profile exibe o perfil da instância
    --instance-action exibe a ação da instância

    --public-keys exibe as chaves públicas do openssh
    --user-data exibe os dados do usuário (na verdade não são metadados)
rhunwicks
fonte
No Ubuntu, o lucid apt-get installrecupera a versão 0.11-0ubuntu1, que não contém este utilitário. Foi adicionado ao pacote logo depois .
Aryeh Leib Taurog
7
O pacote cloud-utils está incluído por padrão na AMI do Ubuntu 12.04.1 LTS Cluster Compute.
Andrew Andrew
2
cloud-utils parece estar no RHEL / CentOS também
Craig Ringer
50

Use o /dynamic/instance-identity/documentURL se você também precisar consultar mais do que apenas o ID da sua instância.

wget -q -O - http://169.254.169.254/latest/dynamic/instance-identity/document

Isso fornecerá dados JSON como este - com apenas uma única solicitação .

{
    "devpayProductCodes" : null,
    "privateIp" : "10.1.2.3",
    "region" : "us-east-1",
    "kernelId" : "aki-12345678",
    "ramdiskId" : null,
    "availabilityZone" : "us-east-1a",
    "accountId" : "123456789abc",
    "version" : "2010-08-31",
    "instanceId" : "i-12345678",
    "billingProducts" : null,
    "architecture" : "x86_64",
    "imageId" : "ami-12345678",
    "pendingTime" : "2014-01-23T45:01:23Z",
    "instanceType" : "m1.small"
}
Konrad Kiss
fonte
11
+1 para mostrar todos os detalhes, incluindo instanceType em uma chamada simples
Luksurious 2/14
11
+1 por ter uma linha de trabalho bastante padrão (apenas wget) e (o URL de dados da instância não funcionou para mim no amazon linux), sem instalar pacotes adicionais apenas para esta tarefa simples.
tishma 11/01
27

Para .NETPessoas:

string instanceId = new StreamReader(
      HttpWebRequest.Create("http://169.254.169.254/latest/meta-data/instance-id")
      .GetResponse().GetResponseStream())
    .ReadToEnd();
Mehdi LAMRANI
fonte
24

no AWS Linux:

ec2-metadata --instance-id | cut -d " " -f 2

Resultado:

i-33400429

Usando em variáveis:

ec2InstanceId=$(ec2-metadata --instance-id | cut -d " " -f 2);
ls "log/${ec2InstanceId}/";
gpupo
fonte
Maneira limpa e concisa. Trabalhando fora da caixa para uma instância com o Ubuntu 14.
berbt 23/06
22

Para pessoas com PowerShell:

(New-Object System.Net.WebClient).DownloadString("http://169.254.169.254/latest/meta-data/instance-id")
stefancaunter
fonte
4
apenas diferente commandet:$instanceId=(Invoke-WebRequest -Uri 'http://169.254.169.254/latest/meta-data/instance-id').Content
Sumit Murari
Invoke-WebRequest nem sempre funciona ao executar um script na referida instância do EC2 com um comando ssm send (ou Send-SSMCommand). Isso realmente não diz nos documentos . Possivelmente, não é assíncrono ... o que seria estranho. Mas a opção do stefancaunter funciona sem problemas até agora.
J-Roel
22

Para Python:

import boto.utils
region=boto.utils.get_instance_metadata()['local-hostname'].split('.')[1]

que se resume ao one-liner:

python -c "import boto.utils; print boto.utils.get_instance_metadata()['local-hostname'].split('.')[1]"

Em vez de local_hostname, você também pode usar public_hostname, ou:

boto.utils.get_instance_metadata()['placement']['availability-zone'][:-1]
benlast
fonte
Todas as versões mais recentes do boto que vejo permitem que você chame a chave "instance_id" diretamente. Fiz as edições sugeridas relevantes.
sacarina
8
inst_id = boto.utils.get_instance_metadata () ['instance-id']
atisman
Você percebe que isso mostra a região em que a instância está, não o ID da instância, como a pergunta solicitada, certo?
LukeGT
2
Para quem quer saber, isso está no boto, mas ainda não está no boto3. Consulte stackoverflow.com/a/33733852 para obter uma solução alternativa usando o urllib. Há uma solicitação de recurso aberto em github.com/boto/boto3/issues/313 FWIW, o JS SDK também possui o seguinte: docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/… Usenew AWS.MetadataService().request('instance-id',function(error,data) { myInstanceId = data; })
Armadillo Jim
20

Para todas as máquinas ec2, o ID da instância pode ser encontrado no arquivo:

    /var/lib/cloud/data/instance-id

Você também pode obter o ID da instância executando o seguinte comando:

    ec2metadata --instance-id
Um homem
fonte
2
Esta é uma solução muito limpa, não exigindo uma solicitação HTTP.
Yuri
A melhor resposta possível, na verdade
Shlublu 24/10
11
Ótima resposta, mas não consegui encontrar uma referência para isso na documentação. posso perguntar qual é a sua referência? A preocupação é que, se formos executar esse código em produção, como sabemos que ele não mudará no futuro?
shaya ajzner
Todos linux máquinas EC2, talvez, mas definitivamente não todos máquinas EC2. Esse arquivo não existe no Windows. C:\ProgramData\Amazon\EC2-Windows\Launch\Log\Ec2Launch.logcontém o ID da instância, mas também possui muitos outros itens indesejados.
James
14

Veja este post - observe que o endereço IP no URL fornecido é constante (o que me confundiu a princípio), mas os dados retornados são específicos para sua instância.

gareth_bowles
fonte
Link está 404ing para mim
repalviglator 29/03
Verifique a resposta do @ DEtDev abaixo; minha resposta é bem antiga e parece que o link foi retirado.
gareth_bowles 03/04
10

Para Ruby:

require 'rubygems'
require 'aws-sdk'
require 'net/http'

metadata_endpoint = 'http://169.254.169.254/latest/meta-data/'
instance_id = Net::HTTP.get( URI.parse( metadata_endpoint + 'instance-id' ) )

ec2 = AWS::EC2.new()
instance = ec2.instances[instance_id]
Kevin Meyer
fonte
11
WTF pessoal ?! Você roubou minha edição! stackoverflow.com/review/suggested-edits/4035074
kixorz
3
Desculpa. Não sabia como dizer "É uma boa edição. Eu sou o OP. Aceite isso".
Kevin Meyer
10

Uma solução mais contemporânea.

No Amazon Linux, o comando ec2-metadata já está instalado.

Do terminal

ec2-metadata -help

Oferecerá as opções disponíveis

ec2-metadata -i

retornará

instance-id: yourid
DetDev
fonte
11
muito melhor do que depender do pseudo ip #
Mike D
combine ec2-metadatacom o seu motd, documentos aqui: coderwall.com/p/hr_9pw/motds-on-amazon-amis
Mike D
2
Na imagem do Ubuntu o comando é "ec2metadata --instance-id" e retornará apenas o valor de instância id
Alberto megia
10

Basta digitar:

ec2metadata --instance-id
Akash Arya
fonte
qual AMI você está usando?
Akash Arya
4
Isso é, aparentemente, um comando para a Amazon AMI, você deve atualizar sua resposta
rambossa
@ WédneyYuri Sim.
Akash Arya
9

Você pode tentar isso:

#!/bin/bash
aws_instance=$(wget -q -O- http://169.254.169.254/latest/meta-data/instance-id)
aws_region=$(wget -q -O- http://169.254.169.254/latest/meta-data/hostname)
aws_region=${aws_region#*.}
aws_region=${aws_region%%.*}
aws_zone=`ec2-describe-instances $aws_instance --region $aws_region`
aws_zone=`expr match "$aws_zone" ".*\($aws_region[a-z]\)"`
Alex Koloskov
fonte
8

Uma classe c # .net que escrevi para os metadados do EC2 da api http. Vou construí-lo com a funcionalidade, conforme necessário. Você pode correr com ele, se quiser.

using Amazon;
using System.Net;

namespace AT.AWS
{
    public static class HttpMetaDataAPI
    {
        public static bool TryGetPublicIP(out string publicIP)
        {
            return TryGetMetaData("public-ipv4", out publicIP);
        }
        public static bool TryGetPrivateIP(out string privateIP)
        {
            return TryGetMetaData("local-ipv4", out privateIP);
        }
        public static bool TryGetAvailabilityZone(out string availabilityZone)
        {
            return TryGetMetaData("placement/availability-zone", out availabilityZone);
        }

        /// <summary>
        /// Gets the url of a given AWS service, according to the name of the required service and the AWS Region that this machine is in
        /// </summary>
        /// <param name="serviceName">The service we are seeking (such as ec2, rds etc)</param>
        /// <remarks>Each AWS service has a different endpoint url for each region</remarks>
        /// <returns>True if the operation was succesful, otherwise false</returns>
        public static bool TryGetServiceEndpointUrl(string serviceName, out string serviceEndpointStringUrl)
        {
            // start by figuring out what region this instance is in.
            RegionEndpoint endpoint;
            if (TryGetRegionEndpoint(out endpoint))
            {
                // now that we know the region, we can get details about the requested service in that region
                var details = endpoint.GetEndpointForService(serviceName);
                serviceEndpointStringUrl = (details.HTTPS ? "https://" : "http://") + details.Hostname;
                return true;
            }
            // satisfy the compiler by assigning a value to serviceEndpointStringUrl
            serviceEndpointStringUrl = null;
            return false;
        }
        public static bool TryGetRegionEndpoint(out RegionEndpoint endpoint)
        {
            // we can get figure out the region end point from the availability zone
            // that this instance is in, so we start by getting the availability zone:
            string availabilityZone;
            if (TryGetAvailabilityZone(out availabilityZone))
            {
                // name of the availability zone is <nameOfRegionEndpoint>[a|b|c etc]
                // so just take the name of the availability zone and chop off the last letter
                var nameOfRegionEndpoint = availabilityZone.Substring(0, availabilityZone.Length - 1);
                endpoint = RegionEndpoint.GetBySystemName(nameOfRegionEndpoint);
                return true;
            }
            // satisfy the compiler by assigning a value to endpoint
            endpoint = RegionEndpoint.USWest2;
            return false;
        }
        /// <summary>
        /// Downloads instance metadata
        /// </summary>
        /// <returns>True if the operation was successful, false otherwise</returns>
        /// <remarks>The operation will be unsuccessful if the machine running this code is not an AWS EC2 machine.</remarks>
        static bool TryGetMetaData(string name, out string result)
        {
            result = null;
            try { result = new WebClient().DownloadString("http://169.254.169.254/latest/meta-data/" + name); return true; }
            catch { return false; }
        }

/************************************************************
 * MetaData keys.
 *   Use these keys to write more functions as you need them
 * **********************************************************
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
hostname
instance-action
instance-id
instance-type
local-hostname
local-ipv4
mac
metrics/
network/
placement/
profile
public-hostname
public-ipv4
public-keys/
reservation-id
security-groups
*************************************************************/
    }
}
bboyle1234
fonte
7

O Java SDK mais recente possui EC2MetadataUtils:

Em Java:

import com.amazonaws.util.EC2MetadataUtils;
String myId = EC2MetadataUtils.getInstanceId();

Em Scala:

import com.amazonaws.util.EC2MetadataUtils
val myid = EC2MetadataUtils.getInstanceId
Scott Smith
fonte
5

Para C ++ (usando cURL):

    #include <curl/curl.h>

    //// cURL to string
    size_t curl_to_str(void *contents, size_t size, size_t nmemb, void *userp) {
        ((std::string*)userp)->append((char*)contents, size * nmemb);
        return size * nmemb;
    };

    //// Read Instance-id 
    curl_global_init(CURL_GLOBAL_ALL); // Initialize cURL
    CURL *curl; // cURL handler
    CURLcode res_code; // Result
    string response;
    curl = curl_easy_init(); // Initialize handler
    curl_easy_setopt(curl, CURLOPT_URL, "http://169.254.169.254/latest/meta-data/instance-id");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_to_str);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
    res_code = curl_easy_perform(curl); // Perform cURL
    if (res_code != CURLE_OK) { }; // Error
    curl_easy_cleanup(curl); // Cleanup handler
    curl_global_cleanup(); // Cleanup cURL
Físico médico
fonte
3

Simplesmente verifique o var/lib/cloud/instancelink simbólico, ele deve apontar para /var/lib/cloud/instances/{instance-id}onde {instance_id}está o seu ID da instância.

greg
fonte
11
Eu não usaria isso. É melhor usar a solicitação HTTP aprovada para obter os metadados.
Daisuke Aramaki
3

Se você deseja obter a lista de todas as instâncias em python, aqui está o código:

import boto3

ec2=boto3.client('ec2')
instance_information = ec2.describe_instances()

for reservation in instance_information['Reservations']:
   for instance in reservation['Instances']:
      print(instance['InstanceId'])
Vikas Satpute
fonte
2

FWIW Escrevi um sistema de arquivos FUSE para fornecer acesso ao serviço de metadados do EC2: https://bitbucket.org/dgc/ec2mdfs . Eu executo isso em todas as AMIs personalizadas; permite-me usar este idioma: cat / ec2 / meta-data / ami-id

dgc
fonte
2

No Go, você pode usar o pacote goamz .

import (
    "github.com/mitchellh/goamz/aws"
    "log"
)

func getId() (id string) {
    idBytes, err := aws.GetMetaData("instance-id")
    if err != nil {
        log.Fatalf("Error getting instance-id: %v.", err)
    }

    id = string(idBytes)

    return id
}

Aqui está a fonte GetMetaData.

dmikalova
fonte
1

Na pergunta em que você mencionou o usuário como root, uma coisa que devo mencionar é que o ID da instância não depende do usuário.

Para desenvolvedores de ,

var meta  = new AWS.MetadataService();

meta.request("/latest/meta-data/instance-id", function(err, data){
    console.log(data);
});
Rumesh Eranga Hapuarachchi
fonte
1

Para obter os metadados da instância, use

wget -q -O - http://169.254.169.254/latest/meta-data/instance-id
Soumya Ranjan Mohanty
fonte
0

Você pode simplesmente fazer uma solicitação HTTP para GET Metadata, passando os parâmetros de metadados.

curl http://169.254.169.254/latest/meta-data/instance-id

ou

wget -q -O - http://169.254.169.254/latest/meta-data/instance-id

Você não será cobrado por solicitações HTTP para obter metadados e dados do usuário.

Outro

Você pode usar a Ferramenta de consulta de metadados da instância do EC2, que é um script bash simples que usa curl para consultar os metadados da instância do EC2 de dentro de uma instância do EC2 em execução, conforme mencionado na documentação.

Faça o download da ferramenta:

$ wget http://s3.amazonaws.com/ec2metadata/ec2-metadata

Agora execute o comando para obter os dados necessários.

$ec2metadata -i

Referir:

http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

https://aws.amazon.com/items/1825?externalID=1825

Feliz por ajudar.. :)

Sarat Chandra
fonte
0

Abordagem alternativa para PHP:

$instance = json_decode(file_get_contents('http://169.254.169.254/latest/dynamic/instance-identity/document'),true);
$id = $instance['instanceId'];
print_r($instance);

Isso fornecerá muitos dados sobre a instância, todos bem compactados em uma matriz, sem dependências externas. Como é um pedido que nunca falhou ou atrasou para mim, deve ser seguro fazê-lo dessa maneira, caso contrário, eu usaria curl ()

John
fonte
0

Para PHP:

$instance = json_decode(file_get_contents('http://169.254.169.254/latest/dynamic/instance-identity/document));
$id = $instance['instanceId'];

Editar por @John

Beachhouse
fonte
Mas por que você usaria o GuzzeHttp para esse fim se possui funções nativas e curl no PHP?
John
É a minha preferência. Eu uso o guzzle para muitas outras coisas, é um pré-requisito comum para muitos outros pacotes também.
Beachhouse
$ instance = json_decode (file_get_contents (' 169.254.169.254/latest/dynamic/instance-identity/… ); $ id = $ instance [' instanceId ']; eu sei que o Guzzle é difundido, nunca toquei nele. uma tarefa simples, eu daria a abordagem mais leve. #
John
0

Rode isto:

curl http://169.254.169.254/latest/meta-data/

Você poderá ver os diferentes tipos de atributos fornecidos pelo aws.

Use este link para ver mais

Chinthaka Hasakelum
fonte
0

Todos os metadados relacionados ao recurso EC2 podem ser acessados ​​pela própria instância do EC2 com a ajuda do seguinte comando sendo executado:

ONDULAÇÃO :

http://169.254.169.254/<api-version>/meta-data/<metadata-requested>

Para o seu caso: " metadata-request " deve ser id da instância , " api-version " geralmente é a mais recente que pode ser usada.

Nota adicional: Você também pode obter informações relacionadas aos atributos EC2 abaixo usando o comando acima.

ami-id, ami-launch-index, ami-manifest-path, mapeamento de dispositivo de bloco /, nome do host, iam /, instância-ação, instância-id, tipo de instância, local-hostname, local-ipv4, mac, métricas /, rede /, posicionamento /, perfil, nome do host público, ipv4 público, chaves públicas /, ID de reserva, grupos de segurança, serviços /,

Para mais detalhes, siga este link: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

Vipin Sharma
fonte
0

Para uma instância do Windows:

(wget http://169.254.169.254/latest/meta-data/instance-id).Content

ou

(ConvertFrom-Json (wget http://169.254.169.254/latest/dynamic/instance-identity/document).Content).instanceId
demonicdaron
fonte
0

Para o AWS beanstalk elástico eb cli run eb tags --list

user2584621
fonte