Jak uzyskać identyfikator instancji z poziomu instancji ec2?

379

Jak mogę znaleźć instance idinstancję ec2 z poziomu instancji ec2?

Lecieć jak po sznurku
źródło

Odpowiedzi:

534

Zobacz dokumentację EC2 na ten temat .

Biegać:

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

Jeśli potrzebujesz programowego dostępu do identyfikatora instancji z poziomu skryptu,

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: $?\"`"

Przykład bardziej zaawansowanego zastosowania (pobierz identyfikator instancji oraz strefę dostępności i region itp.):

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

Możesz również użyć curlzamiast wget, w zależności od tego, co jest zainstalowane na twojej platformie.

Vladr
źródło
@Leopd, oczywiście znasz lepiej niż ludzie w Amazon, którzy zaimplementowali EC2 i napisali dokumenty. Nawiasem mówiąc, nikt nie zatrzyma cię od tworzenia alias 169.254.169.254w /etc/hostsrazie sprawia, że czujesz się bardziej bezpieczny, należy ... opieki.
vladr
2
Co z pakietem Java SDK? Czy jest jakiś sposób na uzyskanie tego bez konieczności sprawdzania adresu URL? Wydaje się dziwne, jeśli nie ma go w zestawie SDK
Kevin M
1
Bardzo pomocny, dzięki. Dla innych próbujących znaleźć wyrażenie regularne w ostatnim wierszu, oto co wymyśliłem: Na końcu wiersza ( $) znajdź jedną lub więcej cyfr, po których następuje jedna lub więcej małych liter. Zastępuj tylko cyframi. (Backslash + nawiasy powiedz sed pamiętać podciąg, który przypomniał, z \1). Uważam, że to trochę łatwiejsze do odczytania - jedynymi backslashe są te wymagane przez sed: EC2_REGION="$(echo "$EC2_AVAIL_ZONE" | sed -e 's:\([0-9][0-9]*\)[a-z]*$:\1:')".
Mark Berry
66
Możesz wyeliminować magiczne liczby, używając http://instance-data/zamiast169.254.169.254
Jay P.
20
Sprawdziłem to 04.02.2016. Odkryłem, że nazwa hosta „instancja-dane” nie jest (a) wymieniona w tej dokumentacji i (b) nie działa (dla mnie) na nowym hoście EC2. Dokumentacja - docs.aws.amazon.com/AWSEC2/latest/UserGuide/… - wspomina tylko o adres 169,254 i nie wspomina o nazwie hosta „instancja-dane”. tj. użyj 169.254.169.254/latest/meta-data/instance-id
JDS
138

W AMI Amazon Linux możesz:

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

Lub w Ubuntu i niektórych innych wersjach linuksowych ec2metadata --instance-id(To polecenie może nie być domyślnie instalowane w Ubuntu, ale możesz je dodać sudo apt-get install cloud-utils)

Jak sama nazwa wskazuje, możesz użyć polecenia, aby uzyskać także inne przydatne metadane.

James
źródło
3
Jeśli zastanawiasz się nad użyciem tego, ten artykuł jest wart przeczytania (tldr: czy narzędzia wiersza poleceń to java, a java ma długi czas uruchamiania)
James
Najlepsza odpowiedź
Chuck Le Butt,
@Marc Nope. Nie -po ec2. Jestec2metadata --instance-id
Dawny33,
5
Komenda jest inna w różnych systemach Linux: w Amazon Linux jest ec2-metadata, na Ubuntu wydaje się, że tak ec2metadata.
James
Tak, James, znalazłem te same ec2metadata, które działają na Ubuntu.
pyAddict
69

W Ubuntu możesz:

sudo apt-get install cloud-utils

A potem możesz:

EC2_INSTANCE_ID=$(ec2metadata --instance-id)

Większość metadanych powiązanych z instancją można uzyskać w następujący sposób:

ec2metadata --help
Składnia: / usr / bin / ec2metadata [opcje]

Zapytanie i wyświetlenie metadanych EC2.

Jeśli nie podano żadnych opcji, zostaną wyświetlone wszystkie opcje

Opcje:
    -h --help pokaż tę pomoc

    --kernel-id wyświetla identyfikator jądra
    --ramdisk-id wyświetla identyfikator ramdysku
    - identyfikator-rezerwacji wyświetla identyfikator rezerwacji

    --ami-id wyświetla identyfikator ami
    --ami-launch-index wyświetla indeks uruchamiania ami
    --ami-manifest-path wyświetla ścieżkę manifestu ami
    --ancestor-ami-ids wyświetla identyfikator przodka ami
    - kody produktów wyświetlają kody produktów powiązane z ami
    --availability-zone wyświetla strefę umieszczania ami

    --instance-id wyświetla identyfikator instancji
    --instance-type wyświetla typ instancji

    --local-hostname wyświetla lokalną nazwę hosta
    --public-hostname wyświetla publiczną nazwę hosta

    --local-ipv4 wyświetla lokalny adres IP ipv4
    --public-ipv4 wyświetla publiczny adres IP ipv4

    --block-mapowanie urządzeń wyświetla identyfikator urządzenia blokowego
    --security-groups wyświetla grupy zabezpieczeń

    --mac wyświetla adres mac instancji
    --profile wyświetla profil instancji
    --instance-action wyświetla akcję instancji

    --publiczne-klucze wyświetlają klucze publiczne openssh
    - dane użytkownika wyświetlają dane użytkownika (nie metadane)
rhunwicks
źródło
W Ubuntu lucid apt-get installpobiera wersję 0.11-0ubuntu1, która nie zawiera tego narzędzia. Został on dodany do pakietu tuż potem .
Aryeh Leib Taurog
7
Pakiet cloud-utils jest domyślnie dołączony do Ubuntu 12.04.1 LTS Cluster Compute AMI.
Andrew
2
cloud-utils wydaje się być również w RHEL / CentOS
Craig Ringer
50

Użyj /dynamic/instance-identity/documentadresu URL, jeśli chcesz zapytać o coś więcej niż tylko identyfikator instancji.

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

To będzie Ci JSON dane, takie jak ten - z tylko pojedynczego żądania .

{
    "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
źródło
1
+1 za pokazanie wszystkich szczegółów, w tym instanceType w jednym prostym wywołaniu
Luksurious
1
+1 za posiadanie dość standardowej (tylko wget) i działającej linii (URL danych instancji nie działał dla mnie na amazonie linux), bez instalowania dodatkowych pakietów tylko dla tego prostego zadania.
tishma
27

Dla .NETludzi:

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

w systemie AWS Linux:

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

Wynik:

i-33400429

Używanie w zmiennych:

ec2InstanceId=$(ec2-metadata --instance-id | cut -d " " -f 2);
ls "log/${ec2InstanceId}/";
gpupo
źródło
Czysty i zwięzły sposób. Praca po wyjęciu z pudełka dla instancji z Ubuntu 14.
berbt
22

Dla osób PowerShell:

(New-Object System.Net.WebClient).DownloadString("http://169.254.169.254/latest/meta-data/instance-id")
stefancaunter
źródło
4
po prostu inny komendant:$instanceId=(Invoke-WebRequest -Uri 'http://169.254.169.254/latest/meta-data/instance-id').Content
Sumit Murari
Invoke-WebRequest nie zawsze działa podczas uruchamiania skryptu we wspomnianej instancji EC2 za pomocą komendy send ssm (lub Send-SSMCommand). Tak naprawdę nie mówi się w dokumentach . Być może nie jest to asynchroniczne ... co byłoby dziwne. Ale opcja stefancaunter działa do tej pory bez żadnych problemów.
J-Roel,
22

W przypadku Python:

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

który sprowadza się do jednowarstwowej:

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

Zamiast local_hostname możesz także użyć public_hostname lub:

boto.utils.get_instance_metadata()['placement']['availability-zone'][:-1]
benlast
źródło
Wszystkie nowsze wersje boto, które widzę, pozwalają bezpośrednio wywołać klucz „instance_id”. Dokonałem odpowiednich sugerowanych zmian.
sacharyna
8
inst_id = boto.utils.get_instance_metadata () ['instance-id']
atisman
Zdajesz sobie sprawę, że dzięki temu otrzymujesz region, w którym znajduje się instancja, a nie identyfikator instancji zgodnie z pytaniem, prawda?
LukeGT
2
Dla każdego, kto się zastanawia, jest to w boto, ale nie jest jeszcze w boto3. Zobacz stackoverflow.com/a/33733852 do obejścia przy użyciu urllib. Na stronie github.com/boto/boto3/issues/313 FWIW jest otwarta prośba o dodanie funkcji, JS SDK ma również: docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/… Zastosowanienew AWS.MetadataService().request('instance-id',function(error,data) { myInstanceId = data; })
Armadillo Jim
20

Dla wszystkich maszyn ec2 identyfikator instancji można znaleźć w pliku:

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

Identyfikator instancji można również uzyskać, uruchamiając następującą komendę:

    ec2metadata --instance-id
Mężczyzna
źródło
2
To bardzo czyste rozwiązanie, niewymagające żądania HTTP.
Yuri
Właściwie najlepsza możliwa odpowiedź
Shlublu
1
Świetna odpowiedź, ale nie mogłem znaleźć odniesienia do tego w dokumentacji. czy mogę zapytać o twoje referencje? Problem polega na tym, że jeśli zamierzamy uruchomić ten kod w środowisku produkcyjnym, skąd wiemy, że nie zmieni się on w przyszłości?
shaya ajzner,
Wszystkie linux maszyny EC2, być może, ale na pewno nie wszystkie maszyny EC2. Brak takiego pliku w systemie Windows. C:\ProgramData\Amazon\EC2-Windows\Launch\Log\Ec2Launch.logzawiera identyfikator wystąpienia, ale ma też wiele innych śmieci.
James
14

Zobacz ten post - zauważ, że adres IP w podanym adresie URL jest stały (co początkowo mnie pomyliło), ale zwrócone dane są specyficzne dla twojej instancji.

gareth_bowles
źródło
Link to 404 dla mnie
repalviglator
Sprawdź odpowiedź @ DEtDev poniżej; moja odpowiedź jest dość stara i wygląda na to, że link został usunięty.
gareth_bowles
10

Dla 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
źródło
1
Faceci z WTF ?! Ukradłeś moją edycję! stackoverflow.com/review/suggested-edits/4035074
kixorz
3
Przepraszam. Nie wiedziałem, jak powiedzieć „To dobra edycja. Jestem OP. Zaakceptuj to”.
Kevin Meyer
10

Bardziej współczesne rozwiązanie.

W systemie Amazon Linux polecenie ec2-metadata jest już zainstalowane.

Z terminala

ec2-metadata -help

Daje ci dostępne opcje

ec2-metadata -i

wróci

instance-id: yourid
DetDev
źródło
1
znacznie lepiej niż w zależności od pseudo ip
Mike D
połącz ec2-metadataz motddokumentami tutaj: coderwall.com/p/hr_9pw/motds-on-amazon-amis
Mike D
2
W obrazie Ubuntu polecenie to „ec2metadata --instance-id” i zwróci tylko wartość identyfikatora instancji
Alberto Megía
10

Po prostu wpisz:

ec2metadata --instance-id
Akash Arya
źródło
z którego AMI korzystasz?
Akash Arya
4
Najwyraźniej to polecenie dla Amazon AMI, powinieneś zaktualizować swoją odpowiedź
rambossa
@ WédneyYuri Tak.
Akash Arya
9

Możesz spróbować:

#!/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
źródło
8

Klasa c # .net, którą napisałem dla metadanych EC2 z interfejsu API http. W razie potrzeby zbuduję go z funkcjonalnością. Możesz z nim biegać, jeśli ci się podoba.

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
źródło
7

Najnowszy Java SDK ma EC2MetadataUtils:

W Javie:

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

W Scali:

import com.amazonaws.util.EC2MetadataUtils
val myid = EC2MetadataUtils.getInstanceId
Scott Smith
źródło
5

Dla C ++ (przy użyciu 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
Fizyk medyczny
źródło
3

Po prostu sprawdź var/lib/cloud/instancedowiązanie symboliczne, powinno wskazywać, /var/lib/cloud/instances/{instance-id}gdzie {instance_id}jest twój identyfikator instancji.

greg
źródło
1
Nie użyłbym tego. Lepiej skorzystaj z zatwierdzonego żądania HTTP, aby uzyskać metadane.
Daisuke Aramaki
3

Jeśli chcesz uzyskać listę identyfikatorów wszystkich instancji w pythonie, oto kod:

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
źródło
2

FWIW Napisałem system plików FUSE, aby zapewnić dostęp do usługi metadanych EC2: https://bitbucket.org/dgc/ec2mdfs . Uruchomię to na wszystkich niestandardowych AMI; pozwala mi używać tego idiomu: cat / ec2 / meta-data / ami-id

dgc
źródło
2

W Go możesz użyć pakietu 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
}

Oto źródło GetMetaData.

dmikalova
źródło
1

W pytaniu, w którym wspomniałeś użytkownika jako root, należy wspomnieć, że identyfikator instancji nie jest zależny od użytkownika.

Dla programistów Node

var meta  = new AWS.MetadataService();

meta.request("/latest/meta-data/instance-id", function(err, data){
    console.log(data);
});
Rumesh Eranga Hapuarachchi
źródło
1

Aby uzyskać metadane instancji, użyj

wget -q -O - http://169.254.169.254/latest/meta-data/instance-id
Soumya Ranjan Mohanty
źródło
0

Możesz po prostu wysłać żądanie HTTP, aby uzyskać dowolne metadane, przekazując parametry metadanych.

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

lub

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

Nie będą naliczane opłaty za żądania HTTP, aby uzyskać metadane i dane użytkownika.

Jeszcze

Można użyć narzędzia do wysyłania zapytań o metadane instancji EC2, które jest prostym skryptem bash, który używa curl do zapytania o metadane instancji EC2 z działającej instancji EC2, jak wspomniano w dokumentacji.

Pobierz narzędzie:

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

teraz uruchom polecenie, aby uzyskać wymagane dane.

$ec2metadata -i

Odnosić się:

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

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

Chętnie pomoże.. :)

Sarat Chandra
źródło
0

Alternatywne podejście do PHP:

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

Zapewni to dużo danych o instancji, wszystkie ładnie zapakowane w tablicę, bez zewnętrznych zależności. Ponieważ jest to prośba, która nigdy mnie nie zawiodła ani nie opóźniła, powinno być bezpiecznie zrobić to w ten sposób, w przeciwnym razie wybrałbym curl ()

Jan
źródło
0

Dla PHP:

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

Edytuj według @John

Dom na plaży
źródło
Ale dlaczego miałbyś używać GuzzeHttp do tego celu, jeśli masz funkcje curl i natywne w PHP?
Jan
To moja preferencja. Używam guzzle do wielu innych rzeczy, jest to również wspólny warunek dla wielu innych pakietów.
Beachhouse,
$ instance = json_decode (file_get_contents (' 169.254.169.254/latest/dynamic/instance-identity/… ); $ id = $ instance [' instanceId ']; Wiem, że Guzzle jest szeroko rozpowszechniony, sam go nie dotykałem. Dla takich proste zadanie zapewniłbym najlżejsze podejście
John
0

Do wszystkich metadanych związanych z zasobem EC2 może uzyskać dostęp sama instancja EC2 za pomocą następującego polecenia:

CURL:

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

W twoim przypadku: „ żądanie metadanych ” powinno być identyfikatorem instancji , „ wersja interfejsu API ” jest zwykle najnowsza, której można użyć.

Uwaga dodatkowa: Można również uzyskać informacje związane z poniższymi atrybutami EC2 za pomocą powyższego polecenia.

ami-id, ami-launch-index, ami-manifest-path, block-device-mapping /, nazwa hosta, iam /, instance-action, instance-id, typ-instancji, local-nazwa hosta, local-ipv4, mac, metrics /, network /, placement /, profile, public-hostname, public-ipv4, public-keys /, booking-id, security-groups, services /,

Aby uzyskać więcej informacji, kliknij ten link: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

Vipin Sharma
źródło
0

W przypadku instancji Windows:

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

lub

(ConvertFrom-Json (wget http://169.254.169.254/latest/dynamic/instance-identity/document).Content).instanceId
demonicdaron
źródło
0

Do elastycznej łodygi AWS eb cli run eb tags --list

użytkownik2584621
źródło