27

I've got a Python application that connects to a database and I would like the db credentials to be different when it's running in local env (for testing) or within a lambda function (for production).

Is there any way, from the Python app, to detect that it is running inside the lambda function?

laurent
  • 88,262
  • 77
  • 290
  • 428

5 Answers5

33

EDIT 2: Thanks @MarkB for the update regarding the new feature of custom runtimes.

The Approach: There are certain environment variables whose value is set when code runs in AWS. Checking for the existence of such variables would indicate that the code is running in AWS.

However, due to a new feature my previous take on it with AWS_EXECUTION_ENV environment variable does not work in all cases. From the docs here https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html The AWS_EXECUTION_ENV environment variable is not defined for custom runtimes, which means that checking for its existence when using custom runtimes would not be an indicator of whether the code is running on AWS. One can check for the existence of one of the other AWS_* specific environment variables (see link above). Which one is right for you might depend on your use case. But Mark's suggestion looks good!

os.environ.get("AWS_LAMBDA_FUNCTION_NAME") is not None

This works for me The following would work as long as you are using a standard AWS runtime environment

os.environ.get("AWS_EXECUTION_ENV") is not None

EDIT: I find the existence of the context object insufficient for such a check because you might be mocking it when not running within an AWS lambda function. Then again, you may be mocking the AWS_EXECUTION_ENV as well ...

7

EDIT 2: With the introduction of Lambda function custom runtimes, it may be better to check for the AWS_LAMBDA_FUNCTION_NAME environment variable, like so:

os.environ.get("AWS_LAMBDA_FUNCTION_NAME") is not None

EDIT: See the other answer, this is a better solution:

os.environ.get("AWS_EXECUTION_ENV") is not None

Original answer:

How about checking for the existence of the context object in the handler function? http://docs.aws.amazon.com/lambda/latest/dg/python-programming-model-handler-types.html

Mark B
  • 183,023
  • 24
  • 297
  • 295
  • 7
    That only works in the handler function. Would be nice to know globally. – Jason Mar 30 '17 at 23:56
  • the `AWS_REGION` env would be set – Jonathan Mar 12 '18 at 10:05
  • 1
    @Jonathan the `AWS_REGION` environment would also be set locally if you are using environment variables to configure the AWS CLI/SDK, so I don't think that's a good one to use here. `AWS_EXECUTION_ENV` seems more appropriate. – Mark B Dec 11 '20 at 13:44
  • 1
    Checking for context object doesn't work for library code. AWS_EXECUTION_ENV seems promising. – Chris Wolf Aug 06 '21 at 00:32
  • According to AWS documentation: "the AWS_EXECUTION_ENV environment variable is not defined for custom runtimes (for example, runtimes that use the provided or provided.al2 identifiers)." I think that AWS_LAMBDA_FUNCTION_NAME might be more suitable since it is always inserted – Yoni Melki Jun 02 '22 at 12:52
  • @YoniMelki thank you, I don't think custom runtimes were available when I wrote this answer originally back in 2016. I've updated the answer with your input. – Mark B Jun 02 '22 at 13:38
1

For unit testing I use the structure:

+ my_function/
+- __init__.py - empty files
+- code/
   +- __init__.py
   +- lambda_function.py
+- unittest/
   +- __init__.py
   +- tests.py - from ..code.lambda_function import *

When running unit tests with python -m my_function.unittest.tests, in lambda_function.py the __name__ == 'my_function.code.lambda_function'.

When running in the Lambda running, __name__ == 'lambda_function'. Note that you'll get the same value if you run with python -m my_function.code.lambda_function so you'll always need a wrapper.

Jason
  • 9,408
  • 5
  • 36
  • 36
0

This is what I use

import os

try:
  region = os.environ['AWS_REGION']
except:
  # Not in Lambda environment
  region = "us-east-1"
Jonathan
  • 10,792
  • 5
  • 65
  • 85
-2

Because of this bug it is possible to tell if you are running inside an AWS Lambda Function.

import multiprocessing

def on_lambda():
    try:
        multiprocessing.Pool()
        on_lambda = False
    except:
        on_lambda = True
    return on_lambda

I used this to implement context sensible metric reporting successfully. Lets hope they don't fix the bug any soon!