def aws_metadata()

in elasticapm/utils/cloud.py [0:0]


def aws_metadata():
    """
    Fetch AWS metadata from the local metadata server. If metadata server is
    not found, return an empty dictionary
    """
    http = urllib3.PoolManager()

    try:
        # This will throw an error if the metadata server isn't available,
        # and will be quiet in the logs, unlike urllib3
        with socket.create_connection(("169.254.169.254", 80), 0.1):
            pass

        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=1.0,
                retries=False,
            ).data.decode("utf-8")
        )

        return {
            "account": {"id": metadata["accountId"]},
            "instance": {"id": metadata["instanceId"]},
            "availability_zone": metadata["availabilityZone"],
            "machine": {"type": metadata["instanceType"]},
            "provider": "aws",
            "region": metadata["region"],
        }

    except Exception:
        # Not on an AWS box
        return {}