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.
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)