When deploying a simple function to AWS Lambda, I want to use a config.json
(external file) to fill some of the fields of the template.yaml
that I use to configure my AWS Lambda deployment. My directory structure is
my_project
my_package
my_source_code.py
template.yaml
samconfig.toml
config.json
Here samconfig.toml
contains some deployment parameters related to the environment from which I deploy, template.yaml
contains all the resource definitions (e.g. AWS::Serverless::Function
, AWS::Serverless::Api
, and AWS::ApiGateway::BasePathMapping
), and config.json
contains some package dependent configuration settings, like the package version number or the service name for this particular package.
What I want to do is to load the version number from config.json
and pass it as an environmental variable for the AWS::Serverless::Function
. But I cannot find a way for doing that. What I tried to do is this:
# template.yaml
Resources:
my_lambda:
Type: AWS::Serverless::Function
Properties:
Handler: ...
Environment:
Variables:
VERSION: ${file(config.json):version_number}
where
# config.json
{
"version_number": "1.0"
}
However that doesn’t work and when I load VERSION
from the environment, I get to see the string "${file(config.json):version_number}"
.
I cannot find any resource online describing how to do that (admitting that I find the AWS documentation hard to comprehend).
I did find documentation on Fn::GetParam
, but that needs an artifact name to load the json data from and I don’t know what that would be in my context.
NOTE: I use AWS CLI to deploy to AWS cloud using
sam build --use-container --manifest <path/to/requirements.txt>
andsam deploy --no-confirm-changeset
as build and deploy commands.
2
Answers
Starting from the thread that iagotb shared, I updated my approach to tackle this issue: work with AWS parameters in
template.yaml
.template.yaml
template.yaml
--parameter-overrides
flag ofsam deploy
As the tools that I deploy are deployed automatically via a Jenkins environment, and I don't have control over that environment and what libraries are installed there, the suggested solutions in the linked thread didn't directly work for me. In the end I followed these steps to add the parameter overrides to my deployment:
build.py
file that is called during Jenkins deployment.samparams
frombuild.py
.samparams
into variable during Jenkins deploymentsam deploy
Below I will explain in more detail what I did.
Original desired solution
What I originally wanted, was to directly plug data from a json file in my AWS template and format that data correctly in the template, for example by doing something like:
However, this is simply not possible.
Creating
.samparams
During the Jenkins deployment, I automatically create
.samparams
frombuild.py
. In this process, I can fully control all information sources (a json, another config file, or just hard-coded inbuild.py
) to collect the necessary data to create the parameter overrides.Next I create the file
.samparams
according to the following formatting rules:parameter_name=parameter_value
For example, let's say we have three parameters we want to override:
.samparams
file contains the following line:Passing
.samparams
tosam deploy
The Jenkins deployment is controlled via a Groovy file. In the deployment stage I execute the following two commands:
And with this, the parameter overrides are correctly passed to
sam deploy
.Alternative: update
samconfig.toml
Prior to above solution, I explored the possibility to dynamically update an existing
samconfig.toml
file where other AWS configuration settings are stored. While this is more powerful, as you can define parameter overrides for each AWS command and environment, I abandoned that approach due to the complexity of working with the parameter overrides field and the (limited) capabilities of toml parsers in Python.samconfig.toml
the parameter overrides should be in a similar format as above.samparams
format. However the parameter values should be surrounded by double quotes and the double quoted should be escaped:Given all the above and that for my use case I only needed to supply parameter overrides to
sam deploy
, I abandoned this approach and went for the.samparams
file approach instead.There are some alternatives to pass parameters from file. All of them use sam cli parameter
--parameter-overrides
You can use jq or cat to read from file and pass parameters from file.
Overhere you find an example with jq:
https://github.com/aws/aws-sam-cli/issues/2054#issuecomment-762550286