'aws-sam-local environment variables

I am following the readme here: https://github.com/awslabs/aws-sam-local

I have a lambda written in python 3.6 and its similar to the helloworld example here : https://github.com/awslabs/aws-sam-local/tree/develop/samples/hello-world/python

template.yml looks as such:

AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: MyFunction1 API
Resources:
  MyFunction1:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: MyFunction1
      Handler: lambda_module.lambda_handler
      Runtime: python3.6
      CodeUri: lambda.zip
      MemorySize: 128
      Timeout: 10
      Policies:
        -AWSLamdbaBasicExecutionRole
      Events:
        BingLambdaEndpoint:
          Type: Api
          Properties:
            Path: MyFunction1/search
            Method: get

I have environment variables within the lambda but not able to wire them up on start up. Documentation says I can create a environments.json file and append the following on the invoke command : Use --env-vars argument of invoke

My environment file looks like the example and I get an error: Unable to find environment variable: api_key

environment.json looks as such:

{
  "MyFunction1": {
    "api_key": "123456789",
    "BUCKET_NAME": "testBucket"
  }
}

command I run is as such:

sam local invoke MyFunction1 --env-vars environment_variables.json -e event.json

Can anyone provide additional insight?



Solution 1:[1]

Any environment variables you want to use with SAM Local in this manner need to exist in your SAM template. From this GitHub issue:

... SAM Local only parses environment variables that are defined in the SAM template.

In the template, you can provide no value, an empty string, or choose a sensible default.

A portion of a template including environment variables:

Resources:
  MyFunction1:
    Type: 'AWS::Serverless::Function'
    Properties:
      .....
      Environment:
        Variables:
          api_key:
          BUCKET_NAME:

You can think of the environment variables file as a mechanism to override environment variables that the template "knows" about. It does not work as a mechanism to inject arbitrary environment variables into the local runtime.

Solution 2:[2]

template file

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
  
Globals:

  Function:
    Timeout: 3

Parameters:

  SomeVar:
    Type: String
    Description: My SomeVar
    Default: default value

Resources:

  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs12.x
      Environment:
        Variables:
          SOME_VAR: !Ref SomeVar
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get

Outputs:

  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"

  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn

  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn

from https://github.com/awslabs/aws-sam-cli/issues/1163#issuecomment-557874976

then in code

console.log(process.env.SOME_VAR);

when you run sam local start-api and it will print default value

when you run sam local start-api --parameter-overrides SomeVar=other_value and it will print other_value

then if you create file env.json with this content

{ "PreviewsFunction": { "SOME_VAR": "123" } }

when you run sam local start-api --env-vars env.json and it will print 123

p.s. it will work with start-api/start-lambda/invoke all in the same way, but it looks like sam deploy only works with --parameter-overrides SomeVar=other_value and no --env-vars

Solution 3:[3]

Ensure that the variables are declared in template.yml. A config file overwrites the variables but does not create variables when they don't exist in the original template.

Solution 4:[4]

I had the same issue. When I ran

sam local start-api --env-vars  env.json 

The values in env.json where not being read. What fixed the issue for me was to use the following format in env.json

"Parameters": {
    "PARAM_NAME": "VALUE"
}

The other format did not work for me:

{ "function": { "PARAM_NAME": "VALUE" } }

Solution 5:[5]

Make sure that your template's parameters have NoEcho equals true, like in this example:

Parameters:
  # Build variables
  Stage:
    Type: String
  # Environment variables
  MssqlServer:
    Type: String
    NoEcho: true
  MssqlDatabase:
    Type: String
    NoEcho: true
  MssqlUser:
    Type: String
    NoEcho: true
  MssqlPassword:
    Type: String
    NoEcho: true

Then you can simply pass the environment variables with a command like this:

sam deploy --parameter-overrides "MssqlServer='$MSSQL_SERVER' MssqlDatabase='$MSSQL_DATABASE' MssqlUser='$MSSQL_USER' MssqlPassword='$MSSQL_PASSWORD' Stage=dev" --config-env dev

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Daryn
Solution 2 Daryn
Solution 3 toonsend
Solution 4 hkutluay
Solution 5 Leopoldo Varela