-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SAM deploy doesn't set environment variables #1163
Comments
Same issue here. My current workaround is to use CF parameters, since template.ymlAWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
SomeFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: some-function/
Handler: index.handler
Runtime: nodejs8.10
Environment:
Variables:
SOME_VAR: !Ref SomeVar
Parameters:
SomeVar:
Type: String $ sam package --template-file template.yml --s3-bucket BUCKET_NAME --output-template-file packaged.yml $ sam deploy --template-file packaged.yml --stack-name STACK_NAME --capabilities CAPABILITY_IAM --parameter-overrides SomeVar=123 |
@jsonmaur Thanks for sharing a workaround! Do you know if that is compatible with local development (i.e. |
Works fine for me when I run |
Is there any response to this? I'm seeing the same thing.
Trying to execute the Lambda then fails with the predictable "environment variable not defined" result. |
Hi! Any updates on this issue? Thanks! |
Wow does SAM make setting environment variables complicated! @jsonmaur's workaround seems the best, using the (undocumented in sam docs)
So I tried using the |
Yeah the I store my config file as a JSON file, such as
And define them as parameters in the
Then for development I have the following in
So I can run Then for deployment our CI runs:
Surprising amount of work to get sane environment variables in SAM... I think this needs some developer experience TLC or maybe I'm missing something blatantly obvious 😅 |
this is an issue. My
|
@LEscobar-Driver capital ‘V’ in |
@whereisaaron does nothing at all. Still the same |
For local testing, you can override env variables in a few ways, including the If this doesn't cover your needs, it could help to explain more about what you're trying to do. |
@awood45 Thanks for jumping in! I will see if I can provide some context. Essentially, I'm looking for a unified method for configuring the application that works both in sam local and sam deploy. For example, when I create a non-serverless Node.js application based on express, in the documentation I can provide information on what environment variables are expected to be present. Developers can define these in their environment for local dev, and in production the server can set those environment variables. It's the same interface, it's well defined intuitively, and it's conventional. I thought I had similar behaviour in SAM, as I found a Github issue mentioning how to pass through environment variables by setting them to an empty value in the template. That was great! It was frustrating to learn this does not work when deploying. Some notes on my goals:
FWIW I think there is both dev UX aspects and documentation aspects here. I have ideals about how to deploy, which would be great if we could improve the dev UX there, but realistically documentation is what originally made me create the issue here. When I went to figure out how to add environment variables in dev I couldn't find any documentation on this at all. I did find an answer through Github issues. When I found that didn't work in production, I again couldn't find any documentation at all on how to actually deploy environment variables, and had to get help on this issue here from @jsonmaur to get deploy working. It may seem intuitive as it uses another AWS command under the hood, but do consider that users of SAM for the first time might not be familiar with how to deploy lambda's under cloudformation. This has been my experience over many months so it's possible that docs have improved since then but I definitely found it unclear how to actually deploy an app with env variables. Does that clarify a bit? Happy to help elaborate some more if needed. |
I too expected SAM would have a consistent way to handle env vars between running locally and deploying. Like @jsonmaur I expected Right now |
We'll definitely want to improve documentation on the deploy difference, though I would agree we should at minimum converge options on build/local to match. One issue with deployments is that they are simply a CloudFormation deployment. What you'd be asking for in that case is for Unfortunately the ship has sailed to an extent for naming this better without it being a breaking change, but it's really a way to override your production env variables for local testing. |
To add more context to the "We have 3 different ways to do environment variables". The Now to the "build and local have different way than deploy for Sadly, we didn't have a better way. Currently deploy still shells out to the AWS CLI (which we will be addressing separately). When we introduced the Hopefully that sheds some light on why, it is what it is right now. We know the inconsistency is a UX problem and rough edge right now. |
Thank you both for the context! |
Thanks for the background. Everyone here seems to agree (!) that |
I'm trying to follow the example you shared above, but instead of the value of the parameter, the name of the parameter itself getting into the env variable i.e., SOME_VAR = 'SomeVar', also I want to set the default value of parameters; based on my understanding it should be done as below but none of the way it is working **Parameters:
|
I agree that documentation could be better - the most important is to add missing param
Working example template.yaml 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 When you run: sam build
sam local invoke HelloWorldFunction -e events/event.json the default value will be used - in our case: To deploy run commands: sam package --template-file template.yaml \
--s3-bucket my-bucket \
--output-template-file packaged.yaml
sam deploy --template-file packaged.yaml \
--stack-name my-application \
--capabilities CAPABILITY_IAM \
--parameter-overrides SomeVar=other_value The last line do "the magic" and allow you to override default value: --parameter-overrides SomeVar=other_value When the real function will be invoked: I think is important to remember that SAM templates are compatible with CloudFormation templates and all techniques/concepts could be used in SAM development. |
Thanks @wojtekk! It's really helpful! |
I get "unable to use container host config override file from '$HOME/.config/aws-sam-local/container-config.json': HOME env variable is not set" after get request "127.0.0.1:3000/ping" when use "sam local start-api --template sam.yaml". This is my log: I have followed the guide in README.md. Please help me. |
Local env variables work fine with
I can't figure out how to list the K/V pair the
I've setup env variables in the web UI lambda definition area but that doesn't seem to help. --parameter-overrides Optional. A string that contains AWS
CloudFormation parameter overrides encoded
as key=value pairs.For example, 'ParameterKe
y=KeyPairName,ParameterValue=MyKey Parameter
Key=InstanceType,ParameterValue=t1.micro' or
KeyPairName=MyKey InstanceType=t1.micro Can I get some help with how to list multiples K/V pairs in the |
I think one fo the option is, you can set the env variables and then use
the variable while executing the command. Or create a shell script wrapper
which can supply these value from env. Ideally once you are done with
development, these variable will be injected through ci/cd pipelines
Regards
Adnan
…On Tue, Aug 4, 2020 at 11:27 AM Nick Bordeau ***@***.***> wrote:
Has anyone found a good way to address this with quite a few different env
variables (say 10-20 or so)?
The two things I want to avoid are:
- I definitely do not want to commit any files containing my env
variables to a repo.
- I do not want to manually type them on every deploy. That seems like
a living nightmare.
The only ways I could think of would be adding them to the template.yaml
file or adding the script with the --parameter-overrides to package.json
file. Both would mean I have to commit my env variables to a repo.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1163 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACIH7AHZUTZWG5WEFCCIEYTR7AZITANCNFSM4HK5LDNA>
.
--
Regards,
*Adnan Yaqoob*
|
After reading through this thread, I think one main problem is the docs for --parameter-overrides are extremely confusing. 'ParameterKey=KeyPairName, ParameterValue=MyKey ParameterKey=InstanceType,ParameterValue=t1.micro'. Whereas it should be simply: ParameterKey1=Value1, ParameterKey2=Value2 |
Don't commit your
For more info, refer to the documentation.
Others can create their
Indeed. But you can maintain a deployment script for this. Something like this would work.
Hope this helps. |
I've got the same setup you just mentioned, but still no luck. Variables are showing as undefined on local-invoke. Is there something I am missing? Does my template file need something added as well? Thank you! |
Hi @bvisan, The AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Obtain access token from Github
Globals:
Function:
Timeout: 30 # Seconds
Parameters:
GITHUB_CLIENT_ID:
Type: String
Description: Github client id
GITHUB_CLIENT_SECRET:
Type: String
Description: Github client secret
Resources:
getAccessTokenFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: github-oauth/
Handler: app.getAccessToken
Runtime: nodejs12.x
Environment:
Variables:
GITHUB_CLIENT_ID: !Ref GITHUB_CLIENT_ID
GITHUB_CLIENT_SECRET: !Ref GITHUB_CLIENT_SECRET
Events:
getAccessToken:
Type: Api
Properties:
Path: /access_token
Method: get |
@m-sureshraj That did the trick 👍🏼 |
So why we can't set
and these key/values are plain text, no sensitive password, So I prefer to put in
and I can easily add other environments as staging, prod, etc. Update 1I made it. We can set
When Of course, you can add
Update 2I found an easy way to set
Both ways are working Update 3I made a repo to show case on how to manage the parameter with seperate files for different environments. Take a look, if you are interested. |
Right. I think the main reason against using the samconfig.toml is the secrets issue since you will most likely want to commit it to git. If you add to .gitignore than no problems, works great. Otherwise you could have secrets committed to your repo. Of course creating scripts with the parameter overrides in your package.json will also add secrets to your git repo as well. Dotenv and cross-varI prefer using a .env file then using doting and cross-var to create scripts in my package json.
Then you can have multiple .env files for each environment (.env.dev, .env.prod, .env.uat) and create a package json script for each (I use start for dev and That way I am using an industry standard .env file that can hold secrets and even though the package.json scripts can get quite large, I'm not editing them often so I can just use the yarn scriptname and I'm good to go. Then it's always good practice to add .env.example files as well that will be committed to git so anyone cloning the repo will at least know what environment variables are required. Hope that gives another possible way of organizing. |
How do you update the
We are using CodePipeline for deploying and using I have tried |
I believe the format of your parameter overrides is incorrect. The SAM documentation is super unclear on the syntax and I think it's actually wrong. If you look at my example above parameter overrides should just be key value pairs with no commas or quotes. For your example I would try:
|
Does not work either unfortunately. |
Quick clarification here and likely we need to update some docs.
|
The way we ended up doing it was using Parameter Store to store all variables and then you can update based on the stage. We migrated over to Serverless now because of a different use case but you should be able to do the same with SAM. Here is what it looks like:
|
@classforma You can achieve this by doing CodePipeline Stage -> CodeBuild -> |
For some reason having underscores in parameter values doesn't let me set parameter-overrides for that parameter, changing it to CamelCase did the trick for me. Can anyone confirm if that's the case?
|
Coming to this issue from Google, I'm still confused what the intended way to handle env vars is. I tried something like this (based on a few blogs):
I then want to be able to configure a different config (i.e. a set of env vars) for:
I would imagine this is an MVP setup for any project. We're also using Python if that makes a difference. Is there a simple way to do this? I thought the above would work, but when using build + invoke the environment variables are set to their names (e.g. btw @mudassirkhan19, it didn't work for me even with CamelCase. |
I think you are right. I'm revisiting this with the From this post, seems that the underscore is considered a non-alphanumeric value. Looks like only whats on the right side of the declaration matters, the Variable name in the template can have them. |
Reading through the comments, I believe this is solve. To summarize: SAM CLI will not set environment variables in the template. Instead for If I have a miss understanding of the issue, please create a new issue (closed issues are hard to track). |
One item has been resolved 🥳
The core consistency problem with
|
Another year passed, But here's a workaround. Assuming your project's deployment parameters (e.g. environment variables) are maintained in a Var1=Value1
VAr2=Value2 You can create an alias like this: alias samdeploy="sam deploy --parameter-overrides \"`tr -s '\n' ' ' < .env`\"" Not a perfect solution (e.g. easily breaks with an extra space), but better than nothing. Better yet, if you are working on a nodejs project like me, you can totally use In "scripts": {
"build": "sam build ...",
"deploy": "sam deploy --parameter-overrides \"`tr -s '\n' ' ' < .env`\"",
"invoke": "aws lambda invoke ...",
"logs": "sam logs ..."
} |
Building on @ubertao's comment above, I'm also using node /
NB: Change What a faff.... |
Description
When using AWS SAM for local development, I can introduce environment variables by setting them in the template with no value, and then defining them in my environment. However, when I go to deploy, the environment variables do not appear to be inserted by
sam package
orsam deploy
, and I get the following error on deploy:Where
SECRET_ACCESS_KEY
is one of my environment variables. I cannot find any documentation detailing how to deploy projects with environment variables, either by having them defined in my environment or providing them in an alternate config.I don't want to add the environment variables to my
template.yml
directly because this is stored in Git, and I don't want to edit them manually into thepackaged.yml
file each time between thepackage
anddeploy
steps as that's cumbersome.I haven't seen any steps in the documentation or similar issues, so I presume this is either an edge case bug or I am just missing something simple (in which case I might file this as a documentation bug) 😄
Steps to reproduce
The following config is a minimal excerpt from mine:
Observed result
When I run
sam start-api
withSECRET_ACCESS_KEY
defined, the lambda works as expected. When I attempt to deploy withsam package
andsam deploy
, I receive an error about undefined variables.Additional environment details (Ex: Windows, Mac, Amazon Linux etc)
sam --version
: 0.11The text was updated successfully, but these errors were encountered: