Explaining the Difference Between IMDSv1 and IMDSv2 in AWS

The aim of this pagešŸ“ is to explain the AWS Instance Metadata Service (IMDS) based on the particular example of accessing instance metadata using both IMDSv1 and IMDSv2.

Pavol Kutaj
2 min readSep 19, 2023
  • AWS Instance Metadata Service (IMDS) provides data about an instance that can be used to manage and configure your running instances.
  • Instance metadata is divided into categories, for example, host name, events, and security groups.
  • You can also use instance metadata to access user data that you specified when launching your instance.
  • You can build generic Amazon Machine Images (AMIs) and use user data to modify the configuration files supplied at launch time.
  • You can access the AWS Instance Metadata from within the instance itself using either IPv4 or IPv6 URIs.
  • In IMDSv1, you can directly make a GET request to the metadata URI.
  • IMDSv2 introduces session-oriented requests, which adds defense in depth against unauthorized metadata access.
  • In IMDSv2, you need to create a session token first by making a PUT request to the session URI. You then include this token in your GET request to the metadata URI.
  • The main difference between IMDSv1 and IMDSv2 is not the metadata content, but the method of access.

Hereā€™s a table of some instance metadata categories, their examples, and descriptions:

CODE

Here is an example I have experienced with accessing instance metadata using both IMDSv1 and IMDSv2 These Python scripts will print the instance ID of the EC2 instance they are run on.

IMDSv1:

import requests

response = requests.get("http://169.254.169.254/latest/meta-data/instance-id")
instance_id = response.text
print(instance_id)

IMDSv2:

import requests

response = requests.put("http://169.254.169.254/latest/api/token", headers={"X-aws-ec2-metadata-token-ttl-seconds": "21600"})
token = response.text

headers = {"X-aws-ec2-metadata-token": token}
response = requests.get("http://169.254.169.254/latest/meta-data/instance-id", headers=headers)
instance_id = response.text
print(instance_id)

--

--

No responses yet