Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement equivalent to boto.utils.get_instance_metadata() #313

Open
jgehrcke opened this issue Oct 21, 2015 · 35 comments
Open

Implement equivalent to boto.utils.get_instance_metadata() #313

jgehrcke opened this issue Oct 21, 2015 · 35 comments
Labels
feature-request This issue requests a feature. p2 This is a standard priority issue

Comments

@jgehrcke
Copy link

This request seems to come up often: Should there be a utility function in boto to retrieve the instance metadata? See: http://stackoverflow.com/questions/31630822/boto3-equivalent-to-boto-utils-get-instance-metadata

@mtdowling mtdowling added the feature-request This issue requests a feature. label Oct 21, 2015
@mtdowling
Copy link
Contributor

There is not currently support for this. I'll mark this as a feature request and we can track it here.

@tiadobatima
Copy link

This feature would be awesome! We've been postponing using boto3 for a lot of our stuff because this functionality is not available 👍

When this is implemented, it would also be great if there was builtin way of recursively grabbing all the metadata as a dictionary, instead of only support for lazy loads (like boto2). Somewhat similarly to what we do for collections in boto3, but dict instead of list:

metadata = dict(instance.metadata.all())

Thanks! :)

@rorysavage77
Copy link

I can not believe this is not in boto3 already. Because AWS' next generation of compute services like Lambda include boto3 natively, having to revert back to boto2 for things like this is a PITA.

@marco-hoyer
Copy link

Hi, any news on this? Does anyone plan to implement it?

@copumpkin
Copy link

This is a disappointing regression from boto.

@Bartvds
Copy link

Bartvds commented Jun 14, 2017

@mtdowling What is the recommended way to replace this method? Do we have to roll our own thing or should we include outdated boto?

@adamchainz
Copy link
Contributor

adamchainz commented Jun 14, 2017

Update (as below): I've made a library ec2-metadata that provides an easy interface to query the EC2 metadata API, with caching.


On the instance, do e.g.:

In [5]: requests.get('http://169.254.169.254/latest/meta-data/ami-id').text
Out[5]: 'ami-f0928696'

I think the reason this hasn't been copied is because multiple HTTP requests are needed to get all the metadata as a dict, whereas often you only need one item like so.

@ranman
Copy link

ranman commented Jun 15, 2017

I would also love it if we could implement this one. I'll see what I can do internally!

@Bartvds
Copy link

Bartvds commented Jun 15, 2017

Maybe it doesn't have to be this full dict, but an object with some lazy loading properties, and an option to materialize the whole dict if some must have it (for logging/monitoring).

@adamchainz
Copy link
Contributor

I made a separate mini library for this, with @Bartvds 's suggestion for lazy loading, check it out at https://github.com/adamchainz/ec2-metadata

@vitchyr
Copy link

vitchyr commented Dec 27, 2017

Any updates on this feature request?

@jpiccari
Copy link

Additionally, it would be great to see boto3 automatically pickup the current region when run on an EC2 instance.

@rendicott
Copy link

+1 need this

@adamchainz
Copy link
Contributor

@rendicott does ec2-metadata not fit your use case? I'd like to make it do everything we need.

@rendicott
Copy link

@adamchainz I'm sure ec2-metadata will work fine, I plan on using it until it's built into boto

unv-annihilator added a commit to unv-annihilator/yas3fs that referenced this issue Oct 29, 2018
Remove use of boto
Add botocore requirement (might not be required)
Add ec2_metadata to requirements to workaround missing util call in boto3. Related issue: boto/boto3#313
Remove use of UTF8DecodingKey, might look to remake if causing issues
@zepplen
Copy link

zepplen commented May 30, 2019

+1 It would be very nice to have this included in the native boto3 lib.

Adding the ec2-metadata lib listed above seems like a very heavy handed approach, if I wanted to add another pip, I would just use requests.

Having this in boto3 or botocore would mean I could run the code natively on Amazon Linux or a Lambda function w/o having to add dependencies. It would also prevent me from needing to use six to be able to use a python native http get method.

@jweede
Copy link

jweede commented May 30, 2019

Recently noticed /run/cloud-init/instance-data.json on systems with cloud-init.

https://cloudinit.readthedocs.io/en/latest/topics/instancedata.html

@adamchainz
Copy link
Contributor

@zepplen ec2-metadata is a single 286 line file that builds all the requests calls for you :) Python packaging is better now than it used to be, pip install is not so heavy :)

@ThrawnCA
Copy link

@adamchainz ec2-metadata looks great, but we're working with a software package (CKAN) that hasn't yet migrated to Python 3.

@adamchainz
Copy link
Contributor

ec2-metadata 1.8.0 is still installable and supports Python 2.

@zepplen
Copy link

zepplen commented Mar 2, 2020

With the changes in IMDSv2, it seems like this is an even more useful feature.

Announcement: https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service/

The local metadata service now has a v2 endpoint, which is differentiated from v1 by the existance of a x-aws-ec2-metadata-token header being passed to the local metadata service.

This token is retrieved by sending a PUT request to a new token API in the local metadata service, which will remain active for up to 6 hours (ttl is set as a header in the put request).

It is possible to disable the v1 endpoint, however to do so, ALL metadata queries must use the token, not only IAM Role Credential request calls.

Given the extra complexity of requesting the token, and keeping track of the token TTL for future requests, this undifferentiated heavy lifting, seems like something that should be solved via the AWS provided SDK.

The ec2-metadata library mentioned by @adamchainz does not implement this solution, and I would argue is not a replacement for a solution provided by AWS. (As some development environments have restrictions on what libraries you can import and use).

@adamchainz
Copy link
Contributor

ec2-metadata does have an open issue: adamchainz/ec2-metadata#150

@ThrawnCA
Copy link

ThrawnCA commented Mar 6, 2020

@zepplen Incidentally, for those needing a workaround, it's very easy with requests. Eg to retrieve the equivalent of get_instance_metadata()['document']:

token = requests.put('http://169.254.169.254/latest/api/token', headers={'X-aws-ec2-metadata-token-ttl-seconds': '60'}).text
document = requests.get('http://169.254.169.254/latest/dynamic/instance-identity/document', headers={'X-aws-ec2-metadata-token': token}).json()

@adamchainz
Copy link
Contributor

ec2-metadata 2.2.0 now supports v2, thanks to @ThrawnCA . #ossFasterThanAWS

@tomaskutaj
Copy link

yes please +1

@nnsense
Copy link

nnsense commented Jun 2, 2020

In [5]: requests.get('http://169.254.169.254/latest/meta-data/ami-id').text
Out[5]: 'ami-f0928696'

I think the reason this hasn't been copied is because multiple HTTP requests are needed to get all the metadata as a dict, whereas often you only need one item like so.

MMhh.. I've tried with requests and I have to agree with @adamchainz it's quite pointless to spend time on this

@adamchainz
Copy link
Contributor

@nnsense please try out ec2-metadata, it's a bit more work than one request to use the metadata api v2 ..

@ThrawnCA
Copy link

ThrawnCA commented Jun 3, 2020

At least, it's a bit more work than one request if you want it to be efficient. If you just retrieve a new token every time, you're doubling up all your requests. The implementation in ec2-metadata caches tokens for up to 10 hours and refreshes them when expired, all transparently.

@fshields
Copy link

fshields commented Jun 5, 2020

This is crazy that access to instance metadata is not part of boto. Come on guys!

@steven-aerts
Copy link

You can access specific metadata easily from botocore if you do not mind calling a private function:

from botocore.utils import IMDSFetcher

IMDSFetcher()._get_request("/latest/meta-data/instance-type", None).text

@ThrawnCA
Copy link

You can access specific metadata easily from botocore if you do not mind calling a private function:

I think a lot of people would mind.

@JoshBLive
Copy link

@aBurmeseDev aBurmeseDev added the p2 This is a standard priority issue label Nov 11, 2022
@2rs2ts
Copy link

2rs2ts commented Mar 17, 2023

If the Go SDK can have a package for this, then surely the Python one can too! https://pkg.go.dev/github.com/aws/aws-sdk-go/aws/ec2metadata

@adamchainz
Copy link
Contributor

My package ec2-metadata is a "critical" project on PyPI, and funded on Tidelift at $100/mo, so I will be maintaining it for the forseeable future (6 years and counting!).

@chrisbecke
Copy link

and here we are in 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request This issue requests a feature. p2 This is a standard priority issue
Projects
None yet
Development

No branches or pull requests