Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to escape variables format #8116

Closed
0ptional opened this issue Aug 21, 2020 · 8 comments
Closed

Allow to escape variables format #8116

0ptional opened this issue Aug 21, 2020 · 8 comments

Comments

@0ptional
Copy link

0ptional commented Aug 21, 2020

Source of a reported issue was that "${StepFunctionArn}" in CF template was attempted to be resolved by our variable resolver, when it was unexpected.

Proposed solution:

We probably should support escaping such case, so "${StepFunctionArn}" will not invoke variable resolver but just strip leading slash.


Original report:

Using custom variableSyntax, serverless can't resolve variable value if it contains another variable:

serverless.yml
service: test

provider:
  name: aws
  stage: dev
  variableSyntax: "\\${((env|self|opt|file|cf|s3)[:\\(][ :a-zA-Z0-9._,\\-\\/\\(\\)]*?)}"
  environment:
    VAR: ${self:custom.bucketName}
  
custom:
  bucketName: mytest-bucket-${self:provider.stage}
sls package .serverless/serverless-stage.json

Custom variable bucketName gets correctly resolved to mytest-bucket-dev. But environment variable in provider gets resolved to ${deep:0}. See serverless-stage.json:

{
  "service": {
    "service": "test",
    "serviceObject": {
      "name": "test"
    },
    "provider": {
      "stage": "dev",
      "variableSyntax": "\\${((env|self|opt|file|cf|s3)[:\\(][ :a-zA-Z0-9._,\\-\\/\\(\\)]*?)}",
      "name": "aws",
      "environment": {
        "VAR": "${deep:0}"
      },
      "region": "us-east-1",
      "versionFunctions": true,
      "compiledCloudFormationTemplate": {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Description": "The AWS CloudFormation template for this Serverless application",
        "Resources": {
          "ServerlessDeploymentBucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
              "BucketEncryption": {
                "ServerSideEncryptionConfiguration": [
                  {
                    "ServerSideEncryptionByDefault": {
                      "SSEAlgorithm": "AES256"
                    }
                  }
                ]
              }
            }
          },
          "ServerlessDeploymentBucketPolicy": {
            "Type": "AWS::S3::BucketPolicy",
            "Properties": {
              "Bucket": {
                "Ref": "ServerlessDeploymentBucket"
              },
              "PolicyDocument": {
                "Statement": [
                  {
                    "Action": "s3:*",
                    "Effect": "Deny",
                    "Principal": "*",
                    "Resource": [
                      {
                        "Fn::Join": [
                          "",
                          [
                            "arn:",
                            {
                              "Ref": "AWS::Partition"
                            },
                            ":s3:::",
                            {
                              "Ref": "ServerlessDeploymentBucket"
                            },
                            "/*"
                          ]
                        ]
                      }
                    ],
                    "Condition": {
                      "Bool": {
                        "aws:SecureTransport": false
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "Outputs": {
          "ServerlessDeploymentBucketName": {
            "Value": {
              "Ref": "ServerlessDeploymentBucket"
            }
          }
        }
      },
      "coreCloudFormationTemplate": {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Description": "The AWS CloudFormation template for this Serverless application",
        "Resources": {
          "ServerlessDeploymentBucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
              "BucketEncryption": {
                "ServerSideEncryptionConfiguration": [
                  {
                    "ServerSideEncryptionByDefault": {
                      "SSEAlgorithm": "AES256"
                    }
                  }
                ]
              }
            }
          },
          "ServerlessDeploymentBucketPolicy": {
            "Type": "AWS::S3::BucketPolicy",
            "Properties": {
              "Bucket": {
                "Ref": "ServerlessDeploymentBucket"
              },
              "PolicyDocument": {
                "Statement": [
                  {
                    "Action": "s3:*",
                    "Effect": "Deny",
                    "Principal": "*",
                    "Resource": [
                      {
                        "Fn::Join": [
                          "",
                          [
                            "arn:",
                            {
                              "Ref": "AWS::Partition"
                            },
                            ":s3:::",
                            {
                              "Ref": "ServerlessDeploymentBucket"
                            },
                            "/*"
                          ]
                        ]
                      }
                    ],
                    "Condition": {
                      "Bool": {
                        "aws:SecureTransport": false
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "Outputs": {
          "ServerlessDeploymentBucketName": {
            "Value": {
              "Ref": "ServerlessDeploymentBucket"
            }
          }
        }
      }
    },
    "custom": {
      "bucketName": "mytest-bucket-dev"
    },
    "pluginsData": {},
    "functions": {},
    "configValidationMode": "warn",
    "serviceFilename": "serverless.yml",
    "layers": {},
    "initialServerlessConfig": {
      "service": {
        "$ref": "$[\"service\"][\"serviceObject\"]"
      },
      "provider": {
        "$ref": "$[\"service\"][\"provider\"]"
      },
      "custom": {
        "$ref": "$[\"service\"][\"custom\"]"
      },
      "functions": {
        "$ref": "$[\"service\"][\"functions\"]"
      },
      "package": {
        "artifactDirectoryName": "serverless/test/dev/1598020300313-2020-08-21T14:31:40.313Z"
      },
      "layers": {
        "$ref": "$[\"service\"][\"layers\"]"
      },
      "configValidationMode": "warn"
    },
    "isDashboardMonitoringPreconfigured": false
  },
  "package": {
    "artifactDirectoryName": "serverless/test/dev/1598020300313-2020-08-21T14:31:40.313Z",
    "artifact": ""
  }
}

Installed version

Framework Core: 1.79.0
Plugin: 3.7.1
SDK: 2.3.1
Components: 2.34.6
@medikoo
Copy link
Contributor

medikoo commented Aug 21, 2020

@0ptional thanks for report. Can you respect all bug template remarks, and point at which exactly point you observe ENV_VAR1 not resolved as expected?

@0ptional
Copy link
Author

@medikoo Sorry! I updated the report with full serverless.yml and output for serverless-stage.json file.

@0ptional 0ptional removed their assignment Aug 21, 2020
@medikoo
Copy link
Contributor

medikoo commented Aug 21, 2020

@optional thanks for update. It's caused by variableSyntax configuration in your config. Is there any specific reason you override that?

@medikoo medikoo assigned medikoo and 0ptional and unassigned medikoo Aug 21, 2020
@0ptional
Copy link
Author

@medikoo Yes, I need it because it otherwise conflicts with Variable Syntax of CloudFormation:

Type: AWS::CloudWatch::Dashboard
Properties:
    DashboardName: ${self:custom.dashboardName}
    DashboardBody: !Sub 
        - |
            {
                "widgets": [
                    {
                        "type": "metric",
                        "properties": {
                            "view": "singleValue",
                            "metrics": [
                                [ "AWS/States", "ExecutionTime", "StateMachineArn", "${StepFunctionArn}" ]
                            ],
                            "region": "eu-central-1",
                        }
                    },
        - StepFunctionArn: !Ref TestStepFunctionsStateMachine

If I run it without setting variableSyntax, I get Invalid variable reference syntax for variable StepFunctionArn. Not sure how else I could get that working without modifying variableSyntax.

@0ptional 0ptional removed their assignment Aug 21, 2020
@medikoo
Copy link
Contributor

medikoo commented Aug 21, 2020

Problem is that internally variable resolution engine uses temporary deep variable scope, and as you do not recognize it in your regex, it is not resolved. If you add it to list of recognized scopes (in regex) it'll resolve as expected.

Anyway it feels to me that real problem is collision of our syntax with format you use in CloudFormation template. I wonder how to tackle that in best way.

We probably should support escaping such case, so "\${StepFunctionArn}" will not invoke variable resolver but just strip leading slash.

Let me keep this issue open as reference to that specific problem

@medikoo medikoo changed the title With custom variableSyntax serverless can't resolve variable value if it contains another variable Allow to escape variables format Aug 21, 2020
@medikoo medikoo added bug/design Functionality design flaw cat/variable needs feedback and removed question labels Aug 21, 2020
@0ptional
Copy link
Author

@medikoo Ah, perfect. That solved my problem. Thank you!

variableSyntax: "\\${((env|self|opt|file|cf|s3|deep)[:\\(][ :a-zA-Z0-9._,\\-\\/\\(\\)]*?)}"

@medikoo
Copy link
Contributor

medikoo commented Sep 23, 2020

Closing in favor of #3184, which is about same thing and has already involved discussion

@medikoo
Copy link
Contributor

medikoo commented Sep 23, 2020

Duplicate of #3184

@medikoo medikoo marked this as a duplicate of #3184 Sep 23, 2020
@medikoo medikoo closed this as completed Sep 23, 2020
@medikoo medikoo added duplicate and removed bug/design Functionality design flaw cat/variable needs feedback labels Sep 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants