Reputation: 761
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?
Upvotes: 72
Views: 87284
Reputation: 372
For those using
sam local invoke MyFunction1 --env-vars environment_variables.json -e event.json
and not getting the variables in your function, it’s because the options should go after the function name. It should be
sam local invoke --env-vars environment_variables.json -e event.json MyFunction1
Upvotes: 0
Reputation: 1677
If you're like me and want to set some environment variable only for local development purposes, I got this to work without an environment file by simply defining the environment variable in the template.yaml
file (as shown in the other answers) and then just exporting the variable in the shell:
export MY_VARIABLE=some_value
If I then launch the local environment using:
sam local start-api
the variable is available to my lambda function.
Upvotes: 1
Reputation: 496
You can use the option -n, --env-vars PATH
. This this is JSON file and you need to have an object that maps with your resource name in the template.
template.yaml:
...
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
...
Environment:
Variables:
SOME_VAR: !Ref SomeVar
...
Let's assume your file name for the variables is .env.local.json
. The content should match something like this:
{
"HelloWorldFunction": {
"SOME_VAR": "NEW_VALUE"
}
}
Then you need to run the command:
sam local start-api --env-vars .env.local.json
Upvotes: 5
Reputation: 5005
Here’s a comprehensive solution to use environment-specific variables with AWS SAM. Do not use this approach for secrets!
In the Cloudformation template (template.yaml by default), define the variables and refer to them as needed, for example:
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Parameters:
TargetEnv:
Type: String
Description: Target environment name
DynamoDB:
Type: String
Description: ARN of the DynamoDB table
SecurityGroups:
Type: List<String>
Description: List of VPC security groups
Subnet:
Type: String
Description: VPC subnet identifier
Globals:
Function:
Environment:
Variables:
TargetEnv: !Ref TargetEnv
DynamoDB: !Ref DynamoDB
…
Resources:
ServiceRole:
Type: 'AWS::IAM::Role'
Properties:
Policies:
- PolicyName: dynamodb
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:Query
Resource: !Ref DynamoDB
…
MyFunction1:
Type: AWS::Serverless::Function
Properties:
Role: !GetAtt ServiceRole.Arn
VpcConfig: &vpc_props
SecurityGroupIds: !Ref SecurityGroups
SubnetIds:
- !Ref Subnet
…
The variables that are listed under Globals.Function.Environment.Variables
are also available at runtime – in Node.js in this example as process.env.TargetEnv
and process.env.DynamoDB
Then, set the parameters’ values in SAM’s configuration (samconfig.yaml by default, or use the TOML format if you prefer).
version: 0.1
default:
build:
parameters:
cached: true
parallel: true
deploy:
parameters: &default_deploy_parameters
stack_name: my-service
s3_prefix: my-service
resolve_s3: true
region: eu-central-1
capabilities: CAPABILITY_IAM
image_repositories: []
staging:
deploy: &staging_deploy
parameters:
<<: *default_deploy_parameters
parameter_overrides:
- TargetEnv=staging
- HandshakeTable=arn:aws:dynamodb:eu-central-1:07867760868:table/MyTable
- SecurityGroups=sg-61f4470b87daef18c,sg-72a87ea4bf7f4b5d2
- Subnet=subnet-16b4ca88aca7ab4b8
local_start_api: *staging_deploy
local_invoke: *staging_deploy
production:
deploy:
parameters:
<<: *default_deploy_parameters
parameter_overrides:
- TargetEnv=production
- HandshakeTable=arn:aws:dynamodb:eu-central-1:870517811788:table/MyTable
- SecurityGroups=sg-9fa4b495c33d84a18,sg-fcb69e4ca84aa7e81
- Subnet=subnet-daad36a5d2a700a8e
Finally, you can use the environments defined in the template (staging
, production
) with the respective commands.
sam deploy --config-env staging
sam local start-api --config-env staging
sam local invoke MyFunction1 --config-env staging
sam deploy --config-env production
For sam build
, the environment must not be specified.
Upvotes: 1
Reputation: 364
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
Upvotes: 1
Reputation: 10241
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
Upvotes: 52
Reputation: 11006
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.
Upvotes: 88
Reputation: 147
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" } }
Upvotes: 6
Reputation: 1352
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.
Upvotes: 13