Reading User Data and Metadata on EC2

When creating a new Linux EC2 instance on AWS you’re able to pass extra data to the server to be used late in the boot sequence. This can be in the form of a simple bash script, or the URL(s) of a number of scripts. Or the data could simple by a list of parameters you need that instance to know. Full details on the sorts of things you can pass via the “User Data” parameter can be found on Ubuntu Website or details for the AWS build AMI can be found here. (Not all images can be passed User Data, but the standard ones by Amazon can be along with a range of community ones.)

Now if you pass a script or the URL to a script as User Data to your new instance then this will get run for you, and you don’t need to worry about it. However if you pass it a list of parameters (for example you may pass it the Endpoint URI for your RDS instance so the DB settings for your apps can be set up correctly) you need to know how to read the User Data. Along with reading the User Data you may also want to read in Metadata about your new instance, such as its AMI-ID or the public hostname of your instance. Reading the Metadata is done by querying a simple API:

The base URI of all the query’s is: http://169.254.169.254/

Followed by the API Version (or use “latest” to get the most recent API) and then the type of data you want to retrieve (i.e. meta-data) then the category you wish to query. For example the URI you would use to get the local hostname of your instance would be:

http://169.254.169.254/latest/meta-data/local-hostname

A full list of categories is available here or you can use the wget utility and run the following command from the shell of one of your EC2 instances:

wget http://169.254.169.254/latest/meta-data/ -O -

Whilst the API is designed so only your instance can read your User Data, the requests are not encrypted so it is best not to store passwords or encryption keys using this method. If a hacker was able to gain access to your EC2 instance even via a non privileged user they would still be able to read all the User Data along with any other Metadata for your instance.

‘EC2 Instance Metadata Query Tool’:

http://aws.amazon.com/code/1825?_encoding=UTF8&jiveRedirect=1

This provides you with a simple command line tool to query the Metadata and User Data for your current instance. For example to get the current AMI ID:

$ ec2-metadata --ami-id
ami-id: ami-12c56a

Querying Directly in PHP using CURL:

If you’re using PHP for your web application(s) then querying then you can use something similar to this:

$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);
// The next line returns the response as the return value of the curl_exec command.
curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);
curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/2007-08-29/user-data');
$userdata = curl_exec($curl_handle); // Make the request
 
if ($userdata) {
            parse_str($userdata, $arr);
            // .... All my User Data parameters are now stored in $arr
}

Or if you fancy getting the AMI ID as we did earlier:

$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);
// The next line returns the response as the return value of the curl_exec command.
curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);
curl_setopt($curl_handle,CURLOPT_URL,'http://169.254.169.254/latest/meta-data/instance-id');
 
$instanceId = curl_exec($curl_handle); // Make the request

For the full documentation on reading in the Metadata (and User Data) refer to the Amazon documentation here:
http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/?AESDG-chapter-instancedata.html