Как получить идентификатор экземпляра из экземпляра ec2?

379

Как я могу узнать instance idэкземпляр ec2 из экземпляра ec2?

ЭЛЕКТРОДИСТАНЦИОННАЯ СИСТЕМА УПРАВЛЕНИЯ
источник

Ответы:

534

См. Документацию EC2 по этому вопросу .

Запустить:

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

Если вам нужен программный доступ к идентификатору экземпляра из скрипта,

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

Пример более сложного использования (получение идентификатора экземпляра, а также зоны доступности и региона и т. Д.):

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

Вы также можете использовать curlвместо wget, в зависимости от того, что установлено на вашей платформе.

vladr
источник
@ Leopd, вы, очевидно, знаете лучше, чем люди из Amazon, которые внедрили EC2 и написали документы. Кстати, никто не мешает вам от создания псевдонима 169.254.169.254в /etc/hostsслучае , что заставляет вас чувствовать себя более безопасно, вы должны ... уход.
vladr
2
Как насчет Java SDK? Есть ли способ получить это, не делая GET по этому URL? Кажется странным, если его нет в SDK
Кевин М
1
Очень полезно, спасибо. Для других, пытающихся выяснить регулярное выражение в последней строке, вот что я придумал: В конце строки ( $) найдите одну или несколько цифр, за которыми следуют одна или несколько строчных букв. Подставлять только цифрами. (Обратный слеш + Скобки расскажите СЭД помнить подстроку, которая будет вызвана с \1.) Я нашел это немного легче читать - только обратные косые являются те , которые требуются СЭД: EC2_REGION="$(echo "$EC2_AVAIL_ZONE" | sed -e 's:\([0-9][0-9]*\)[a-z]*$:\1:')".
Марк Берри
66
Вы можете устранить магические числа, используя http://instance-data/вместо169.254.169.254
Jay P.
20
Я проверял это 2016-02-04. Я обнаружил, что имя хоста "instance-data" (а) не указано в этой документации и (б) не работает (для меня) на новом хосте EC2. В документации - docs.aws.amazon.com/AWSEC2/latest/UserGuide/… - упоминается только адрес 169.254 и не упоминается имя хоста "instance-data". то есть используйте 169.254.169.254/latest/meta-data/instance-id
JDS
138

На Amazon Linux AMI вы можете сделать:

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

Или в Ubuntu и некоторых других разновидностях Linux ec2metadata --instance-id(эта команда может быть не установлена ​​по умолчанию в Ubuntu, но вы можете добавить ее с помощью sudo apt-get install cloud-utils)

Как следует из его названия, вы можете использовать команду для получения других полезных метаданных.

Джеймс
источник
3
Если вы думаете об этом, стоит прочитать эту статью (tldr: если инструменты командной строки являются java, а у java много времени запуска)
James
Лучший ответ
Чак Ле Батт
@ Марк Нет. Нет -после ec2. Этоec2metadata --instance-id
Dawny33
5
Команда отличается в разных Linux: в Amazon Linux она есть ec2-metadata, в Ubuntu она, кажется, такова ec2metadata.
Джеймс
Правильно, Джеймс, я обнаружил, что те же самые ec2metadata работают с Ubuntu.
pyAddict
69

На Ubuntu вы можете:

sudo apt-get install cloud-utils

И тогда вы можете:

EC2_INSTANCE_ID=$(ec2metadata --instance-id)

Вы можете получить большую часть метаданных, связанных с экземпляром, следующим образом:

ec2metadata --help
Синтаксис: / usr / bin / ec2metadata [параметры]

Запрос и отображение метаданных EC2.

Если опции не предоставлены, будут отображены все опции

Опции:
    -h - Помогите показать эту помощь

    --kernel-id показать идентификатор ядра
    --ramdisk-id показать идентификатор ramdisk
    --reservation-id показать идентификатор бронирования

    --ami-id показать идентификатор ami
    --ami-launch-index показать индекс запуска ami
    --ami-manifest-path отобразить путь манифеста ami
    --ancestor-ami-ids отображает идентификатор предка ami
    --product-коды отображают ами связанные коды продуктов
    --availability-zone отображать зону размещения ami

    --instance-id показать идентификатор экземпляра
    --instance-type показать тип экземпляра

    --local-hostname отображать локальное имя хоста
    --public-hostname отображать публичное имя хоста

    --local-ipv4 отображать локальный IP-адрес ipv4
    --public-ipv4 отображать публичный IP-адрес ipv4

    --block-device-mapping отображает идентификатор блочного устройства
    --security-groups отображают группы безопасности

    --mac показать mac-адрес экземпляра
    --profile показать профиль экземпляра
    --instance-action показать действие экземпляра

    --public-keys отображает открытые ключи openssh
    --user-data отображать пользовательские данные (на самом деле не метаданные)
rhunwicks
источник
Под Ubuntu lucid apt-get installполучает версию 0.11-0ubuntu1, которая не содержит эту утилиту. Он был добавлен в пакет сразу после этого .
Арье Лейб Таурог
7
Пакет cloud-utils включен по умолчанию в Ubuntu 12.04.1 LTS Cluster Compute AMI.
Андрей
2
Облачные утилиты, кажется, тоже в RHEL / CentOS
Крейг Рингер
50

Используйте /dynamic/instance-identity/documentURL-адрес, если вам также нужно запросить не только идентификатор вашего экземпляра.

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

Это позволит вам получить данные в формате JSON, такие как этот, - всего за один запрос .

{
    "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 за отображение всех деталей, включая instanceType, за один простой вызов
Luksurious
1
+1 за то, что у меня довольно стандартная (только wget) и рабочая строка (экземпляр-data-url у меня не работает на amazon linux), без установки дополнительных пакетов только для этой простой задачи.
Тишма
27

Для .NETлюдей:

string instanceId = new StreamReader(
      HttpWebRequest.Create("http://169.254.169.254/latest/meta-data/instance-id")
      .GetResponse().GetResponseStream())
    .ReadToEnd();
Мехди ЛАМРАНИ
источник
24

в AWS Linux:

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

Вывод:

i-33400429

Использование в переменных:

ec2InstanceId=$(ec2-metadata --instance-id | cut -d " " -f 2);
ls "log/${ec2InstanceId}/";
gpupo
источник
Чистый и лаконичный способ. Разработка из коробки для экземпляра с Ubuntu 14.
berbt
22

Для пользователей PowerShell:

(New-Object System.Net.WebClient).DownloadString("http://169.254.169.254/latest/meta-data/instance-id")
stefancaunter
источник
4
просто другой командир:$instanceId=(Invoke-WebRequest -Uri 'http://169.254.169.254/latest/meta-data/instance-id').Content
Сумит Мурари
Invoke-WebRequest не всегда работает при запуске сценария на указанном экземпляре EC2 с помощью команды ssm send (или Send-SSMCommand). Это действительно не сказано в документах . Возможно, это не асинхронно ... что было бы странно. Но вариант stefancaunter пока работает без проблем.
J-Roel
22

Для Python:

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

который сводится к одной строке:

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

Вместо local_hostname вы также можете использовать public_hostname или:

boto.utils.get_instance_metadata()['placement']['availability-zone'][:-1]
benlast
источник
Все новые версии boto, которые я вижу, позволяют напрямую вызывать ключ "instance_id". Я сделал соответствующие предлагаемые изменения.
сахарин
8
inst_id = boto.utils.get_instance_metadata () ['instance-id']
atisman
Вы понимаете, что это получает регион, в котором находится экземпляр, а не идентификатор экземпляра, как заданный вопрос, верно?
LukeGT
2
Для всех, кто интересуется, это в boto, но еще не в boto3. См. Stackoverflow.com/a/33733852 для обхода проблемы с использованием urllib. На github.com/boto/boto3/issues/313 есть FWIW, в JS SDK также есть следующее: docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/… Использованиеnew AWS.MetadataService().request('instance-id',function(error,data) { myInstanceId = data; })
Armadillo Jim
20

Для всех компьютеров ec2 идентификатор экземпляра можно найти в файле:

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

Вы также можете получить идентификатор экземпляра, выполнив следующую команду:

    ec2metadata --instance-id
Человек
источник
2
Это очень чистое решение, не требующее HTTP-запроса.
Юрий
Самый лучший ответ на самом деле
Shlublu
1
Отличный ответ, но я не смог найти ссылку на это в документации. Могу ли я спросить, что ваша ссылка? Проблема заключается в том, что если мы собираемся запустить этот код в производстве, откуда мы знаем, что он не изменится в будущем?
Шая Айзнер
Все Linux EC2 машина, может быть, но определенно не все EC2 машина. Нет такого файла в Windows. C:\ProgramData\Amazon\EC2-Windows\Launch\Log\Ec2Launch.logсодержит идентификатор экземпляра, но также имеет много другого мусора.
Джеймс
14

См. Этот пост - обратите внимание, что IP-адрес в указанном URL-адресе является постоянным (что меня сначала смутило), но возвращаемые данные относятся к вашему экземпляру.

gareth_bowles
источник
Ссылка для меня
404
Проверьте ответ @ DEtDev ниже; мой ответ довольно старый и похоже, что ссылка была удалена.
gareth_bowles
10

Для Руби:

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 ребята ?! Вы украли мою правку! stackoverflow.com/review/suggested-edits/4035074
kixorz
3
Сожалею. Не знал, как сказать: «Это хорошее редактирование. Я ОП. Примите это».
Кевин Мейер
10

Более современное решение.

Из Amazon Linux команда ec2-metadata уже установлена.

Из терминала

ec2-metadata -help

Даст вам доступные варианты

ec2-metadata -i

вернусь

instance-id: yourid
DetDev
источник
1
гораздо лучше, чем в зависимости от псевдо ip
Майк Д
в сочетании ec2-metadataс вашими motdдокументами здесь: coderwall.com/p/hr_9pw/motds-on-amazon-amis
Майк Д
2
В образе Ubuntu команда "ec2metadata --instance-id" и будет возвращать только значение идентификатора экземпляра
Alberto Megía
10

Просто введите:

ec2metadata --instance-id
Акаш Арья
источник
какой AMI вы используете?
Акаш Арья
4
Видимо, это команда для Amazon AMI, вы должны обновить свой ответ
rambossa
@ WédneyYuri Да.
Акаш Арья
9

Вы можете попробовать это:

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

C # .net класс, который я написал для метаданных EC2 из HTTP API. Я буду строить его с функциональностью по мере необходимости. Вы можете работать с ним, если вам это нравится.

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
источник
7

Последний Java SDK имеет EC2MetadataUtils:

В Java:

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

В Скала:

import com.amazonaws.util.EC2MetadataUtils
val myid = EC2MetadataUtils.getInstanceId
Скотт Смит
источник
5

Для C ++ (с использованием 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

Просто проверьте var/lib/cloud/instanceсимволическую ссылку, она должна указывать, /var/lib/cloud/instances/{instance-id}где {instance_id}находится ваш экземпляр экземпляра.

Greg
источник
1
Я бы не стал этим пользоваться. Вам лучше использовать утвержденный HTTP-запрос для получения метаданных.
Дайсуке Арамаки
3

Если вы хотите получить список всех экземпляров в Python, вот код:

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 Я написал файловую систему FUSE для обеспечения доступа к службе метаданных EC2: https://bitbucket.org/dgc/ec2mdfs . Я запускаю это на всех пользовательских AMI; это позволяет мне использовать эту идиому: cat / ec2 / meta-data / ami-id

DGC
источник
2

В Go вы можете использовать пакет 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
}

Вот источник GetMetaData.

dmikalova
источник
1

В вопросе, который вы упомянули в качестве пользователя root, я должен упомянуть одну вещь: идентификатор экземпляра не зависит от пользователя.

Для разработчиков Node ,

var meta  = new AWS.MetadataService();

meta.request("/latest/meta-data/instance-id", function(err, data){
    console.log(data);
});
Румеш Эранга Хапуараччи
источник
1

Для получения метаданных экземпляра используйте

wget -q -O - http://169.254.169.254/latest/meta-data/instance-id
Soumya Ranjan Mohanty
источник
0

Вы можете просто сделать HTTP-запрос для получения любых метаданных, передав параметры ваших метаданных.

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

или

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

Вам не нужно будет оплачивать HTTP-запросы для получения метаданных и пользовательских данных.

еще

Вы можете использовать инструмент запроса метаданных экземпляра EC2, который представляет собой простой bash-скрипт, который использует curl для запроса метаданных экземпляра EC2 из запущенного экземпляра EC2, как упомянуто в документации.

Загрузите инструмент:

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

Теперь запустите команду, чтобы получить необходимые данные.

$ec2metadata -i

См:

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

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

Рад помочь.. :)

Сарат Чандра
источник
0

Альтернативный подход для PHP:

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

Это предоставит много данных об экземпляре, все красиво упаковано в массив, без внешних зависимостей. Поскольку это запрос, который никогда не был для меня неудачным или отложенным, было бы безопасно сделать это таким образом, иначе я бы пошел на curl ()

Джон
источник
0

Для PHP:

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

Редактировать за @Джон

Пляжный домик
источник
Но зачем вам использовать GuzzeHttp для этой цели, если у вас есть функции curl и native в PHP?
Джон
Это мое предпочтение. Я использую жадность для многих других вещей, это также является обязательным условием для многих других пакетов.
Beachhouse
$ instance = json_decode (file_get_contents (' 169.254.169.254/latest/dynamic/instance-identity/… ); $ id = $ instance [' instanceId ']; я знаю, что Guzzle широко распространен, я сам никогда его не трогал. Для таких простое задание, которое я бы обеспечил самым легким подходом
Джон
0

Все метаданные, относящиеся к ресурсу EC2, могут быть доступны для самого экземпляра EC2 с помощью следующей выполняемой команды:

CURL:

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

Для вашего случая: « metadata-required » должно быть instance-id , « api-version » обычно самое последнее что можно использовать.

Дополнительное примечание: Вы также можете получить информацию, относящуюся к атрибутам ниже EC2, используя вышеуказанную команду.

ami-id, ami-launch-index, ami-manifest-path, block-device-mapping /, имя хоста, iam /, instance-action, instance-id, тип экземпляра, local-hostname, local-ipv4, mac, метрики /, сеть /, размещение /, профиль, публичное имя хоста, публичный ipv4, публичные ключи /, идентификатор резервирования, группы безопасности, услуги /,

Для получения более подробной информации перейдите по этой ссылке: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

Випин Шарма
источник
0

Для экземпляра Windows:

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

или

(ConvertFrom-Json (wget http://169.254.169.254/latest/dynamic/instance-identity/document).Content).instanceId
demonicdaron
источник
0

Для упругого стебля AWS eb cli run eb tags --list

user2584621
источник