aws / aws-sam-cli

CLI tool to build, test, debug, and deploy Serverless applications using AWS SAM
https://aws.amazon.com/serverless/sam/
Apache License 2.0
6.5k stars 1.17k forks source link

Use the default profile for default values with custom config-env #2258

Open twasink opened 3 years ago

twasink commented 3 years ago

Describe your idea/feature/enhancement

I would like to be able to specify multiple env profiles in my samconfig.toml, and share common settings via the default profile.

As an example of what I would like to do:

version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
s3_bucket = <bucket>
s3_prefix = <prefix>
region = "us-east-1"
confirm_changeset = false
capabilities = "CAPABILITY_NAMED_IAM"

[env1]
[env1.deploy]
[env1.deploy.parameters]
stack_name = "Environment 1"
parameter_overrides = "Environment=\"Environment1\""

[env2]
[env2.deploy]
[env2.deploy.parameters]
stack_name = "Environment 2"
parameter_overrides = "Environment=\"Environment2\""

Currently, the selected profile needs to have all of the parameters provided, which will lead to extensive duplication with a large number of profiles.

Proposal

One possibility would be to process the config file twice. The first pass would load the defaults, with the second pass augmenting & overriding these defaults. The command line overrides would then follow as normal.

Additional Details

twasink commented 3 years ago

If combined with #2253 , this would also allow for the default profile to set common or default values for parameters, with environments only needing to override the ones that they specifically care about.

diegogurpegui commented 3 years ago

The simple approach would be to always take the "default" env as the default one, which is ok for me.

However, a more complex and versatile approach would be to have the ability to indicate the "parent" environment, from which take the defaults configuration.

However, at this point, the simple approach is more than enough I think.

ulrichwinter commented 2 years ago

I'm confused as this exact behaviour is already documented in the SAM Developer Guide - section "Precedence"

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html

Is this really still not implemented or did I miss something?

I'm currently facing this exact problem as shown in this sample SAM app: https://github.com/ulrichwinter/hello-sam-app

matsoob commented 2 years ago

Seconding @ulrichwinter

From the AWS documentation you linked it looks like this precedence should be implemented with default-ing behaviour.

(edit: upon closer reading, it's not. The environment itself is called default in the documentation's examples, it's not a default set of params. Oops!)

Yet when I try to use it: e.g. specifying stack_name only in default.global.parameters or default.deploy.parameters and attempting a deploy

[default.deploy.parameters]
stack_name = "test-stack"
confirm_changeset = true

[dev.deploy.parameters]
s3_bucket = "test"
region = "eu-west-1"

I get errors telling me:

Error: Missing option '--stack-name', 'sam deploy --guided' can be used to provide and save needed parameters for future deploys.

I am re-using quite a few parameters across envs, so it will make samconfig.toml much more readable if they can inherit the defaults.

(Note: I am using localstack & samlocal now. But this is coming from the underlying sam CLI itself).

carlnordenfelt commented 1 year ago

To avoid breaking existing implementations that are using the default keyword, the global keyword could be applied on the environment level to support the above use case:

[global.global.parameters] // Applies to all envs, all scripts
s3_bucket="..."

[global.deploy.parameters] // Applies to all envs, deploy only
stack_name ="..."

[myenv.deploy.parameters] // Applies to "myenv", deploy only
role_arn="..."

etc

davidjb commented 11 months ago

Just encountered this issue when trying to grok SAM's default behaviour based on the docs and config example at https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html#serverless-sam-cli-config-default. That example config doesn't work because prod doesn't inherit from default – given the brevity of the prod config and the name default, it suggests the apparent overriding of the watch parameter.

In any case, having this implemented would, as others have suggested, significantly simply configuration and remove duplication. In my testing YAML merge keys aren't supported in a samconfig.yaml (they would have solved the problem but were born deprecated in YAML so it was a long shot), but at least YAML aliases and anchors work. It isn't pretty, but it is possible to write:

default:
  build: &build
    parameters:
      cached: true
      parallel: true

  validate: &validate
    parameters:
      lint: true

  deploy:
    parameters:
      capabilities: &capabilities CAPABILITY_IAM
      fail_on_empty_changeset: &fail_on_empty_changeset false
      confirm_changeset: true

prod:
  build: *build
  validate: *validate

  deploy:
    parameters:
      capabilities: *capabilities
      fail_on_empty_changeset: *fail_on_empty_changeset
      confirm_changeset: false

Unfortunately, when any value changes in a given mapping, then you have to repeat (and/or alias) every key-value pair just to override a given value, as the deploy mapping shows above between default and prod environments.

calebworks commented 1 month ago

Any updates on this long-overdue functionality?