Reputation: 1543
I have Serverless Framework function for AWS Lambda. I have secrets in AWS Secrets Manager (SSM) Parameter Store and other environment variables in local .yml files, for separate deployments (dev, stg, prod).
How can I use environment variables from both file and SSM?
Only secrets work:
functions:
kinesisEvents:
handler: kinesis_events_processing.lambda_handler
name: kinesis-events-${self:provider.stage}
package: {}
maximumRetryAttempts: 2
events:
- stream:
type: kinesis
... # omitted a few things
environment:
DB_PASSWORD: ${ssm:/${self:provider.stage}/db/db_password}
API_KEY: ${ssm:/${self:provider.stage}/api/internal_api_key}
And only file also works:
functions:
kinesisEvents:
... # as above
environment:
${file(${self:provider.stage}.yml):}
But how can I combine those, so I have all those variables set as env vars in final deployment? I tried this, but it does not work and throws error during deploy:
functions:
kinesisEvents:
... # as above
environment:
DB_PASSWORD: ${ssm:/${self:provider.stage}/db/db_password}
API_KEY: ${ssm:/${self:provider.stage}/api/internal_api_key}
${file(${self:provider.stage}.yml):}
Upvotes: 1
Views: 1919
Reputation: 2083
I tried @qalis's answer but getting (in BitBucket build pipeline): "Cannot parse "serverless.yml": cannot merge mappings; the provided source object is unacceptable in "/opt/atlassian/pipelines/agent/build/serverless.yml" (12:5)"
service: {project}-14-dkr
env_vars: &env_vars
${file(./config/serverless/config.${self:provider.stage}.json):}
provider:
name: aws
stage: ${opt:stage, 'local'}
region: eu-west-1
environment:
<<: *env_vars
RUNTIME_AWS_ACCESS_KEY_ID: ${param:runtimeAwsAccessKeyId}
RUNTIME_AWS_SECRET_ACCESS_KEY: ${param:runtimeAwsSecretAccessKey}
Upvotes: 0
Reputation: 1543
I found answers here, here and here. Basically, Serverless Framework has no particular support for this feature. However, it supports extended YAML syntax, which has anchor and dictionary merging capabilities.
So first I unpack the env vars from YAML config file, at the top of the file, and anchor it with &env_vars
(like a variable for referencing, but in YAML):
env_vars: &env_vars
${file(${self:provider.stage}.yml):}
functions:
...
And then I use it, unpacking this dictionary:
environment:
<<: *env_vars
DB_PASSWORD: ${ssm:/${self:provider.stage}/db/db_password}
API_KEY: ${ssm:/${self:provider.stage}/api/internal_api_key}
Upvotes: 2