Bagaimana cara mendapatkan instance id dari dalam instance EC2?

379

Bagaimana saya bisa mengetahui instance idcontoh instance EC2 dari dalam instance EC2?

flybywire
sumber

Jawaban:

534

Lihat dokumentasi EC2 tentang masalah ini .

Lari:

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

Jika Anda memerlukan akses terprogram ke instance ID dari dalam skrip,

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

Contoh penggunaan yang lebih lanjut (ambil ID instan serta zona ketersediaan dan wilayah, dll.):

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

Anda juga dapat menggunakan curlsebagai gantinya wget, tergantung pada apa yang diinstal pada platform Anda.

vladr
sumber
@Leopd, Anda jelas tahu lebih baik daripada orang-orang di Amazon yang menerapkan EC2 dan menulis dokumen. Kebetulan, tidak ada yang menghentikan Anda dari membuat alias untuk 169.254.169.254di /etc/hostsjika itu membuat Anda merasa lebih aman, sebaiknya Anda ... peduli.
vladr
2
Bagaimana dengan Java SDK? Apakah ada cara untuk mendapatkan ini tanpa harus melakukan GET pada url itu? Tampaknya aneh jika tidak ada di SDK
Kevin M
1
Terima kasih banyak. Bagi yang lain yang mencoba mencari tahu persamaan reguler di baris terakhir, inilah yang saya dapatkan: Di akhir baris ( $), cari satu atau lebih digit yang diikuti oleh satu atau lebih huruf kecil. Pengganti dengan digit saja. (Backslash + kurung tell sed mengingat substring, yang teringat dengan \1.) Saya menemukan ini sedikit lebih mudah untuk dibaca - satu-satunya backslashes adalah yang dibutuhkan oleh sed: EC2_REGION="$(echo "$EC2_AVAIL_ZONE" | sed -e 's:\([0-9][0-9]*\)[a-z]*$:\1:')".
Mark Berry
66
Anda dapat menghilangkan angka ajaib dengan menggunakan http://instance-data/alih-alih169.254.169.254
Jay P.
20
Saya memeriksa ini pada 2016-02-04. Saya menemukan bahwa nama host "instance-data" adalah (a) tidak tercantum dalam dokumentasi itu, dan (b) tidak berfungsi (bagi saya) pada host EC2 baru. Dokumentasi - docs.aws.amazon.com/AWSEC2/latest/UserGuide/… - hanya menyebutkan alamat 169.254, dan tidak menyebutkan nama host "instance-data". yaitu menggunakan 169.254.169.254/latest/meta-data/instance-id
JDS
138

Di Amazon Linux, AMI dapat Anda lakukan:

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

Atau, di Ubuntu dan beberapa rasa linux lainnya, ec2metadata --instance-id(Perintah ini mungkin tidak diinstal secara default di ubuntu, tetapi Anda dapat menambahkannya dengan sudo apt-get install cloud-utils)

Seperti namanya, Anda dapat menggunakan perintah untuk mendapatkan metadata berguna lainnya juga.

James
sumber
3
Jika Anda berpikir untuk menggunakan ini, artikel ini layak dibaca (tldr: adalah alat command line adalah java, dan java memiliki waktu startup yang lama)
James
Jawaban terbaik
Chuck Le Butt
@Marc Tidak. Tidak -setelah ec2. Itu adalahec2metadata --instance-id
Dawny33
5
Perintahnya berbeda pada Linux yang berbeda: di Amazon Linux ec2-metadata, sepertinya di Ubuntu ec2metadata.
James
Benar James, saya menemukan ec2metadata yang sama untuk bekerja di Ubuntu.
pyAddict
69

Di Ubuntu Anda dapat:

sudo apt-get install cloud-utils

Dan kemudian Anda bisa:

EC2_INSTANCE_ID=$(ec2metadata --instance-id)

Anda bisa mendapatkan sebagian besar metadata yang terkait dengan instance dengan cara ini:

ec2metadata --help
Sintaks: / usr / bin / ec2metadata [opsi]

Permintaan dan tampilkan metadata EC2.

Jika tidak ada opsi yang disediakan, semua opsi akan ditampilkan

Pilihan:
    -h --help tunjukkan bantuan ini

    --kernel-id menampilkan id kernel
    --ramdisk-id menampilkan id ramdisk
    --reservasi-id menampilkan id reservasi

    --ami-id menampilkan ami id
    --ami-launch-index menampilkan indeks peluncuran ami
    --ami-manifest-path menampilkan ami manifest path
    --ancestor-ami-id menampilkan id leluhur ami
    --product-codes menampilkan kode produk terkait ami
    - ketersediaan-zona menampilkan zona penempatan ami

    --instance-id menampilkan id instan
    --instance-type menampilkan tipe instance

    --local-hostname menampilkan nama host lokal
    --publik-hostname menampilkan hostname publik

    --local-ipv4 menampilkan alamat ipv4 lokal
    --public-ipv4 menampilkan alamat ipvv4 publik

    --block-device-mapping menampilkan id perangkat blokir
    --security-groups menampilkan grup keamanan

    --mac menampilkan alamat mac instance
    --profil menampilkan profil contoh
    --instance-action menampilkan instance-action

    --publik-kunci menampilkan kunci publik openssh
    --user-data menampilkan data pengguna (tidak benar-benar metadata)
rhunwicks
sumber
Di bawah Ubuntu lucid apt-get installmengambil versi 0.11-0ubuntu1 yang tidak mengandung utilitas ini. Itu ditambahkan ke paket setelah itu .
Aryeh Leib Taurog
7
Paket cloud-utils disertakan secara default pada Ubuntu 12.04.1 LTS Cluster Compute AMI.
Andrew
2
cloud-utils tampaknya juga ada di RHEL / CentOS
Craig Ringer
50

Gunakan /dynamic/instance-identity/documentURL jika Anda juga perlu meminta lebih dari sekadar ID instan Anda.

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

Ini akan memberi Anda data JSON seperti ini - hanya dengan satu permintaan .

{
    "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
sumber
1
+1 untuk menampilkan semua detail termasuk instanceType dalam satu panggilan sederhana
Luksurious
1
+1 karena memiliki standar yang cukup (hanya wget) dan jalur kerja (url instance-data tidak berfungsi untuk saya di amazon linux), tanpa menginstal paket tambahan hanya untuk tugas sederhana ini.
tishma
27

Untuk .NETOrang:

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

di AWS Linux:

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

Keluaran:

i-33400429

Menggunakan dalam variabel:

ec2InstanceId=$(ec2-metadata --instance-id | cut -d " " -f 2);
ls "log/${ec2InstanceId}/";
gpupo
sumber
Cara bersih dan ringkas. Bekerja di luar kotak misalnya dengan Ubuntu 14.
berbt
22

Untuk orang-orang PowerShell:

(New-Object System.Net.WebClient).DownloadString("http://169.254.169.254/latest/meta-data/instance-id")
stefancaunter
sumber
4
komando hanya berbeda:$instanceId=(Invoke-WebRequest -Uri 'http://169.254.169.254/latest/meta-data/instance-id').Content
Sumit Murari
Invoke-WebRequest tidak selalu berfungsi saat menjalankan skrip pada instance EC2 dengan perintah send-ssm (atau Send-SSMCommand). Itu tidak benar-benar dikatakan dalam dokumen . Mungkin itu bukan async ... yang akan aneh. Tapi opsi stefancaunter bekerja tanpa masalah sejauh ini.
J-Roel
22

Untuk Python:

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

yang bermuara pada satu-liner:

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

Alih-alih local_hostname, Anda juga dapat menggunakan public_hostname, atau:

boto.utils.get_instance_metadata()['placement']['availability-zone'][:-1]
Benlast
sumber
Semua versi boto terbaru yang saya lihat memungkinkan Anda memanggil kunci "instance_id" secara langsung. Saya membuat suntingan yang disarankan yang relevan.
saccharine
8
inst_id = boto.utils.get_instance_metadata () ['instance-id']
atisman
Anda benar-benar menyadari ini membuat daerah tempat instance berada, bukan instance-id seperti pertanyaan yang diajukan, bukan?
LukeGT
2
Bagi siapa pun yang bertanya-tanya, ini ada di boto tetapi belum di boto3. Lihat stackoverflow.com/a/33733852 untuk solusi menggunakan urllib. Ada permintaan fitur terbuka di github.com/boto/boto3/issues/313 FWIW, JS SDK juga memiliki ini: docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/… Penggunaannew AWS.MetadataService().request('instance-id',function(error,data) { myInstanceId = data; })
Armadillo Jim
20

Untuk semua mesin EC2, id-instance dapat ditemukan dalam file:

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

Anda juga bisa mendapatkan id instan dengan menjalankan perintah berikut:

    ec2metadata --instance-id
Seorang pria
sumber
2
Ini adalah solusi yang sangat bersih, tidak memerlukan permintaan HTTP.
Yuri
Jawaban terbaik yang mungkin
Shlublu
1
Jawaban yang bagus tetapi saya tidak dapat menemukan referensi untuk ini dalam dokumentasi. bolehkah saya bertanya apa referensi Anda? Kekhawatirannya adalah jika kita akan menjalankan kode ini dalam produksi, bagaimana kita tahu itu tidak akan berubah di masa depan?
shaya ajzner
Semua mesin linux ec2, mungkin, tapi jelas tidak semua mesin ec2. Tidak ada file seperti itu di Windows. C:\ProgramData\Amazon\EC2-Windows\Launch\Log\Ec2Launch.logberisi id instan, tetapi juga memiliki banyak sampah lainnya.
James
14

Lihat posting ini - perhatikan bahwa alamat IP dalam URL yang diberikan adalah konstan (yang membuat saya bingung pada awalnya), tetapi data yang dikembalikan khusus untuk instance Anda.

gareth_bowles
sumber
Tautan sudah siap untuk saya
repalviglator
Periksa jawaban @ DEtDev di bawah ini; jawaban saya cukup tua dan sepertinya tautannya telah dihapus.
gareth_bowles
10

Untuk 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
sumber
1
WTF guys ?! Anda mencuri hasil edit saya! stackoverflow.com/review/suggested-edits/4035074
kixorz
3
Maaf. Tidak tahu bagaimana mengatakan "Ini hasil edit yang bagus. Saya OP. Terima ini".
Kevin Meyer
10

Solusi yang lebih kontemporer.

Dari Amazon Linux perintah ec2-metadata sudah diinstal.

Dari terminal

ec2-metadata -help

Akan memberi Anda opsi yang tersedia

ec2-metadata -i

akan kembali

instance-id: yourid
DetDev
sumber
1
jauh lebih baik daripada bergantung pada ip semu
Mike D
kombinasikan ec2-metadatadengan Anda motd, dokumen di sini: coderwall.com/p/hr_9pw/motds-on-amazon-amis
Mike D
2
Dalam gambar Ubuntu perintahnya adalah "ec2metadata --instance-id" dan hanya akan mengembalikan nilai instance instance
Alberto Megía
10

Ketik saja:

ec2metadata --instance-id
Akash Arya
sumber
AMI mana yang Anda gunakan?
Akash Arya
4
Rupanya itu perintah untuk Amazon AMI, Anda harus memperbarui jawaban Anda
rambossa
@ WédneyYuri Ya.
Akash Arya
9

Anda dapat mencoba ini:

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

Kelas c # .net yang saya tulis untuk metadata EC2 dari http api. Saya akan membangunnya dengan fungsionalitas sesuai kebutuhan. Anda dapat menjalankannya jika Anda suka.

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
sumber
7

Java SDK terbaru memiliki EC2MetadataUtils:

Di Jawa:

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

Dalam Scala:

import com.amazonaws.util.EC2MetadataUtils
val myid = EC2MetadataUtils.getInstanceId
Scott Smith
sumber
5

Untuk C ++ (menggunakan 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
Fisikawan medis
sumber
3

Cukup periksa var/lib/cloud/instancesymlink, itu harus menunjuk ke /var/lib/cloud/instances/{instance-id}mana {instance_id}instance-id Anda.

greg
sumber
1
Saya tidak akan menggunakan ini. Anda lebih baik menggunakan permintaan HTTP yang disetujui untuk mendapatkan metadata.
Daisuke Aramaki 6-18
3

Jika Anda ingin mendapatkan semua daftar id instance dengan python di sini adalah kode:

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'])
Satpute Vikas
sumber
2

FWIW Saya menulis sistem file FUSE untuk menyediakan akses ke layanan metadata EC2: https://bitbucket.org/dgc/ec2mdfs . Saya menjalankan ini pada semua AMI khusus; itu memungkinkan saya untuk menggunakan idiom ini: cat / ec2 / meta-data / ami-id

dgc
sumber
2

Di Go, Anda dapat menggunakan paket 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
}

Inilah sumber GetMetaData.

dmikalova
sumber
1

Dalam pertanyaan yang Anda sebutkan pengguna sebagai root, satu hal yang harus saya sebutkan adalah bahwa instance ID tidak tergantung pada pengguna.

Untuk pengembang Node ,

var meta  = new AWS.MetadataService();

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

Untuk mendapatkan instance metadata gunakan

wget -q -O - http://169.254.169.254/latest/meta-data/instance-id
Soumya Ranjan Mohanty
sumber
0

Anda bisa membuat permintaan HTTP untuk MENDAPATKAN Metadata apa pun dengan meneruskan parameter metadata Anda.

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

atau

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

Anda tidak akan dikenai biaya untuk permintaan HTTP untuk mendapatkan Metadata dan Userdata.

Lain

Anda bisa menggunakan EC2 Instance Metadata Query Tool yang merupakan skrip bash sederhana yang menggunakan curl untuk meminta contoh EC2 Metadata dari dalam instance EC2 yang berjalan seperti yang disebutkan dalam dokumentasi.

Unduh alat:

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

sekarang jalankan perintah untuk mendapatkan data yang diperlukan.

$ec2metadata -i

Lihat:

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

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

Senang Membantu .. :)

Sarat Chandra
sumber
0

Pendekatan alternatif untuk PHP:

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

Itu akan memberikan banyak data tentang instance, semua dikemas dengan baik dalam array, tidak ada dependensi eksternal. Karena ini adalah permintaan yang tidak pernah gagal atau tertunda untuk saya, maka aman untuk melakukannya dengan cara itu, jika tidak, saya akan mencari ikal ()

John
sumber
0

Untuk PHP:

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

Edit per @John

Rumah pantai
sumber
Tapi mengapa Anda menggunakan GuzzeHttp untuk tujuan itu jika Anda memiliki fungsi curl dan asli di PHP?
John
Ini pilihan saya. Saya menggunakan guzzle untuk banyak hal lain, ini adalah prasyarat umum untuk banyak paket lain juga.
Beachhouse
$ instance = json_decode (file_get_contents (' 169.254.169.254/latest/dynamic/instance-identity/… ); $ id = $ instance [' instanceId ']; Saya tahu Guzzle tersebar luas, saya tidak pernah menyentuhnya sendiri. Untuk itu tugas sederhana saya akan memberikan pendekatan yang paling ringan
John
0

Semua meta-data yang terkait dengan sumber daya EC2 dapat diakses oleh instance EC2 itu sendiri dengan bantuan perintah berikut sedang dijalankan:

CURL:

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

Untuk kasus Anda: " metadata-diminta " harus berupa instance-id , " api-versi " biasanya terbaru yang dapat digunakan.

Catatan Tambahan: Anda juga bisa mendapatkan informasi terkait atribut EC2 di bawah ini menggunakan perintah di atas.

ami-id, ami-launch-index, ami-manifest-path, block-device-mapping /, hostname, iam /, instance-action, instance-id, instance-type, nama host lokal, local-ipv4, mac, metrik /, jaringan /, penempatan /, profil, public-hostname, public-ipv4, public-key /, reservasi-id, grup keamanan, layanan /,

Untuk detail lebih lanjut, ikuti tautan ini: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

Vipin Sharma
sumber
0

Untuk contoh Windows:

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

atau

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

Untuk batang pohon elastis AWS eb cli run eb tags --list

pengguna2584621
sumber