amazon-ec2 aws - How to get the instance id from within an ec2 instance?




cli metadata (21)

How can I find out the instance id of an ec2 instance from within the ec2 instance?


Answers

Use the /dynamic/instance-identity/document URL if you also need to query more than just your instance ID.

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

This will get you JSON data such as this - with only a single request.

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

For PHP:

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

Edit per @John


The latest Java SDK has EC2MetadataUtils:

In Java:

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

In Scala:

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

For all ec2 machines, the instance-id can be found in file:

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

You can also get instance id by running the following command:

    ec2metadata --instance-id

For .NET People :

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

See this post - note that the IP address in the URL given is constant (which confused me at first), but the data returned is specific to your instance.


Alternative approach for PHP:

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

That will provide a lot of data about the instance, all nicely packed in an array, no external dependencies. As it's a request that never failed or delayed for me it should be safe to do it that way, otherwise I'd go for curl()


If you wish to get the all available instance id list using python here is the code:

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'])

On Amazon Linux AMIs you can do:

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

Or, on Ubuntu and some other linux flavours, ec2metadata --instance-id (This command may not be installed by default on ubuntu, but you can add it with sudo apt-get install cloud-utils)

As its name suggests, you can use the command to get other useful metadata too.


You can just make a HTTP request to GET any Metadata by passing the your metadata parameters.

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

or

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

You won't be billed for HTTP requests to get Metadata and Userdata.

Else

You can use EC2 Instance Metadata Query Tool which is a simple bash script that uses curl to query the EC2 instance Metadata from within a running EC2 instance as mentioned in documentation.

Download the tool:

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

now run command to get required data.

$ec2metadata -i

Refer:

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

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

Happy To Help.. :)


FWIW I wrote a FUSE filesystem to provide access to the EC2 metadata service: https://bitbucket.org/dgc/ec2mdfs . I run this on all custom AMIs; it allows me to use this idiom: cat /ec2/meta-data/ami-id


Simply check the var/lib/cloud/instance symlink, it should point to /var/lib/cloud/instances/{instance-id} where {instance_id} is your instance-id.


You can try this:

#!/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]\)"`

On Ubuntu you can:

sudo apt-get install cloud-utils

And then you can:

EC2_INSTANCE_ID=$(ec2metadata --instance-id)

You can get most of the metadata associated with the instance this way:

ec2metadata --help
Syntax: /usr/bin/ec2metadata [options]

Query and display EC2 metadata.

If no options are provided, all options will be displayed

Options:
    -h --help               show this help

    --kernel-id             display the kernel id
    --ramdisk-id            display the ramdisk id
    --reservation-id        display the reservation id

    --ami-id                display the ami id
    --ami-launch-index      display the ami launch index
    --ami-manifest-path     display the ami manifest path
    --ancestor-ami-ids      display the ami ancestor id
    --product-codes         display the ami associated product codes
    --availability-zone     display the ami placement zone

    --instance-id           display the instance id
    --instance-type         display the instance type

    --local-hostname        display the local hostname
    --public-hostname       display the public hostname

    --local-ipv4            display the local ipv4 ip address
    --public-ipv4           display the public ipv4 ip address

    --block-device-mapping  display the block device id
    --security-groups       display the security groups

    --mac                   display the instance mac address
    --profile               display the instance profile
    --instance-action       display the instance-action

    --public-keys           display the openssh public keys
    --user-data             display the user data (not actually metadata)

In the question you have mentioned the user as root, one thing I should mention is that the instance ID is not dependent on the user.

For Node developers,

var meta  = new AWS.MetadataService();

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

For Python:

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

which boils down to the one-liner:

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

Instead of local_hostname you could also use public_hostname, or:

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

For C++ (using 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

Just Type:

ec2metadata --instance-id

A more contemporary solution.

From Amazon Linux the ec2-metadata command is already installed.

From the terminal

ec2-metadata -help

Will give you the available options

ec2-metadata -i

will return

instance-id: yourid

on AWS Linux:

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

Output:

i-33400429

Using in variables:

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

Most people choose to use EBS backed instance as it is stateful. It is to safer because everything you have running and installed inside it, will survive stop/stop or any instance failure.

Instance store is stateless, you loose it with all the data inside in case of any instance failure situation. However, it is free and faster because the instance volume is tied to the physical server where the VM is running.





amazon-ec2 amazon-web-services