8

i want to set or modify an environment variable in my lambda script. I need to save a value for the next call of my script. For exemple i create an environment variable with the aws lambda console and don't set value. After that i try this :

import boto3
import os

if os.environ['ENV_VAR']:
   print(os.environ['ENV_VAR'])
os.environ['ENV_VAR'] = "new value"

In this case my value will never print. I tried with :

os.putenv()

but it's the same result. Do you know why this environment variable is not set ?

Thank you !

palaho
  • 93
  • 1
  • 1
  • 4

3 Answers3

15

Consider using the boto3 lambda command, update_function_configuration to update the environment variable.

response = client.update_function_configuration(
            FunctionName='test-env-var',
            Environment={
                'Variables': {
                    'env_var': 'hello'
                }
            }
        )
Jason
  • 159
  • 1
  • 3
  • But this code is removing the old environment variables. Is there any work around. – Srinivasu May 25 '18 at 11:46
  • 1
    Environment variables are bet understood as an effective mechanism to pass parameters that are _static_. In an ostensibly highly concurrent runtime environment such as lambda, it doesn't make any sense for each execution to update the configuration parameters for each subsequent execution because it doesn't account for concurrency. It would be "last write wins". Further, this will trash your Lambda performance because updating a function configuration will not be particularly fast. And, it invalidates any of your cached lambda runtimes. This is _not_ the right way to approach this problem – erik258 Aug 09 '18 at 17:34
7

I need to save a value for the next call of my script.

That's not how environment variables work, nor is it how lambda works. Environment variables cannot be set in a child process for the parent - a process can only set environment variables in its own and child process environments.

This may be confusing to you if you set environment variables at the shell, but in that case, the shell is the long running process setting and getting your environment variables, not the programs it calls.

Consider this example:

from os import environ
print environ['A']
environ['A'] = "Set from python"
print environ['A']

This will only set env A for itself. If you run it several times, the initial value of A is always the shell's value, never the value python sets.

$ export A="set from bash"
$ python t.py
set from bash
Set from python
$ python t.py
set from bash
Set from python

Further, even if that wasn't the case, it wouldn't work reliably with aws lambda. Lambda runs your code on whatever compute resources are available at the time; it will typically cache runtimes for frequently executed functions, so in these cases data could be written to the filesystem to preserve it. But if the next invocation wasn't run in that runtime, your data would be lost.

For your needs, you want to preserve your data outside the lambda. Some obvious options are: write to s3, write to dynamo, or, write to sqs. The next invocation would read from that location, achieving the desired result.

erik258
  • 14,701
  • 2
  • 25
  • 31
  • If passing the value to the next execution of the script can be "best effort", you can store the data in the cached function storage. If the same cached function runtime is used on the next execution, the value will be there. Another concurrent invocation will get a new runtime and won't have the value. The runtime might also be evicted from AWS lambda's cache, in which case the value would also be gone. But for best-effort caching this is a very performant and effective mechanism. – erik258 Aug 09 '18 at 17:36
2

AWS Lambda just executes the piece of code with given set of inputs. Once executed, it returns the output and that's all. If you want to preserve the output for your next call, then you probably need to store that in DB or Queue as Dan said. I personally use SQS in conjunction with SNS that sends me notifications about current state. You can even store the end result like success or failure in SQS which you can use for next trigger. Just throwing the options here, rest all depends on your requirements.

Karan B
  • 21
  • 4