Skip to content

Commit

Permalink
Better error handling for AWS token fetching (elastic#884)
Browse files Browse the repository at this point in the history
* Better error handling for AWS token fetching

It turns out for docker containers on AWS elastic beanstalk, the PUT for the
token fails, and fails slowly. This is not the case for the ec2 host on which
the docker container is running. This was causing issues, compounded by the
fact that I didn't have `retries=False` on that call.

* Add changelog

* Add comments about IMDSv2
  • Loading branch information
basepi authored and romulorosa committed Oct 15, 2020
1 parent 4a1b687 commit 31f03e1
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ endif::[]
===== Bug fixes
* Updated CLOUD_PROVIDER config to allow for new options defined in https://github.com/elastic/apm/issues/289[#289] {pull}878[#878]
* Fixed a bug in AWS metadata collection on docker containers in AWS Elastic Beanstalk {pull}884[#884]
[[release-notes-5.x]]
Expand Down
25 changes: 17 additions & 8 deletions elasticapm/utils/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,26 @@ def aws_metadata():
# and will be quiet in the logs, unlike urllib3
socket.create_connection(("169.254.169.254", 80), 0.1)

ttl_header = {"X-aws-ec2-metadata-token-ttl-seconds": "300"}
token_url = "http://169.254.169.254/latest/api/token"
token_request = http.request("PUT", token_url, headers=ttl_header, timeout=3.0)
token = token_request.data.decode("utf-8")
aws_token_header = {"X-aws-ec2-metadata-token": token} if token else {}
try:
# This whole block is almost unnecessary. IMDSv1 will be supported
# indefinitely, so the only time this block is needed is if a
# security-conscious user has set the metadata service to require
# IMDSv2. Thus, the very expansive try:except: coverage.

# TODO: should we have a config option to completely disable IMDSv2 to reduce overhead?
ttl_header = {"X-aws-ec2-metadata-token-ttl-seconds": "300"}
token_url = "http://169.254.169.254/latest/api/token"
token_request = http.request("PUT", token_url, headers=ttl_header, timeout=1.0, retries=False)
token = token_request.data.decode("utf-8")
aws_token_header = {"X-aws-ec2-metadata-token": token} if token else {}
except Exception:
aws_token_header = {}
metadata = json.loads(
http.request(
"GET",
"http://169.254.169.254/latest/dynamic/instance-identity/document",
headers=aws_token_header,
timeout=3.0,
timeout=1.0,
retries=False,
).data.decode("utf-8")
)
Expand Down Expand Up @@ -94,7 +103,7 @@ def gcp_metadata():
"GET",
"http://metadata.google.internal/computeMetadata/v1/?recursive=true",
headers=headers,
timeout=3.0,
timeout=1.0,
retries=False,
).data.decode("utf-8")
)
Expand Down Expand Up @@ -135,7 +144,7 @@ def azure_metadata():
"GET",
"http://169.254.169.254/metadata/instance/compute?api-version=2019-08-15",
headers=headers,
timeout=3.0,
timeout=1.0,
retries=False,
).data.decode("utf-8")
)
Expand Down

0 comments on commit 31f03e1

Please sign in to comment.