39

Is there a straightforward way to access AWS instance metadata from within a Docker container?

For example, when trying to fetch credentials for an IAM role on an EC2 instance, this would work on the instance itself:

http://169.254.169.254/latest/meta-data/iam/security-credentials/my_role

...but not from within a Docker container running on that EC2 instance.

user3420508
  • 491
  • 1
  • 4
  • 3

3 Answers3

43

There should be no difference between doing this in a container vs the host. The container can access EC2 metadata directly.

root@f1e5964e87e4:/# curl http://169.254.169.254/latest/meta-data/iam/security-credentials/myrole
{
  "Code" : "Success",
  "LastUpdated" : "2014-03-14T17:07:24Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "mykey",
  "SecretAccessKey" : "mysecret",
  "Token" : "mytoken",
  "Expiration" : "2014-03-14T23:09:39Z"
}

What do you see when you try the command from within the container? has an IAM role assigned?

Ben Whaley
  • 32,811
  • 7
  • 87
  • 85
  • 6
    I have to use `--net=host` to enable the access to the metadata service. – Jingpeng Wu Oct 18 '17 at 19:39
  • 2
    nope. 5 years ago, I said that http://169.254.169.254 is accessible from a docker container. Your code can therefore retrieve its EC2 instance host meta data. There is no need to write code to retrieve temporary credentials if you are using the AWS SDK. Our SDKs do that automatically for you. (and AWS CLI is using the Python SDK) – Sébastien Stormacq Jul 18 '19 at 06:20
  • 1
    @SébastienStormacq This does not appear to be true inside a Windows container. If jingpeng-wu is correct then that would explain it since Windows docker can't do host mode networking. Do you know how I can do this in Windows and/or without host networking? – Richard Payne Feb 28 '20 at 15:40
  • 1
    sorry - I just use Linux and MacOs OS. No idea how docker works on Windows or with Windows containers – Sébastien Stormacq Feb 28 '20 at 19:48
  • 2
    @RichardPayne check out this link for accessing metadata from Windows containers: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/windows_task_IAM_roles.html – Ben Whaley Feb 28 '20 at 19:53
  • 7
    Just want to point out that I ran into this in a Ubuntu box and fixed it by increasing the maximum PUT "hops" that you can make. `aws ec2 modify-instance-metadata-options --instance-id --http-put-response-hop-limit 3 --http-endpoint enabled` https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html – efess Feb 25 '21 at 13:39
  • As per Jingpeng Wu, adding --net=host my requirement was fulfilled. – Damith Udayanga Feb 17 '22 at 10:19
4

If you've migrated your instance/s to IMDSv2*, then the default hop limit for getting metadata is set to 1. This hop limit will prevent Docker containers from accessing the metadata (assuming they're using a Docker network, not the host network).

This answer describes how to change the hop limit to remedy the situation: https://stackoverflow.com/a/71884476/243104

* IMDSv2 = "Instance Metadata Service Version 2" = EC2's new, more secure, session-oriented metatdata access method, which is recommended/required by some security audits.

(HT to @efess for their comment above which made me realise this was my issue.)

Graham Lea
  • 5,797
  • 3
  • 40
  • 55
0

As mentioned by @Ben Whaley in comments, below commands worked for me, mentioned in https://docs.aws.amazon.com/AmazonECS/latest/developerguide/windows_task_IAM_roles.html

$gateway = (Get-NetRoute | Where { $_.DestinationPrefix -eq '0.0.0.0/0' } | Sort-Object RouteMetric | Select NextHop).NextHop
$ifIndex = (Get-NetAdapter -InterfaceDescription "Hyper-V Virtual Ethernet*" | Sort-Object | Select ifIndex).ifIndex
New-NetRoute -DestinationPrefix 169.254.169.254/32 -InterfaceIndex $ifIndex -NextHop $gateway
Utkarsh Bhushan
  • 163
  • 2
  • 7