Amazon EC2 instances may access instance-specific metadata as well as data supplied when launching the instances. This data can be used to build more generic AMIs (e.g. behavior could be modified by configuration files supplied at launch time).
Perhaps you run web servers for various Mom-and-Pop stores. All the instances use the same AMI. At launch time you could specify which Amazon S3 bucket the AMI should retrieve its content from. This allows you to launch multiple Mom-and-Pop sites serving different content using the same AMI by doing the following:
Create an Amazon S3 bucket
Place your content in the Amazon S3 bucket
Launch an instance of your web server AMI specifying the Amazon S3 bucket containing the web content
The data available to instances is categorized into
This data is specific to an instance. Currently we provide:
| Data | Description | Version Introduced |
|---|---|---|
| ami-id | The AMI id the instance was launched with. | 1.0 |
| ami-manifest-path | The manifest path of the AMI the instance was launched with. | 1.0 |
| ami-launch-index | The index of this instance in the reservation (per AMI). | 1.0 |
| instance-id | The id of this instance. | 1.0 |
| hostname | The local hostname of this instance. Deprecated as of 2007-01-19,
use local-hostname instead. | 1.0 |
| local-hostname | The local hostname of the instance. | 2007-01-19 |
| public-hostname | The public hostname of the instance. | 2007-01-19 |
| local-ipv4 | Public IP address if launched with direct addressing, private IP address if launched with public addressing. | 1.0 |
| public-ipv4 | NATted public IP Address | 2007-01-19 |
| public-keys/ | Public keys. Only available if supplied at instance launch time | 1.0 |
| reservation-id | Id of the reservation. | 1.0 |
| security-groups | Names of the security groups the instance is launched in. Only available if supplied at instance launch time | 1.0 |
| product-codes | Product codes associated with this instance. | 2007-03-01 |
Any user-supplied data is treated as opaque data: what you give us is what you get back.
![]() | Note |
|---|---|
|
An instance retrieves the data by querying a web server using a
REST-like API. The base URI of all requests is
http://169.254.169.254/2007-03-01/ where
2007-03-01 indicates the API version.
![]() | Note |
|---|---|
Version 1.0 is part of a legacy versioning scheme. Newer versions follow a date based versioning scheme. See the section called “API Versioning” for more information on the versioning scheme used by Amazon EC2. |
The latest version of the API is always available using the
URI http://169.254.169.254/latest.
Although this data is only accessible by your specific instance, the data is not protected by cryptographic methods. You should take suitable precautions to protect sensitive data (such as long lived encryption keys).
You are not billed for these HTTP requests.
Requests for a specific metadatum resource returns the
appropriate value or a 404 HTTP error code
if the resource is not available. All metadata is returned as
text (content type text/plain).
Requests for a general metadatum resource (i.e. an URI ending
with a /) return a list of the
resources available at that level or a 404
HTTP error code if there is no such
resource. The list items are on separate lines with lines
terminated by any combination of linefeed (ASCII 10) and
carriage return (ASCII 13).
| Resource & URI | Example |
|---|---|
|
Get the available API versions
|
Request
GET http://169.254.169.254/Response 1.0 2007-03-01 |
|
Get the top-level metadata items
|
Request
GET http://169.254.169.254/2007-03-01/meta-data/Response ami-id ami-launch-index ami-manifest-path instance-id hostname local-ipv4 public-keys/ reservation-id security-groups |
|
Get the value of metadatum X (where 'X' is from the above list)
|
Request
GET http://169.254.169.254/2007-03-01/meta-data/ami-manifest-pathResponse my-amis/spamd-image.manifest.xmlRequest GET http://169.254.169.254/2007-03-01/meta-data/ami-idResponse ami-5bae4b32Request GET http://169.254.169.254/2007-03-01/meta-data/reservation-idResponse r-fea54097Request GET http://169.254.169.254/2007-03-01/meta-data/hostnameResponse domU-12-34-31-00-00-05.usma1.compute.amazonaws.com |
|
Get the list of available public keys
|
Request
GET http://169.254.169.254/2007-03-01/meta-data/public-keys/Response 0=my-public-key |
|
In which formats is public key 0 available?
|
Request
GET http://169.254.169.254/2007-03-01/meta-data/public-keys/0/Response openssh-key |
|
Get public key 0 (in openssh-key format)
|
Request
GET http://169.254.169.254/2007-03-01/meta-data/public-keys/0/openssh-keyResponse ssh-rsa AAAA.....wZEf my-public-key |
|
Get product codes
|
Request
GET http://169.254.169.254/2007-03-01/meta-data/product-codesResponse 774F4FF8 |
Requests for the user data returns the data as-is
(content type application/x-octetstream).
![]() | Note |
|---|---|
As mentioned previously, all user-supplied data is treated as opaque data: what you give us is what you get back. It is thus the responsibility of the instance to interpret this data appropriately. |
| Resource & URI | Examples |
|---|---|
|
Get the user-supplied data
|
Request
GET http://169.254.169.254/2007-03-01/user-dataResponse 1234,fred,reboot,true | 4512,jimbo, | 173,,,Request GET http://169.254.169.254/2007-03-01/user-dataResponse [general] instances: 4 [instance-0] s3-bucket: fred [instance-1] reboot-on-error: yesRequest GET http://169.254.169.254/2007-03-01/user-dataResponse GIF89aXfgs13qa.... |
Alice wants four instances of her favorite database AMI. The first instance will be the master with the remainder acting as replicants.
The master database configuration specifies various
database parameters (the size of store, say) while the
replicants' configuration specifies different parameters
(replication strategy say). Alice decides to provide this
data as an ASCII string with | delimiting the various
instances' data:
store-size=123PB backup-every=5min | replicate-every=1min | replicate-every=2min | replicate-every=10min | replicate-every=20min
The example above breaks down as follows
store-size=123PB backup-every=5min
defines the master database configuration
replicate-every=1min
defines the first replicant's configuration
Etc.
Alice launches her instances:
$ec2-run-instances ami-5bae4b32 -n 4 -d "store-size=123PB backup-every=5min | replicate-every=1min | replicate-every=2min | replicate-every=10min | replicate-every=20min"RESERVATION r-fea54097 598916040194 default INSTANCE i-3ea74257 ami-5bae4b32 pending 0 INSTANCE i-31a74258 ami-5bae4b32 pending 1 INSTANCE i-31a74259 ami-5bae4b32 pending 2 INSTANCE i-31a7425a ami-5bae4b32 pending 3
Note that only 4 instances were launched.
Once launched, the instances all have a copy of the user data and the common metadata:
AMI id: ami-5bae4b32
AMI manifest path: ec2-public-images/getting-started.manifest.xml
Reservation id: r-fea54097
Public keys: none
Security group names: default
However each instance has certain unique metadata:
Instance 1
| Metadatum | Value |
|---|---|
| instance-id | i-3ea74257 |
| ami-launch-index | 0 |
| hostname | domU-12-43-33-00-01-27.usma1.compute.amazonaws.com |
| local-ipv4 | 216.182.228.87 |
Instance 2
| Metadatum | Value |
|---|---|
| instance-id | i-31a74258 |
| ami-launch-index | 1 |
| hostname | domU-12-31-33-00-01-72.usma1.compute.amazonaws.com |
| local-ipv4 | 216.182.228.88 |
Instance 3
| Metadatum | Value |
|---|---|
| instance-id | i-31a74259 |
| ami-launch-index | 2 |
| hostname | domU-12-31-33-00-01-73.usma1.compute.amazonaws.com |
| local-ipv4 | 216.182.228.89 |
Instance 4
| Metadatum | Value |
|---|---|
| instance-id | i-31a7425a |
| ami-launch-index | 3 |
| hostname | domU-12-31-33-00-01-74.usma1.compute.amazonaws.com |
| local-ipv4 | 216.182.228.90 |
Therefore an instance can determine its portion of the user-supplied data by the simple process of
Determining which instance in the launch group it is:
GET http://169.254.169.254/2007-03-01/meta-data/ami-launch-index
1Retrieving the user data:
GET http://169.254.169.254/2007-03-01/user-data
store-size=123PB backup-every=5min | replicate-every=1min | replicate-every=2min | replicate-every=10min | replicate-every=20min
Extracting the appropriate part of the user data:
user_data.split('|')[ami_launch_index]