Skip to content

Instantly share code, notes, and snippets.

Last active November 6, 2022 10:14
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save patrickbrandt/21fc41459fe6a6a19e31 to your computer and use it in GitHub Desktop.
Save patrickbrandt/21fc41459fe6a6a19e31 to your computer and use it in GitHub Desktop.
A simple approach to multi-environment configurations for AWS Lambda functions

AWS recently released Versioning and Aliases for Lambda Functions. I'm going to outline how I've taken advantage of this to provide environmentally-aware Lambda function configurations in Python.

AWS Lambda doesn't currently support environment variables, so 12-factor-style configuration isn't an option. I'll be using seprate config files for each environment.


We're making two assumptions for this article:

  • I've already created an AWS Lambda function with the following aliases:
    • Dev
    • Test
    • Staging
    • Production
  • I've put together a deployment routine that will create and deploy a Python Deployment Package

The configuration files

My (simplified) project folder structure looks like this:

  • My Lambda function handler is in
  • The config directory contains specific * files for each Lambda function alias/environment
  • The module contains the code used to inject environment-specific values into the Lambda function handler

As an example, here's what my file looks like:

class MyName:
    first_name = "Bandit"
    last_name = "Brandit"

The configuration code

I'm using a Python Function Decorator to inject a config argument into my Lambda function handler.

Let's start with a basic handler in

def myfunction_handler(event, context):
    message = 'Hello {} {}!'.format(event['first_name'], 
    return { 
        'message' : message

I'm going to add the @import_config decorator that injects the environment-specific configuration:

from lambda_utils import *

def myfunction_handler(event, context, config):
    message = 'Hello {} {}!'.format(config.MyName.first_name, 
    return { 
        'message' : message

Here's the @import_config decorator code in

def get_env(context):
    # get the Alias name from the Lambda Function ARN
    split_arn = context.invoked_function_arn.split(':')
    env = split_arn[len(split_arn) - 1]
    return env

def import_config(f):
    def wrapper(*args, **kwargs):
        context = args[1]
        env = get_env(context)
        config = __import__(env + '-config')
        args += (config,)
        return f(*args, **kwargs)
    return wrapper


That's it! Put your * and files into your deployment package and you're good to go.

In the real world, I've used this pattern to integrate with environment-specific DynamoDB tables. It is also quite handy when defining configurations for local development (i.e. each developer has their own config). More on local Lambda function development to come...

Copy link

Hey Patrick,
Can u tell me how did u put together a deployment routine for lambda functions and from where would u push the updates?
Thank u!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment