A Step by Step Guide with Python Code Snippets My first attempt to log EC2 instance names to and broke most of our infrastructure. I failed to account for unpublished AWS rate limits, and when an unexpected volume of errors caused my code hit those rate limits, insufficient error handling led to an infinite loop when errors were thrown in our exception loggers. PagerDuty Airbrake I hope that this tutorial can save you some of my headache. I’ll walk you through how to use the Python client to access the name of a running EC2 instance from that instance, and along the way I’ll include caveats and gotchas that will help you avoid some of my mistakes. boto3 Pre-Requisites . This tutorial assumes that you are familiar with using AWS’s boto3 Python client, and that you have followed AWS’s instructions to configure your AWS credentials. Boto3 , a Python HTTP library. Requests Get the Instance Id and Region Most information about the instance is accessible with the . To create that resource, we first need to retrieve the instance id and instance region. boto3 Instance resource AWS provides via the url , which you can request from any running EC2 instance. In particular, we are interested in the , which is accessible at . Instance Metadata and User Data http://169.254.169.254 Instance Identity Document http://169.254.169.254/latest/dynamic/instance-identity/document import requests r = requests.get("http://169.254.169.254/latest/dynamic/instance-identity/document")response_json = r.json()region = response_json.get('region')instance_id = response_json.get('instanceId') If you are not familiar with the library, I would recommend checking out , particularly the function, as a starting point for error handling. requests Response Status Codes raise_for_status Get the Instance Resource We can then use the instance id and region to retrieve the . boto3 Instance resource import boto3 ec2 = boto3.resource('ec2', region_name=region)instance = ec2.Instance(instance_id) Validate and before passing them to region instance_id boto3 The first step of is to catch and , both found in the package. boto3 error handling ClientError BotoCoreError botocore.exceptions In my experience, the client has pretty confusing error handling for invalid or region or instance ids. In addition to the errors mentioned above, values in either field will raise the Python built-in . I would recommend that you do not attempt to use the client if is false. boto3 None None ValueError boto3 region && instance_id Get the Name An instance’s “Name” is really an instance tag with the key “Name”. You can retrieve tags from the instance resource, and filter for tags. Name tags = instance.tags or []names = [tag.get('Value') for tag in tags if tag.get('Key') == 'Name']name = names[0] if names else None Because attributes are lazy-loaded, some invalid instance ids throw errors here According to the , resource attributes are lazy-loaded, meaning that the first API call is made when the attribute is first accessed. This means that while or empty strings are validated when creating the resource, non-empty string ids that are the right type but the wrong value will be validated here, with the first call. To combat this, you’ll want to attempt to catch the Exceptions from the last section. boto3 documentation None ec2.Instance DescribeInstances botocore.exceptions Gotcha! From the section on : Open Guide To AWS EC2 gotchas and limitations ❗If the EC2 API itself is a critical dependency of your infrastructure (e.g. for automated server replacement, custom scaling algorithms, etc.) and you are running at a large scale or making many EC2 API calls, make sure that you understand when they might fail (calls to it are rate limited and the limits are not published and subject to change) and code and test against that possibility. The client loads information about an instance with the API call. If you, for instance, make this API call to retrieve the instance name every time you log an error, you could easily hit the rate limit. boto3 DescribeInstances DescribeInstances In addition to the error handling mentioned above, you will want to consolidate your calls to the API to avoid hitting the unpublished AWS rate limits. Our solution was to fetch the instance name once at the of the API server, and cache the result in a global data structure. Instead of calling the EC2 API every time we need to log an error, we now call it only once when deploying new code to a machine. AWS startup Put it All Together Here is an example of what a final function could look like. get_instance_name