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.51k stars 1.17k forks source link

Support immediate validation of parameter values on entry #3244

Open specious opened 3 years ago

specious commented 3 years ago

It would be valuable to have immediate parameter value validation upon entry.

For example, a parameter may be defined in template.yml (e.g. as per the official documentation for RDS password constraints):

Parameters:
  DBAdminPassword:
    Description: Database admin password
    Type: String
    MinLength: 8
    MaxLength: 128
    AllowedPattern: "[^\\s@\"\\/]*"
    ConstraintDescription: 'The password can include any printable ASCII character except "/", """, or "@".'

It would then be useful to have the value validated against both the implicit constraints and explicitly stated constraints upon entry:

$ sam deploy -g

Configuring SAM deploy
======================

        Looking for config file [samconfig.toml] :  Found
        Reading default arguments  :  Success

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [myapp-backend]:
        AWS Region [us-east-1]:
        Parameter DBInstanceClass [db.t2.micro]:
        Parameter DBPostgresVersion [12.7]:
        Parameter DBAllocatedStorage [5]:
        Parameter DBName [mydb]:
        Parameter DBAdminUser [admin]:
        Parameter DBAdminPassword [] (The password can include any printable ASCII character except "/", """, or "@".): ZCd)6Qyt~T^<"/\!3i,2L:&,&=*NzU#[

        Invalid parameter value.

        Parameter DBAdminPassword [] (The password can include any printable ASCII character except "/", """, or "@".): 

The current behavior is to let the value pass until the deployment initiation phase, at which point the deployment attempt doesn't pass validation:

$ sam deploy -g

Configuring SAM deploy
======================

        Looking for config file [samconfig.toml] :  Found
        Reading default arguments  :  Success

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [myapp-backend]:
        AWS Region [us-east-1]:
        Parameter DBInstanceClass [db.t2.micro]:
        Parameter DBPostgresVersion [12.7]:
        Parameter DBAllocatedStorage [5]:
        Parameter DBName [mydb]:
        Parameter DBAdminUser [admin]:
        Parameter DBAdminPassword []: ZCd)6Qyt~T^<"/\!3i,2L:&,&=*NzU#[
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [y/N]:
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]:
        Save arguments to configuration file [Y/n]:
        SAM configuration file [samconfig.toml]:
        SAM configuration environment [default]:

        Looking for resources needed for deployment: Found!

                Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-hw20z48xixco
                A different default S3 bucket can be set in samconfig.toml

        Saved arguments to config file
        Running 'sam deploy' for future deployments will use the parameters saved above.
        The above parameters can be changed by modifying samconfig.toml
        Learn more about samconfig.toml syntax at
        https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config
.html

Uploading to myapp-backend/c26270266b2546e105a4b9588ceed669  248067 / 248067  (100.00%)
Uploading to myapp-backend/611706200045c2015244856d552824b0  620 / 620  (100.00%)
Uploading to myapp-backend/99beaacc5f7faa76fe3d48e90ce9ab52  870 / 870  (100.00%)
Uploading to myapp-backend/fd4d6f52df1662f7622eb7a73ba31c77  630 / 630  (100.00%)

        Deploying with following values
        ===============================
        Stack name                   : myapp-backend
        Region                       : us-east-1
        Confirm changeset            : False
        Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-hw20z48xixco
        Capabilities                 : ["CAPABILITY_IAM"]
        Parameter overrides          : {"DBInstanceClass": "db.t2.micro", "DBPostgresVersion": "12.7", "DBAllocatedStorage": "5", "DBName": "mydb", "DBAdminUser": "admin", "DBAdminPassword": "ZCd)6Qyt~T^<\"/\\!3i,2L:&,&=*NzU#["}
        Signing Profiles             : {}

Initiating deployment
=====================
Uploading to myapp-backend/26a34904b77c7349a000bd41c640542f.template  7825 / 7825  (100.00%)
Error: Failed to create changeset for the stack: myapp-backend, An error occurred (ValidationError) when calling the CreateChangeSet operation: Parameter DBAdminPassword failed to satisfy constraint: The password can include any printable ASCII character except "/", """, or "@".

This is a noticeable inconvenience.

aahung commented 3 years ago

Thanks for the suggestion, we will look into it

davidjb commented 12 months ago

Having this validation occur before a deployment is attempted would help avoid a failed deployment and a corresponding rollback. In my testing, if I set a parameter up like so:

Parameters:
  MyParam:
    Type: String
    MinLength: 1
    ConstraintDescription: is a required parameter

then running a sam deploy with this parameter set as an empty string creates a changeset successfully and prompts for deployment. Upon starting to deploy, CloudFormation begins but then fails very quickly, needing to rollback the failed deployment:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ResourceStatus                              ResourceType                                LogicalResourceId                           ResourceStatusReason
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS                          AWS::CloudFormation::Stack                  MyStack                                     -
CREATE_FAILED                               AWS::CloudFormation::Stack                  MyStack                                     Parameter MyParam failed to
                                                                                                                                    satisfy constraint: is a required
                                                                                                                                    parameter
UPDATE_ROLLBACK_IN_PROGRESS                 AWS::CloudFormation::Stack                  MyStack                                     The following resource(s) failed to
                                                                                                                                    create: [MyStack].
UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGR   AWS::CloudFormation::Stack                  MyStack                                     -
ESS
DELETE_COMPLETE                             AWS::CloudFormation::Stack                  MyStack                                     -
UPDATE_ROLLBACK_COMPLETE                    AWS::CloudFormation::Stack                  MyStack                                     -
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Edit: I've encountered this issue again in a slightly different context - expecting that AllowedValues would be validated at SAM build time. In my case, builds are allowed to proceed - and fail - for resources with invalid parameter values since any value is permitted at this time.