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


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.


@ 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.


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)

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"
}

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

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}/";

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")

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]

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

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.


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]

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

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


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]\)"`

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
*************************************************************/
    }
}

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

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

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.


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

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


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.


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 Nó ,

var meta  = new AWS.MetadataService();

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

1

Para obter os metadados da instância, use

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

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.. :)


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


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


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

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


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

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.