Come ottenere l'ID istanza dall'interno di un'istanza ec2?


Risposte:


534

Vedi la documentazione EC2 sull'argomento .

Correre:

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

Se è necessario un accesso programmatico all'ID istanza dall'interno di uno 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 esempio di un uso più avanzato (recupero dell'ID istanza, nonché zona e regione di disponibilità, ecc.):

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:'`"

Puoi anche usare curlinvece di wget, a seconda di ciò che è installato sulla tua piattaforma.


@Leopd, ovviamente conosci meglio delle persone di Amazon che hanno implementato EC2 e scritto i documenti. Per inciso, nessuno ti impedisce di creare un alias per 169.254.169.254in /etc/hostsse questo ti fa sentire più sicuro, dovresti ... preoccuparti.
Vladr

2
Che dire di Java SDK? C'è un modo per ottenere questo senza dover fare un GET su quell'URL? Sembra strano se non è nell'SDK
Kevin M,

1
Molto utile, grazie. Per altri che cercano di capire l'espressione regolare nell'ultima riga, ecco cosa mi è venuto in mente: Alla fine della riga ( $), trova una o più cifre che seguono una o più lettere minuscole. Sostituisci solo con le cifre. (Parentesi backslash + dico sed di ricordare una stringa, che viene ricordato con \1.) Ho trovato questo un po 'più facile da leggere - gli unici backslash sono quelli richiesti dalla sed: EC2_REGION="$(echo "$EC2_AVAIL_ZONE" | sed -e 's:\([0-9][0-9]*\)[a-z]*$:\1:')".
Mark Berry,

66
Puoi eliminare i numeri magici usando http://instance-data/invece di169.254.169.254
Jay P.

20
L'ho verificato il 04-02-2016. Ho scoperto che il nome host "istanza-dati" non è (a) elencato in quella documentazione e (b) non funziona (per me) su un nuovo host EC2. La documentazione - docs.aws.amazon.com/AWSEC2/latest/UserGuide/… - menziona solo l'indirizzo 169.254 e non menziona il nome host "istanza-dati". vale a dire utilizzare 169.254.169.254/latest/meta-data/instance-id
JDS

138

Su AMI Amazon Linux puoi fare:

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

Oppure, su Ubuntu e alcune altre versioni di Linux, ec2metadata --instance-id(questo comando potrebbe non essere installato di default su Ubuntu, ma è possibile aggiungerlo con sudo apt-get install cloud-utils)

Come suggerisce il nome, è possibile utilizzare il comando per ottenere anche altri metadati utili.


3
Se stai pensando di usarlo, questo articolo merita una lettura (tldr: gli strumenti della riga di comando sono java e java ha un tempo di avvio lungo)
James,

La migliore risposta
Chuck Le Butt

@Marc Nope. No -dopo ec2. Èec2metadata --instance-id
Dawny33 il

5
Il comando è diverso su diversi Linux: su Amazon Linux è ec2-metadata, su Ubuntu sembra esserlo ec2metadata.
James,

Giusto James, ho trovato gli stessi ec2metadata su Ubuntu.
pyAddict,

69

Su Ubuntu puoi:

sudo apt-get install cloud-utils

E poi puoi:

EC2_INSTANCE_ID=$(ec2metadata --instance-id)

Puoi ottenere la maggior parte dei metadati associati all'istanza in questo modo:

ec2metadata: aiuto
Sintassi: / usr / bin / ec2metadata [opzioni]

Interroga e visualizza metadati EC2.

Se non viene fornita alcuna opzione, verranno visualizzate tutte le opzioni

Opzioni:
    -h --help mostra questo aiuto

    --kernel-id visualizza l'id del kernel
    --ramdisk-id visualizza l'id ramdisk
    --reservation-id visualizza l'id prenotazione

    --ami-id visualizza l'id ami
    --ami-launch-index mostra l'indice di avvio di ami
    --ami-manifest-path mostra il percorso manifest di ami
    --ancestor-ami-ids mostra l'id dell'antenato
    --product-codes visualizza i codici prodotto associati ami
    --availability-zone visualizza la zona di posizionamento degli ami

    --instance-id visualizza l'id dell'istanza
    --instance-type visualizza il tipo di istanza

    --local-hostname visualizza il nome host locale
    --public-hostname visualizza il nome host pubblico

    --local-ipv4 visualizza l'indirizzo IP ipv4 locale
    --public-ipv4 mostra l'indirizzo IP pubblico di ipv4

    --block-device-mapping mostra l'ID del dispositivo a blocchi
    --security-groups visualizza i gruppi di sicurezza

    --mac visualizza l'indirizzo mac dell'istanza
    --profile visualizza il profilo dell'istanza
    --instance-action mostra l'istanza-action

    --public-keys mostra le chiavi pubbliche di openssh
    --user-data mostra i dati dell'utente (in realtà non i metadati)

Sotto Ubuntu lucid apt-get installrecupera la versione 0.11-0ubuntu1 che non contiene questa utility. È stato aggiunto al pacchetto subito dopo .
Aryeh Leib Taurog,

7
Il pacchetto cloud-utils è incluso di default nell'AMI Cluster Compute Ubuntu 12.04.1.
Andrew,

2
cloud-utils sembra essere anche in RHEL / CentOS
Craig Ringer

50

Utilizza l' /dynamic/instance-identity/documentURL se devi anche eseguire una query oltre al tuo ID istanza.

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

In questo modo otterrai dati JSON come questo, con una sola richiesta .

{
    "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 per mostrare tutti i dettagli tra cui istanza
Digita

1
+1 per avere una linea abbastanza standard (solo wget) e funzionante (url istanza-dati non ha funzionato per me su Amazon Linux), senza installare pacchetti aggiuntivi solo per questo semplice compito.
tishma,

27

Per le .NETpersone:

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

24

su AWS Linux:

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

Produzione:

i-33400429

Usando nelle variabili:

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

Modo pulito e conciso. Lavorare fuori dagli schemi per un'istanza con Ubuntu 14.
berbt,

22

Per le persone PowerShell:

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

4
solo diversi comandi:$instanceId=(Invoke-WebRequest -Uri 'http://169.254.169.254/latest/meta-data/instance-id').Content
Sumit Murari

Invoke-WebRequest non sempre funziona quando si esegue uno script su detta istanza EC2 con un comando di invio ssm (o Send-SSMCommand). Non dice davvero nei documenti . Forse a non è asincrono ... il che sarebbe strano. Ma l'opzione di stefancaunter funziona senza problemi finora.
J-Roel,

22

Per Python:

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

che si riduce al one-liner:

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

Invece di local_hostname puoi anche usare public_hostname o:

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

Tutte le versioni più recenti di boto che vedo consentono di chiamare direttamente il tasto "instance_id". Ho apportato le modifiche suggerite pertinenti.
saccarina,

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

Ti rendi conto che questo ottiene la regione in cui si trova l'istanza, non l'ID istanza come la domanda posta, giusto?
LukeGT,

2
Per chiunque si chieda, questo è in boto ma non è ancora in boto3. Consulta stackoverflow.com/a/33733852 per una soluzione alternativa utilizzando urllib. C'è una richiesta di funzionalità aperta su github.com/boto/boto3/issues/313 FWIW, l'SDK JS ha anche questo: docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/… Usonew AWS.MetadataService().request('instance-id',function(error,data) { myInstanceId = data; })
Armadillo Jim

20

Per tutte le macchine ec2, l'istanza-id può essere trovata nel file:

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

È inoltre possibile ottenere l'ID istanza eseguendo il comando seguente:

    ec2metadata --instance-id

2
Questa è una soluzione molto pulita, che non richiede una richiesta HTTP.
Yuri,

La migliore risposta possibile in realtà
Shlublu,

1
Ottima risposta ma non sono riuscito a trovare un riferimento per questo nella documentazione. posso chiederti qual è il tuo riferimento? La preoccupazione è che se eseguiremo questo codice in produzione, come facciamo a sapere che non cambierà in futuro?
shaya ajzner,

Tutte le macchine ec2 di Linux , forse, ma sicuramente non tutte le macchine ec2. Nessun file simile su Windows. C:\ProgramData\Amazon\EC2-Windows\Launch\Log\Ec2Launch.logcontiene l'ID istanza, ma ha anche un sacco di altra spazzatura.
James,

14

Vedi questo post - nota che l'indirizzo IP nell'URL indicato è costante (il che mi ha inizialmente confuso), ma i dati restituiti sono specifici della tua istanza.


Link per me è 404ing
repalviglator

Controlla la risposta di @ DEtDev di seguito; la mia risposta è piuttosto vecchia e sembra che il link sia stato rimosso.
gareth_bowles

10

Per 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
Ragazzi WTF ?! Hai rubato la mia modifica! stackoverflow.com/review/suggested-edits/4035074
kixorz

3
Scusate. Non sapevo dire "È una buona modifica. Sono l'OP. Accettalo".
Kevin Meyer,

10

Una soluzione più contemporanea.

Da Amazon Linux il comando ec2-metadata è già installato.

Dal terminal

ec2-metadata -help

Ti darà le opzioni disponibili

ec2-metadata -i

tornerà

instance-id: yourid

1
molto meglio che a seconda dello pseudo ip
Mike D,

combinano ec2-metadatacon i tuoi motd, documenti qui: coderwall.com/p/hr_9pw/motds-on-amazon-amis
Mike D

2
Nell'immagine Ubuntu il comando è "ec2metadata --instance-id" e restituirà solo il valore ID istanza
Alberto Megía


9

Puoi provare questo:

#!/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 classe c # .net che ho scritto per metadati EC2 da api http. Lo costruirò con funzionalità secondo necessità. Puoi correre con esso se ti piace.

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

L'ultimo SDK Java ha EC2MetadataUtils :

In Java:

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

Alla Scala:

import com.amazonaws.util.EC2MetadataUtils
val myid = EC2MetadataUtils.getInstanceId

5

Per 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

Basta controllare il var/lib/cloud/instancecollegamento simbolico, dovrebbe indicare /var/lib/cloud/instances/{instance-id}dove si {instance_id}trova il tuo ID istanza.


1
Non lo userei. È meglio utilizzare la richiesta HTTP approvata per ottenere i metadati.
Daisuke Aramaki,

3

Se desideri ottenere l'elenco di ID di tutte le istanze in Python ecco il codice:

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 Ho scritto un filesystem FUSE per fornire l'accesso al servizio metadati EC2: https://bitbucket.org/dgc/ec2mdfs . Lo eseguo su tutte le AMI personalizzate; mi permette di usare questo linguaggio: cat / ec2 / meta-data / ami-id


2

In Go puoi usare il pacchetto 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
}

Ecco la fonte GetMetaData.


1

Nella domanda che hai citato l'utente come root, una cosa che dovrei menzionare è che l'ID dell'istanza non dipende dall'utente.

Per gli sviluppatori di nodi ,

var meta  = new AWS.MetadataService();

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

1

Per ottenere i metadati dell'istanza, utilizzare

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

0

Puoi semplicemente fare una richiesta HTTP per ottenere qualsiasi metadata passando i parametri dei metadati.

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

Non ti verranno addebitate richieste HTTP per ottenere metadati e dati utente.

Altro

È possibile utilizzare lo Strumento di query sui metadati dell'istanza EC2, che è un semplice script bash che utilizza curl per eseguire una query sui metadati dell'istanza EC2 dall'interno di un'istanza EC2 in esecuzione, come indicato nella documentazione.

Scarica lo strumento:

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

ora esegui il comando per ottenere i dati richiesti.

$ec2metadata -i

Fare riferimento:

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

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

Felice di aiutare.. :)


0

Approccio alternativo per PHP:

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

Ciò fornirà molti dati sull'istanza, tutti ben confezionati in un array, senza dipendenze esterne. Dato che è una richiesta che non ha mai fallito o ritardato per me, dovrebbe essere sicuro farlo in questo modo, altrimenti andrei per curl ()


0

Per PHP:

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

Modifica per @John


Ma perché dovresti usare GuzzeHttp a tale scopo se hai PHL e funzioni native in PHP?
Giovanni

È la mia preferenza. Uso guzzle per molte altre cose, è un prerequisito comune anche per molti altri pacchetti.
Beachhouse,

$ instance = json_decode (file_get_contents (' 169.254.169.254/latest/dynamic/instance-identity/… ); $ id = $ instance [' instanceId ']; so che Guzzle è molto diffuso, non l'ho mai toccato da solo. un compito semplice fornirei l'approccio più leggero.
Giovanni


0

Tutti i metadati relativi alla risorsa EC2 sono accessibili dall'istanza EC2 stessa con l'aiuto del seguente comando in esecuzione:

CURL:

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

Nel tuo caso: " metadata-request " dovrebbe essere id-istanza , " api-version " è di solito l' ultimo che può essere usato.

Nota aggiuntiva: è inoltre possibile ottenere informazioni relative agli attributi EC2 seguenti utilizzando il comando sopra.

ami-id, ami-launch-index, ami-manifest-path, block-device-mapping /, nome host, iam /, istanza-azione, id-istanza, tipo-istanza, local-hostname, local-ipv4, mac, metriche /, rete /, posizionamento /, profilo, nome host pubblico, ipv4 pubblico, chiavi pubbliche /, id prenotazione, gruppi sicurezza, servizi /,

Per maggiori dettagli, segui questo link: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html


0

Per un'istanza di 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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.