¿Cómo obtener la identificación de la instancia desde una instancia ec2?


Respuestas:


534

Consulte la documentación de EC2 sobre el tema .

Correr:

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

Si necesita acceso programático a la ID de la instancia desde un 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: $?\"`"

Un ejemplo de uso más avanzado (recuperar ID de instancia, así como zona y región de disponibilidad, 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:'`"

También puede usar en curllugar de wget, según lo que esté instalado en su plataforma.


@Leopd, obviamente sabes mejor que las personas de Amazon que implementaron EC2 y escribieron los documentos. Por cierto, nadie le impide crear un alias para 169.254.169.254en /etc/hostscaso de que te hace sentir más seguro, en caso de que ... cuidado.
vladr

2
¿Qué pasa en el SDK de Java? ¿Hay alguna manera de obtener esto sin tener que hacer un GET en esa URL? Parece extraño si no está en el SDK
Kevin M

1
Muy servicial, gracias. Para otros que intentan descubrir la expresión regular en la última línea, esto es lo que se me ocurrió: al final de la línea ( $), encuentre uno o más dígitos seguidos de una o más letras minúsculas. Sustituir solo con los dígitos. (Paréntesis barra invertida + a sed de recordar una subcadena, que se recordó con \1.) Me pareció un poco más fácil de leer - las únicas barras invertidas son las requeridas por el SED: EC2_REGION="$(echo "$EC2_AVAIL_ZONE" | sed -e 's:\([0-9][0-9]*\)[a-z]*$:\1:')".
Mark Berry

66
Puede eliminar los números mágicos usando en http://instance-data/lugar de169.254.169.254
Jay P.

20
Lo comprobé el 04/02/2016. Descubrí que el nombre de host "instancia-datos" (a) no figura en esa documentación, y (b) no funciona (para mí) en un nuevo host EC2. La documentación, docs.aws.amazon.com/AWSEC2/latest/UserGuide/… , solo menciona la dirección 169.254 y no menciona el nombre de host "instancia-datos". es decir, use 169.254.169.254/latest/meta-data/instance-id
JDS

138

En las AMI de Amazon Linux puede hacer:

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

O, en Ubuntu y algunos otros sabores de Linux, ec2metadata --instance-id(este comando puede no estar instalado de manera predeterminada en ubuntu, pero puede agregarlo con sudo apt-get install cloud-utils)

Como su nombre lo indica, también puede usar el comando para obtener otros metadatos útiles.


3
Si está pensando en usar esto, vale la pena leer este artículo (tldr: las herramientas de línea de comandos son Java y Java tiene un tiempo de inicio largo)
James

La mejor respuesta
Chuck Le Butt

@Marc Nope. No -despues ec2. Esec2metadata --instance-id
Dawny33

55
El comando es diferente en diferentes Linux: en Amazon Linux es ec2-metadata, en Ubuntu parece ser ec2metadata.
James

Correcto James, encontré los mismos ec2metadata trabajando en Ubuntu.
pyAddict

69

En Ubuntu puedes:

sudo apt-get install cloud-utils

Y luego puedes:

EC2_INSTANCE_ID=$(ec2metadata --instance-id)

Puede obtener la mayoría de los metadatos asociados con la instancia de esta manera:

ec2metadata --help
Sintaxis: / usr / bin / ec2metadata [opciones]

Consulta y muestra metadatos EC2.

Si no se proporcionan opciones, se mostrarán todas las opciones

Opciones:
    -h - ayuda a mostrar esta ayuda

    --kernel-id muestra la identificación del kernel
    --ramdisk-id muestra la identificación de ramdisk
    --reservation-id muestra la identificación de la reserva

    --ami-id muestra la identificación ami
    --ami-launch-index muestra el índice de lanzamiento de ami
    --ami-manifest-path muestra la ruta ami manifest
    --ancestor-ami-ids muestra la identificación del antepasado ami
    - los códigos de producto muestran los códigos de producto asociados ami
    - zona de disponibilidad muestra la zona de colocación de ami

    --instance-id muestra la identificación de la instancia
    --instance-type muestra el tipo de instancia

    --local-hostname muestra el nombre de host local
    --public-hostname muestra el nombre de host público

    --local-ipv4 muestra la dirección ip ipv4 local
    --public-ipv4 muestra la dirección IP pública de ipv4

    --block-device-mapping muestra la identificación del dispositivo de bloque
    --seguridad-grupos muestran los grupos de seguridad

    --mac muestra la dirección mac de la instancia
    --perfil muestra el perfil de la instancia
    --instance-action muestra la instancia-acción

    --public-keys muestra las claves públicas openssh
    --user-data muestra los datos del usuario (en realidad no son metadatos)

Bajo Ubuntu, apt-get installlucid recupera la versión 0.11-0ubuntu1 que no contiene esta utilidad. Fue agregado al paquete justo después .
Aryeh Leib Taurog

77
El paquete cloud-utils se incluye por defecto en Ubuntu 12.04.1 LTS Cluster Compute AMI.
Andrew

2
las utilidades en la nube también parecen estar en RHEL / CentOS
Craig Ringer

50

Use la /dynamic/instance-identity/documentURL si también necesita consultar más que su ID de instancia.

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

Esto le proporcionará datos JSON como este, con una sola solicitud .

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

1
+1 para mostrar todos los detalles, incluyendo instanceType en una simple llamada
Luksurious

1
+1 por tener una línea bastante estándar (solo wget) y de trabajo (la url de datos de instancia no funcionó para mí en Amazon Linux), sin instalar paquetes adicionales solo para esta simple tarea.
tishma

27

Para .NETpersonas:

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

24

en AWS Linux:

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

Salida:

i-33400429

Utilizando en variables:

ec2InstanceId=$(ec2-metadata --instance-id | cut -d " " -f 2);
ls "log/${ec2InstanceId}/";

Forma limpia y concisa. Trabajando fuera de la caja para una instancia con Ubuntu 14.
berbt

22

Para las personas de PowerShell:

(New-Object System.Net.WebClient).DownloadString("http://169.254.169.254/latest/meta-data/instance-id")

44
simplemente commandet diferente:$instanceId=(Invoke-WebRequest -Uri 'http://169.254.169.254/latest/meta-data/instance-id').Content
Sumit Murari

Invoke-WebRequest no siempre funciona cuando se ejecuta un script en dicha instancia EC2 con un comando de envío ssm (o Send-SSMCommand). Realmente no dice en los documentos . Posiblemente no sea asíncrono ... lo cual sería extraño. Pero la opción de stefancaunter funciona sin problemas hasta ahora.
J-Roel

22

Para Python:

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

que se reduce a una línea:

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

En lugar de local_hostname, también puedes usar public_hostname o:

boto.utils.get_instance_metadata()['placement']['availability-zone'][:-1]

Todas las versiones más recientes de boto que veo le permiten llamar a la clave "instancia_id" directamente. Hice las ediciones sugeridas relevantes.
sacarina

8
inst_id = boto.utils.get_instance_metadata () ['instancia-id']
atisman

Te das cuenta de que esto obtiene la región en la que se encuentra la instancia, no el id de instancia como se hizo la pregunta, ¿verdad?
LukeGT

2
Para cualquiera que se pregunte, esto está en boto pero aún no está en boto3. Consulte stackoverflow.com/a/33733852 para una solución alternativa usando urllib. Hay una solicitud de función abierta en github.com/boto/boto3/issues/313 FWIW, el SDK de JS también tiene esto: docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/… Usonew AWS.MetadataService().request('instance-id',function(error,data) { myInstanceId = data; })
Armadillo Jim

20

Para todas las máquinas ec2, la instancia-id se puede encontrar en el archivo:

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

También puede obtener la identificación de la instancia ejecutando el siguiente comando:

    ec2metadata --instance-id

2
Esta es una solución muy limpia, que no requiere una solicitud HTTP.
Yuri

La mejor respuesta posible en realidad
Shlublu

1
Gran respuesta, pero no pude encontrar una referencia para esto en la documentación. ¿Puedo preguntar cuál es su referencia? La preocupación es que si vamos a ejecutar este código en producción, ¿cómo sabemos que no cambiará en el futuro?
shaya ajzner

Todas las máquinas linux ec2, tal vez, pero definitivamente no todas las máquinas ec2. No existe tal archivo en Windows. C:\ProgramData\Amazon\EC2-Windows\Launch\Log\Ec2Launch.logcontiene el Id. de instancia, pero también tiene muchos otros archivos basura.
James

14

Vea esta publicación : tenga en cuenta que la dirección IP en la URL proporcionada es constante (lo que me confundió al principio), pero los datos devueltos son específicos de su instancia.


Link es 404 para mí
repalviglator

Verifique la respuesta de @ DEtDev a continuación; mi respuesta es bastante antigua y parece que el enlace se ha eliminado.
gareth_bowles

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]

1
WTF chicos? ¡Robaste mi edición! stackoverflow.com/review/suggested-edits/4035074
kixorz

3
Lo siento. No sabía cómo decir "Es una buena edición. Soy el OP. Acepta esto".
Kevin Meyer

10

Una solución más contemporánea.

Desde Amazon Linux, el comando ec2-metadata ya está instalado.

Desde la terminal

ec2-metadata -help

Te dará las opciones disponibles

ec2-metadata -i

volverá

instance-id: yourid

1
mucho mejor que dependiendo de la pseudo ip
Mike D

combine ec2-metadatacon sus motddocumentos aquí: coderwall.com/p/hr_9pw/motds-on-amazon-amis
Mike D

2
En la imagen de Ubuntu, el comando es "ec2metadata --instance-id" y devolverá solo el valor de id de instancia
Alberto Megía


9

Puedes probar esto:

#!/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

Una clase de c # .net que escribí para metadatos EC2 desde la api http. Lo construiré con funcionalidad según sea necesario. Puedes correr con él si te gusta.

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

El último SDK de Java tiene EC2MetadataUtils:

En Java:

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

En 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

Simplemente verifique el var/lib/cloud/instanceenlace simbólico, debe apuntar a /var/lib/cloud/instances/{instance-id}dónde {instance_id}está su id de instancia.


1
No usaría esto. Es mejor usar la solicitud HTTP aprobada para obtener los metadatos.
Daisuke Aramaki el

3

Si desea obtener la lista de ID de todas las instancias en Python, aquí está el 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 Escribí un sistema de archivos FUSE para proporcionar acceso al servicio de metadatos EC2: https://bitbucket.org/dgc/ec2mdfs . Ejecuto esto en todas las AMI personalizadas; me permite usar este modismo: cat / ec2 / meta-data / ami-id


2

En Go puedes usar el paquete 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
}

Aquí está la fuente GetMetaData.


1

En la pregunta que mencionó al usuario como root, una cosa que debo mencionar es que el ID de la instancia no depende del usuario.

Para los desarrolladores de nodos ,

var meta  = new AWS.MetadataService();

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

1

Para obtener los metadatos de la instancia, use

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

0

Puede hacer una solicitud HTTP para OBTENER cualquier metadato pasando los parámetros de sus metadatos.

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

o

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

No se le facturarán las solicitudes HTTP para obtener metadatos y datos de usuario.

Más

Puede usar la herramienta de consulta de metadatos de instancia EC2, que es un script bash simple que usa curl para consultar los metadatos de instancia EC2 desde una instancia EC2 en ejecución como se menciona en la documentación.

Descargue la herramienta:

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

ahora ejecute el comando para obtener los datos requeridos.

$ec2metadata -i

Referir:

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

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

Feliz de ayudar.. :)


0

Enfoque alternativo 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);

Eso proporcionará una gran cantidad de datos sobre la instancia, todo bien empaquetado en una matriz, sin dependencias externas. Como es una solicitud que nunca falló o se retrasó para mí, debería ser seguro hacerlo de esa manera, de lo contrario iría por 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


Pero, ¿por qué usarías GuzzeHttp para ese propósito si tienes funciones curl y nativas en PHP?
John

Es mi preferencia Utilizo guzzle para muchas otras cosas, también es un requisito previo común para muchos otros paquetes.
Beachhouse

$ instance = json_decode (file_get_contents (' 169.254.169.254/latest/dynamic/instance-identity/… ); $ id = $ instance [' instanceId ']; Sé que Guzzle está muy extendido, nunca lo he tocado. una tarea simple proporcionaría el enfoque más ligero.
John


0

La instancia de EC2 puede acceder a todos los metadatos relacionados con el recurso EC2 con la ayuda del siguiente comando que se está ejecutando:

CURL:

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

Para su caso: " metadata-request " debe ser id-instancia , " api-version " suele ser lo último que se puede utilizar.

Nota adicional: También puede obtener información relacionada con los siguientes atributos EC2 utilizando el comando anterior.

ami-id, ami-launch-index, ami-manifest-path, block-device-mapping /, hostname, iam /, instance-action, instance-id, instance-type, local-hostname, local-ipv4, mac, métricas /, red /, ubicación /, perfil, nombre de host público, ipv4 público, claves públicas /, id de reserva, grupos de seguridad, servicios /,

Para obtener más detalles, siga este enlace: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html


0

Para una instancia de Windows:

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

o

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

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.