In AWS Lambda, you can have multiple environment configurations such as dev, test, staging, production etc using AWS Lambda Aliases. Even if you don’t have aliases, you have 2 default configurations; 1) test
when you are running the Lambda function locally using say VS Code and 2) prod
when the function is run on AWS Lambda service.

But how to figure the current environment in AWS Lambda?
The answer is, from the context
argument in the lambda handler. Whenever the Lambda function is invoked, the context
argument has some attributes that let us know in which alias the Lambda function is currently running in.
This post shows how to have multiple environment configuration files and load those values so they can be used in the the codebase anywhere until the invocation of the Lambda function remains active.
Separate configuration files
Let’s say I have this directory structure:
- test-config.py
- prod-config.py
- lambdaHandler.py
- configLoader.py
- globalConstants.py
- src
- ...
*-config.py
test-config.py
& prod-config.py
are my configurations for test and production environments respectively. They contain dictionaries like this:
class myConfig:
mysql = { 'host': 'localhost', 'user': 'admin', 'password': 'p@$$word!', 'port': 3306, 'database': 'cars' }
Why I am using Python files for configuration instead of json or YAML is just my preference currently and I have my reasons which I will discuss in a separate blog post.
globalConstants.py
globalConstants.py
contains global variables that can be accessed anywhere in the code:
mysql = ''
def __init__():
global mysql
lambdaHandler.py
lambdaHandler.py
is the Lambda handler.
lambdaHandler.py
from configLoader import lambdaConfig
@lambdaConfig
def lambda_handler(event, context):
...
Notice the @lambdaConfig
, this is a Python decorator inside configLoader.py
which I describe in the next section.
configLoader.py: Load configuration
configLoader.py
contains my Python decorator function. I place this decorator on my lambda handler so that my current configuration file gets loaded before any statements inside the lambda handler get executed. A brilliant explanation of Python decorators can be found here.
So we build a Python decorator function:
configLoader.py
import globalConstants
def getEnvironment(context):
# get the Alias name from the Lambda Function ARN
split_arn = context.invoked_function_arn.split(':')
environment = split_arn[len(split_arn) - 1]
return environment
def lambdaConfig(func):
def wrapper(*args, **kwargs):
context = args[1]
environment = getEnvironment(context)
config = __import__(environment + '-config')
globalConstants.mysql = config.myConfig.mysql
return func(*args, **kwargs)
return wrapper
What I am doing here is that I am parsing the incoming context
argument and within it I can see what alias of the Lambda function is currently being invoked.
After I figure the current environment, I load the corresponding config file; test
or prod
. Then I assign values to a global variable inside of globalConstants.py
. I then return the current function upon which the decorator is placed(lambda_handler
) so that it’s invocation can be resumed now.
Accessing values anywhere in code
This way, I am now able to use the current environment values from globalConstants.py
from anywhere inside my code no matter which configuration got loaded:
import globalConstants
host = globalConstants.mysql["host"]
user = globalConstants.mysql["user"]
password = globalConstants.mysql["password"]
Alternatively, inject the config into Lambda function
As can be seen here, you can load the configuration and inject it into the Lambda function as well. All credit goes to that reference as this is the original idea behind my approach, I just didn’t want to inject the config in the Lambda function.
So just do this in your Python decorator:
def lambdaConfig(func):
def wrapper(*args, **kwargs):
context = args[1]
environment = getEnvironment(context)
config = __import__(environment + '-config')
args += (config,)
return func(*args, **kwargs)
return wrapper
Instead of assigning to globalConstants, just add it to the arguments.
In the Lambda handler:
def lambda_handler(event, context, config):
Summary
This post describes how you can use environment variables using Python in AWS Lambda functions by having multiple environment configuration files and loading the corresponding configuration when that AWS alias is invoked. AWS Lambda environment variables are loaded by Python decorators but other languages can also avail it, e.g., C# attributes etc. It also shows 2 possible ways to get the current configuration values, by either using global variables in Python or by injecting the config into the Lambda function.