How can I find out the instance id
of an ec2 instance from within the ec2 instance?
See the EC2 documentation on the subject.
Run:
wget -q -O - http://169.254.169.254/latest/meta-data/instance-id
If you need programmatic access to the instance ID from within a 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: $?\"`"
Here is an example of a more advanced use (retrieve instance ID as well as availability zone and region, etc.):
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:'`"
You may also use curl
instead of wget
, depending on what is installed on your platform.
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.
-
after ec2
. It is ec2metadata --instance-id
ec2-metadata
, on Ubuntu it seems to be ec2metadata
.
[ec2-user@ip-10-1-1-1 ~]$ ec2-metadata -i \ instance-id: <redacted> \ [ec2-user@ip-10-1-1-1 ~]$ ec2metadata \ -bash: ec2metadata: command not found
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)
apt-get install
retrieves version 0.11-0ubuntu1 which doesn't contain this utility. It was added to the package just afterwards.
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"
}
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}/";
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
C:\ProgramData\Amazon\EC2-Windows\Launch\Log\Ec2Launch.log
contains the instance Id, but also has a whole lot of other junk.
For .NET
People :
string instanceId = new StreamReader(
HttpWebRequest.Create("http://169.254.169.254/latest/meta-data/instance-id")
.GetResponse().GetResponseStream())
.ReadToEnd();
For powershell people:
(New-Object System.Net.WebClient).DownloadString("http://169.254.169.254/latest/meta-data/instance-id")
$instanceId=(Invoke-WebRequest -Uri 'http://169.254.169.254/latest/meta-data/instance-id').Content
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]
new AWS.MetadataService().request('instance-id',function(error,data) { myInstanceId = data; })
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.
Just Type:
ec2metadata --instance-id
ec2-metadata
command not ec2metadata
. Unsure if this is a typo or the command has changed in the new AMI instance. ec2-metadata --instance-id | cut -d' ' -f2
for just the id as a string
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
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]\)"`
For 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]
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
A c# .net class I wrote for EC2 metadata from the http api. I will build it up with functionality as needed. You can run with it if you like it.
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
*************************************************************/
}
}
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
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.
If you wish to get the all instances id list in 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'])
In Go you can use the goamz package.
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
}
Here's the GetMetaData source.
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://github.com/xdgc/ec2mdfs . I run this on all custom AMIs; it allows me to use this idiom: cat /ec2/meta-data/ami-id
Motivation: User would like to Retrieve aws instance metadata.
Solution: The IP address 169.254.169.254
is a link-local address (and is valid only from the instance) aws gives us link with dedicated Restful API for Retrieving metadata of our running instance (Note that you are not billed for HTTP requests used to retrieve instance metadata and user data) . for Additional Documentation
Example:
//Request:
curl http://169.254.169.254/latest/meta-data/instance-id
//Response
ami-123abc
You able to get additional metadata labels of your instance using this link http://169.254.169.254/latest/meta-data/<metadata-field>
just choose the right tags:
ami-id ami-launch-index ami-manifest-path block-device mapping events hibernation hostname iam identity-credentials instance-action instance-id instance-type local-hostname local-ipv4 mac metrics network placement profile reservation-id security-groups services
http://169.254.169.254/latest/meta-data/
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);
});
To get the instance metadata use
wget -q -O - http://169.254.169.254/latest/meta-data/instance-id
For a Windows instance:
(wget http://169.254.169.254/latest/meta-data/instance-id).Content
or
(ConvertFrom-Json (wget http://169.254.169.254/latest/dynamic/instance-identity/document).Content).instanceId
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()
For PHP:
$instance = json_decode(file_get_contents('http://169.254.169.254/latest/dynamic/instance-identity/document));
$id = $instance['instanceId'];
Edit per @John
Run this:
curl http://169.254.169.254/latest/meta-data/
You will be able to see different types of attributes which are provided by aws.
All meta-data related to EC2 resource can be accessed by the EC2 instance itself with the help of the following command being executed:
CURL :
http://169.254.169.254/<api-version>/meta-data/<metadata-requested>
For your case: "metadata-requested" should be instance-id , "api-version" is usually latest that can be used.
Additional Note: You can also get information related to below EC2 attributes using the above command.
ami-id, ami-launch-index, ami-manifest-path, block-device-mapping/, hostname, iam/, 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, services/,
For more details please follow this link : https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
Success story sharing
$
), find one or more digits following by one or more lowercase letters. Substitute with the digits only. (Backslash + parentheses tell sed to remember a substring, which is recalled with\1
.) I found this a little easier to read--the only backslashes are those required by sed:EC2_REGION="$(echo "$EC2_AVAIL_ZONE" | sed -e 's:\([0-9][0-9]*\)[a-z]*$:\1:')"
.http://instance-data/
instead of169.254.169.254
instance-data
will only be available if you're using the Amazon DNS resolvers - if you're not, it won't be available. It resolves to 169.254.169.254.