Introduction
We will go over How To Detect If I am Running In AWS Lambda Environment.
Did you know that detecting the AWS environment can allow you to test your lambda locally in the same code?
I will break this review in the following sections:
- Talk about the general techniques to detect an AWS environment
- Provide an example of how to do this in NodeJS and Python
- Test it out and see some real examples first locally and then in AWS
I have used this successfully in various projects and it works very well and has saved me a ton of time debugging code since the same code works in both locally and in AWS.
We will go point by point on getting you up and running in less than 5mins of work.
This is a complete guide and should cover all your questions on How To Detect If I am Running In AWS Lambda Environment.
All code and examples on how to do this can be found in the Github link here.
Researching Ways To See If You Are In AWS Lambda Environment
The one thing we will be doing is that AWS lambdas are basically mini versions of a Linux operating system. Like with everything else they have what is called an environment.
The environment allows you to define some variables that are very specific to your execution context. For example your local shell and computer has an execution environment which contains a certain set of variables needed for your shell to operate properly.
Since those are very unique to what you are looking at we will write a small snippet Lambda code that will basically just list all the environment variables that exist in an AWS Lambda function.
Doing this will allow us to basically investigate and see what differences it has with a normal execution environment such as a SHELL. If we see anything of interest we will basically be able to see if that variable is set in the environment and base our code conditions on that. We will demonstrate this later in this article.
So lets start by writing the Python code that will run inside a lambda.
import os def lambda_handler(event, context): for k,v in os.environ.items(): print (f'{k}={v}') return
The code above is very simple in nature all it does it enumerate the environment items and just print the key and their value inside a loop.
Now that we have the code finished we can go ahead and run it inside a Lambda environment to see what output we will get and if there’s anything in those variables that we can use later for detecting the AWS environment.
AWS_LAMBDA_FUNCTION_VERSION=$LATEST AWS_SESSION_TOKEN=ABCDE AWS_LAMBDA_LOG_GROUP_NAME=/aws/lambda/unbiased_coder_python_lambda LAMBDA_TASK_ROOT=/var/task LD_LIBRARY_PATH=/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib AWS_LAMBDA_RUNTIME_API=unbiased-coder.com:9001 AWS_LAMBDA_LOG_STREAM_NAME=2022/04/14/[$LATEST]cc7d335a96ac49e3a751de7d5d5bbd59 AWS_EXECUTION_ENV=AWS_Lambda_python3.9 AWS_LAMBDA_FUNCTION_NAME=unbiased_coder_python_lambda AWS_XRAY_DAEMON_ADDRESS=169.254.79.129:2000 PATH=/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin AWS_DEFAULT_REGION=us-east-1 PWD=/var/task AWS_SECRET_ACCESS_KEY=33137 LANG=en_US.UTF-8 LAMBDA_RUNTIME_DIR=/var/runtime AWS_LAMBDA_INITIALIZATION_TYPE=on-demand AWS_REGION=us-east-1 TZ=:UTC AWS_ACCESS_KEY_ID=ABCDE SHLVL=0 _AWS_XRAY_DAEMON_ADDRESS=169.254.79.129 _AWS_XRAY_DAEMON_PORT=2000 AWS_XRAY_CONTEXT_MISSING=LOG_ERROR _HANDLER=lambda_function.lambda_handler AWS_LAMBDA_FUNCTION_MEMORY_SIZE=128 PYTHONPATH=/var/runtime _X_AMZN_TRACE_ID=Root=1-625865da-6e8264250d584e706e2abdec;Parent=60fa84f61c8327a0;Sampled=0
As you can see above there’s a lot of AWS_ prefix variables that we can use for detection. Those are typically not in a normal shell or executing environment and they are all very useful for us.
Now all we have to do is basically compare this output with a normal shell execution environment and see if they exist there.
To do this we will be running basically the same Python script in our local computer so it can list all the environment variables that we have.
$ python ./lambda_python_dump_environment.py TERM_SESSION_ID=w0t1p0:5B7DA628-2514-43CC-8756-7F9B6AB18E9A SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.pMMSUkZ0eF/Listeners LC_TERMINAL_VERSION=3.4.15 COLORFGBG=7;0 ITERM_PROFILE=Default XPC_FLAGS=0x0 LANG=en_US.UTF-8 PWD=/Users/alex/code/unbiased/python-nodejs-detect-aws-environment-lambda SHELL=/bin/zsh __CFBundleIdentifier=com.googlecode.iterm2 TERM_PROGRAM_VERSION=3.4.15 TERM_PROGRAM=iTerm.app PATH=/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Users/alex/.fig/bin:/Users/alex/Library/Android/Sdk/emulator:/Users/alex/Library/Android/Sdk/tools:/Users/alex/Library/Android/Sdk/tools/bin:/Users/alex/Library/Android/Sdk/platform-tools LC_TERMINAL=iTerm2 COLORTERM=truecolor COMMAND_MODE=unix2003 TERM=xterm-256color HOME=/Users/alex TMPDIR=/var/folders/m4/v8cg9xl14vv660s3fskfz9900000gn/T/ USER=alex XPC_SERVICE_NAME=0 LOGNAME=alex ITERM_SESSION_ID=w0t1p0:5B7DA628-2514-43CC-8756-7F9B6AB18E9A __CF_USER_TEXT_ENCODING=0x1F5:0x0:0x0 SHLVL=1 OLDPWD=/Users/alex/code/unbiased ZSH=/Users/alex/.oh-my-zsh PAGER=less LESS=-F -X -R LSCOLORS=Gxfxcxdxbxegedabagacad VIRTUAL_ENV_DISABLE_PROMPT=1 ANDROID_HOME=/Users/alex/Library/Android/Sdk ANDROID_SDK_ROOT=/Users/alex/Library/Android/Sdk ADB=/Users/alex/Android/Sdk/platform-tools/adb HOMEBREW_PREFIX=/opt/homebrew HOMEBREW_CELLAR=/opt/homebrew/Cellar HOMEBREW_REPOSITORY=/opt/homebrew MANPATH=/opt/homebrew/share/man:: INFOPATH=/opt/homebrew/share/info: JAVA_HOME=/Applications/Android Studio.app/Contents/jre/Contents/Home _=/opt/homebrew/bin/python3
As it can be seen above those two are vastly different from each other. The AWS environment basically contains a lot of AWS specific variables which do not exist in a normal local computer.
Using the fact above we can determine if we are running inside a shell or if you are running in AWS. All we will have to do is basically look for some of those unique AWS variables and that would basically tell us that our code is inside a Lambda.
In the next sections we will write code that demonstrate this in two different lambda flavors:
- Python
- NodeJS – Javascript
The code will be pretty similar in both cases and will make use of the above explanation.
Selecting The Right Environment Variables To Detect An AWS Lambda Environment
Before we do this however we need to select a few environment variables that will be in every lambda function and they will not ever be set locally from the code that runs in our machine.
Let’s better understand this, one important part of it is that when you are writing code locally that executes in your machine and you want to connect to some AWS services you have two options to tell your code how to do this:
- Using AWS credentials file
- Setting some environment variables for the secret and access key
While the first method will never have an impact in our detection code, the second one will. The reason that it will have an impact is because it’s basically setting in the environment variables that also exist in the AWS Lambda context, more specifically you need to set things such as:
- AWS_REGION
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- AWS_SESSION_TOKEN
This basically excludes some of those AWS variables we can use from the list above.
The good news here is that we have a plethora of other variables we can pick from. In this case we will be going with the following two:
- AWS_LAMBDA_FUNCTION_NAME
- AWS_EXECUTION_ENV
The reason we are picking two is that if AWS in the future decides to change the name of one of those two we will still be able to fall back on the other one. If it changes both then you can probably add a few more in the list you are checking for.
To keep things simple in our code that we will demonstrate below we will only be picking two but feel free to include as many as you want. Our selection was careful to pick variables that I basically think will not get deprecated easily in the future such as the Lambda name and the execution environment.
How To Detect If You Are In AWS Lambda Environment In Python
Now that we have the basic concept down lets go ahead and start implementing it inside an AWS Lambda function using Python.
To do this we will be coding a function called is_aws_env() which will be a helper function to tell us whether or not the code is running in AWS Lambda or locally.
import os def is_aws_env(): return os.environ.get('AWS_LAMBDA_FUNCTION_NAME') or os.environ.get('AWS_EXECUTION_ENV') def lambda_handler(event, context): if is_aws_env(): print ('We are running inside an AWS environment') else: print ('We are running outside an AWS environment') if not is_aws_env(): lambda_handler({}, {})
As it can be seen above we are checking for the two AWS environment variables we mentioned earlier. If our code works we should see proper detection of the AWS environment.
Let’s go and test this first in our local machine and after we can test it in the AWS Lambda function itself that runs in AWS.
$ python python_detect_aws_environment.py We are running outside an AWS environment
As shown above basically our code successfully detected that we are running outside an AWS environment since the AWS variables we are checking for are not set in our systems shell (in my case it’s ZSH running on a Mac computer).
To verify this works on AWS we will be logging in the AWS console and running our Lambda there too.
I have a full article on how to do this which you can find here: How to Setup an AWS Lambda Python Function From Scratch
Test Event Name test89 Response null Function Logs START RequestId: 8a5a7991-1215-4d5c-aa54-d636cf270c58 Version: $LATEST We are running inside an AWS environment END RequestId: 8a5a7991-1215-4d5c-aa54-d636cf270c58 REPORT RequestId: 8a5a7991-1215-4d5c-aa54-d636cf270c58 Duration: 4.39 ms Billed Duration: 5 ms Memory Size: 128 MB Max Memory Used: 37 MB Init Duration: 226.89 ms Request ID 8a5a7991-1215-4d5c-aa54-d636cf270c58
From the log above we can clearly see the printout that it’s detecting that we are running inside an AWS environment. This successfully demonstrates that our Python code is functional and can be used conditionally to perform anything you need.
This can be helpful for various things which I will list below:
- Be able to run the Lambda code locally without having to upload
- Be able to debug your code easier and step through every call you make
- If it’s a long executing process and the code will be used as a one off you can run it from your PC without having to worry about the AWS Lambda limits. (I have an article on this here: Limitations Of AWS Lambda Functions)
How To Detect If You Are In AWS Lambda Environment In NodeJS
Similarly like we did with the Python code above we will be doing with the NodeJS using Javascript. Again we will define a function called is_aws_env() which will basically do the same job.
The only thing that changes here is that NodeJS/Javascript has a system module called process which lets us access things such as the environment of the executing context. If we were to investigate the output of the process environment in Javascript like we did earlier we will find the same output of environment variables that we can use.
So basically we do not have to do the same amount of research as before we can take the learnings and just adapt them into Javascript code.
An example of this can be demonstrated below.
function is_aws_env() { return process.env['AWS_LAMBDA_FUNCTION_NAME'] || process.env['AWS_EXECUTION_ENV']; } exports.handler = async (event) => { if (is_aws_env()) console.log('Running inside AWS environment'); else console.log('Running outside AWS environment'); }; if (!is_aws_env()) exports.handler({});
To verify we also run this code like we did with Python in our local environment. Note that this assumes that you have NodeJS installed locally in your computer. If you do not have it installed you can refer to this guide here and find out more about it.
$ node ./nodejs_detect_aws_environment.js Running outside AWS environment
Once executed we verify that our code knows we are outside an AWS environment. Similarly next we are going to test it in the AWS Lambda environment to ensure that it works there too.
Test Event Name test91 Response null Function Logs START RequestId: c8e4cfa5-ab0f-4097-a31e-0d67ecb78273 Version: $LATEST 2022-04-14T18:34:17.548Z c8e4cfa5-ab0f-4097-a31e-0d67ecb78273 INFO Running inside AWS environment END RequestId: c8e4cfa5-ab0f-4097-a31e-0d67ecb78273 REPORT RequestId: c8e4cfa5-ab0f-4097-a31e-0d67ecb78273 Duration: 13.60 ms Billed Duration: 14 ms Memory Size: 128 MB Max Memory Used: 56 MB Init Duration: 175.62 ms Request ID c8e4cfa5-ab0f-4097-a31e-0d67ecb78273
As you can see from the log print out the code properly see’s the variables and knows we are inside an AWS Lambda environment context.
How To Make Code Work In Both AWS Lambda Environment And Locally
In order to do this you simply need to use the code examples mentioned above. In the last few lines of each example in both Python and NodeJS there’s a condition to run our handler function which is the entry point of every lambda by detecting if we are not inside AWS.
The way this works in AWS is that by default AWS will invoke your Lambda handler for you so in that case we do not need to do it.
So we are basically leveraging our detection code to see if we need to execute the handler on our own or let AWS do it for us.
Conclusion
We were able to successfully go over How To Detect If I am Running In AWS Lambda Environment, hopefully I answered any questions you may have had and helped you get started on debugging and testing your AWS Lambda locally.
If you found this useful and you think it may have helped you please drop me a cheer below I would appreciate it.
If you have any questions, comments please post them below or send me a note on my twitter. I check periodically and try to answer them in the priority they come in. Also if you have any corrections please do let me know and I’ll update the article with new updates or mistakes I did.
Which is your favorite method to detect if you are inside an AWS Lambda environment?
I personally like to run the environment variable check for the AWS region.
If you would like to visit the official AWS Lambda documentation here.
If you would like to find more articles related to Lambdas below:
- How To Create An AWS Python Lambda Layer
- How To Store Global Environment Variables In AWS
- How To Setup AWS Lambda Using AWS CDK Python
- How To Access Environment Variables For AWS Lambda
- Fix AWS Python No module named lambda_function
- How to Setup an AWS Lambda Python Function From Scratch
- AWS Lambda vs AWS Step Functions
- How To Create An AWS Python Lambda Layer