From inside an instance, one address answers questions about the instance itself: 169.254.169.254, the instance metadata service. Scripts use it to learn their own id, zone and addresses, and the role's credentials arrive through it too.
A token first
Amazon Linux 2023 requires IMDSv2: every request must carry a token. A plain request is turned away. Inside a session on the instance:
curl -I http://169.254.169.254/latest/meta-data/instance-idHTTP/1.1 401 UnauthorizedThe token is handed out to a PUT request. -X PUT sets the request method, and -H adds a header saying how many seconds the token should last:
TOKEN=$(curl -s -X PUT http://169.254.169.254/latest/api/token -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")Asking with the token
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-idThe token goes in a header of its own, and the answer is the instance's id. Other paths under /latest/meta-data/ answer other questions:
| Path | Answer |
|---|---|
instance-id | the instance's id |
placement/availability-zone | its zone |
public-ipv4 | its public IP |
local-ipv4 | its private IP |
Why the token? A bug in a web application can sometimes be used to make it fetch an address an attacker chooses, such as the metadata service, which also hands out the role's credentials. Such tricks fetch with a plain GET; they cannot send the PUT that a token needs, so the credentials stay out of reach.