[RFC] Stage-specific configuration
See original GitHub issueUse case description
Some configuration values in serverless.yml need to be dynamic, for different reasons:
- Secrets: to avoid exposing a sensitive value (like a credential)
- Stage-specific configuration: to change the configuration based on the stage (dev/prod/etc.)
- Other use cases are intentionally ignored in this initiative because they are less common (for example feature flags, etc.)
There are solutions for secrets (like Serverless Dashboard parameters, SSM, Secrets Manager…)
But for stage-specific configuration, the current and widespread practice is to use the “custom” section in serverless.yml, with nested variables:
provider:
environment:
APP_DOMAIN: ${self:custom.stages.${sls:stage}.domain}
custom:
stages:
staging:
domain: preview.myapp.com
prod:
domain: myapp.com
This approach works but is limited and complex. Let’s make stage-specific configuration simpler.
Proposed solution
Introduce a new params
section in serverless.yml
:
params:
prod:
domain: myapp.com
staging:
domain: preview.myapp.com
The section contains a list of param: value
listed under stage names.
Every parameter defined in that section can be used with the ${param:xxx}
variable:
provider:
environment:
APP_DOMAIN: ${param:domain}
params:
prod:
domain: myapp.com
staging:
domain: preview.myapp.com
The variable resolves to the value that matches the current stage:
$ serverless deploy --stage=prod
# The domain will be "myapp.com"
$ serverless deploy --stage=staging
# The domain will be "preview.myapp.com"
Defaults
It is possible to define default values via the default
keyword:
provider:
environment:
APP_DOMAIN: ${param:domain}
params:
default:
domain: ${sls:stage}.myapp.com
prod:
domain: myapp.com
Serverless Dashboard parameters
${param:xxx}
is a variable that already exists today: it resolves parameters from Serverless Dashboard, our SaaS monitoring product.
The ${param:xxx}
variable will be expanded to resolve parameters:
- from
serverless.yml
- and from Serverless Dashboard
Note that using Serverless Dashboard is completely optional. Everything described here works locally without Serverless Dashboard.
Our goal is to provide a single concept that solves “stage-specific configuration” in a simple way. And for those that want to manage secret values with the same ${param:xxx}
variable, they can look into Serverless Dashboard.
Resolution priority
Here is the priority to resolve a parameter:
- First, look in
params.<stage>
in serverless.yml - If not found, then look in
params.default
- If not found, throw an error
For projects that use Serverless Dashboard, here is the priority to resolve a parameter:
- First, look in
params.<stage>
in serverless.yml - If not found, then look in the instance’s parameters in Serverless Dashboard
- If not found, then look in
params.default
- If not found, then look in the service’s parameters in Serverless Dashboard
- If not found, throw an error
If you have any feedback please post it in this issue ❤️
Issue Analytics
- State:
- Created 2 years ago
- Reactions:20
- Comments:5 (3 by maintainers)
Closing since v3 has been released!
I am concerned that over the longevity of the project having the section named
params
might cause future issues where it might make sense for something else; since this is essentially stage variables, to me the naming convention makes more sense as:stageParams
orstageVars
. Going too general IMO leads to a future state where that name makes more sense for something else later on and thus requires a BC break or naming the field differently.Overall I do this often with the custom fields and I this would certainly be a helpful trick for me across the board; especially with the default.