Working with AWS Regions in Python

Something quick to help with multi region scripts

It’s been a whilst since I posted so thought I’d share a snippet I threw together whilst writing a Python script.

In this post I’ll show you how you can acheive an action in Python using the boto3 library on multiple regions.

In my case I needed to inspect the reserved concurrency status of each lambda function in an account in each region. But I ’m not going to go that deep.

The key thing to note is that the list of aws regions is stored in the ec2 api. So whatever you’re writing you’ll need to setup another boto3 client for ec2. Once you realise this, the rest is easy. Using describe_regions will give you every single piece of information you ever wanted for a region (not that much exists), but maybe this is too much ?

'Regions': [{'Endpoint': 'ec2.eu-north-1.amazonaws.com', 'RegionName': 'eu-north-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.ap-south-1.amazonaws.com', 'RegionName': 'ap-south-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.eu-west-3.amazonaws.com', 'RegionName': 'eu-west-3', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.eu-west-2.amazonaws.com', 'RegionName': 'eu-west-2', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.eu-west-1.amazonaws.com', 'RegionName': 'eu-west-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.ap-northeast-3.amazonaws.com', 'RegionName': 'ap-northeast-3', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.ap-northeast-2.amazonaws.com', 'RegionName': 'ap-northeast-2', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.ap-northeast-1.amazonaws.com', 'RegionName': 'ap-northeast-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.sa-east-1.amazonaws.com', 'RegionName': 'sa-east-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.ca-central-1.amazonaws.com', 'RegionName': 'ca-central-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.ap-southeast-1.amazonaws.com', 'RegionName': 'ap-southeast-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.ap-southeast-2.amazonaws.com', 'RegionName': 'ap-southeast-2', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.eu-central-1.amazonaws.com', 'RegionName': 'eu-central-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.us-east-1.amazonaws.com', 'RegionName': 'us-east-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.us-east-2.amazonaws.com', 'RegionName': 'us-east-2', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.us-west-1.amazonaws.com', 'RegionName': 'us-west-1', 'OptInStatus': 'opt-in-not-required'}, {'Endpoint': 'ec2.us-west-2.amazonaws.com', 'RegionName': 'us-west-2', 'OptInStatus': 'opt-in-not-required'}], 'ResponseMetadata': ... }}

A little ugly yeah? Considering all we want to do is use the Region Name, e.g. ap-southeast-2, etc

Well the rest is just logic.

Create a function in your python application, call it getRegions, myRegions or bob for all I care, just call it something useful. Then as you start your app/script from either your lambda handler or __main__ you can just call your function.

regions = getRegions()

The variable regions is then just a simple list you can loop through to call actions upon.

e.g.

    for region in regions:
        lambda_client = boto3.client('lambda', region_name=region)
        list_functions=lambda_client.list_functions()

Simple yeah? Oh, and my function that I wrote. See below ;)


import boto3

def getRegions():

    regions = []

    ec2_client = boto3.client('ec2')
    describe_regions = ec2_client.describe_regions()
    for region in describe_regions['Regions']:
        regions.append(region['RegionName'])

    return regions 

https://github.com/alanblockley/random_snippets/blob/main/getRegions.py

“Python doesn’t have to be complicated” - Me, today.