简体   繁体   中英

AWS: cloudformation CommaDelimitedList and manual list not matching

I'm trying to create a cloudformation template that has default values, and I'm running a few !Sub functions to replace imported parameters into the template. However, I am passing a list to a nodejs Lambda function that I need to !Sub before sending it.

The code that I'm writing:

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: Creating Athena database and tables

Parameters:
  S3DataLocations:
    Type: CommaDelimitedList
    Description: The S3 locations where the logs are read from (Specify 'Use,Default' to inherit defaults)
    Default: Use,Default

Conditions:
  CustomS3DataLocations: !Equals ['Use,Default', !Join [",", !Ref S3DataLocations]]

Resources:
  # Custom resource for running CreateTableFunction, to create databases
  CreateLogTable:
    Type: Custom::CreateLogTable
    Properties:
      ServiceToken: !GetAtt [CreateLogTableFunction, Arn]
      S3DataLocations:
        Fn::If:
          - CustomS3DataLocations
          - !Split
            - ","
            - !Sub
              - s3://${LoggingBucket}/data/ApplicationLogs1/,
                s3://${LoggingBucket}/data/ApplicationLogs2/,
                s3://${LoggingBucket}/data/ApplicationLogs3/
              - { LoggingBucket: !ImportValue Parent-LoggingBucket}
          - !Ref S3DataLocations

If I pass these as a literal external DataTypes parameter s3://logbucket/data/ApplicationLogs1/,s3://logbucket/data/ApplicationLogs2/,s3://logbucket/data/ApplicationLogs3/ it works fine and translates to ["s3://logbucket/data/ApplicationLogs1/","s3://logbucket/data/ApplicationLogs2/","s3://logbucket/data/ApplicationLogs3/"] and is interpreted by the Lambda without issue. The parameter gets parsed through the CommaDelimitedList type and is passed to the Lambda without issue.

The issue arises in that I am trying to create a manual default, so I need to !Sub a list, as a string, then !Split to be passed as an actual list to the Custom Lambda. This doesn't seem to be working every way I try it and I cannot figure why.

I've been inspecting the success (manual param) and failure (defaults, without manual param) and I cant see a big difference. The event of the lambda shows, when working:

{
    "RequestType": "Create",
    "ServiceToken": "hidden",
    "ResponseURL": "hidden",
    "StackId": "hidden",
    "RequestId": "hidden",
    "LogicalResourceId": "CreateLogTable",
    "ResourceType": "Custom::CreateLogTable",
    "ResourceProperties": {
        "S3DataLocations": [
            "s3://loggingbucket/data/ApplicationLogs/",
            "s3://loggingbucket/data/ApplicationLogs/",
            "s3://loggingbucket/data/ApplicationLogs/",
            "s3://loggingbucket/data/ApplicationLogs/"
        ]
    }
}

And when NOT working:

...
{
    "RequestType": "Create",
    "ServiceToken": "hidden",
    "ResponseURL": "hidden",
    "StackId": "hidden",
    "RequestId": "hidden",
    "LogicalResourceId": "CreateLogTable",
    "ResourceType": "Custom::CreateLogTable",
    "ResourceProperties": {
        "S3DataLocations": [
            "s3://logging/data/ApplicationLogs/",
            " s3://loggingbucket/data/ApplicationLogs/",
            " s3://loggingbucket/data/ApplicationLogs/",
            " s3://loggingbucket/data/ApplicationLogs/"
        ]
    }
}

I'm a little stuck here, I think there might be some Type mismatch but I cant tell the difference between the manual and param.

Does anyone have any idea?

You can break your string into multiple line while preventing the change of \n into space using quotation and slash combo.

To verify that, I used the following surrogate template for your situation:


Resources:

  MyBucket:
    Type: AWS::S3::Bucket
    Properties: {}

Outputs:
  Test1:
    Value: !Sub
          - s3://${LoggingBucket}/data/ApplicationLogs1/,
            s3://${LoggingBucket}/data/ApplicationLogs2/,
            s3://${LoggingBucket}/data/ApplicationLogs3/
          - { LoggingBucket: "Parent-LoggingBucket"}

  Test2:
    Value: !Sub
          - "s3://${LoggingBucket}/data/ApplicationLogs1/,\
            s3://${LoggingBucket}/data/ApplicationLogs2/,\
            s3://${LoggingBucket}/data/ApplicationLogs3/"
          - { LoggingBucket: "Parent-LoggingBucket"}   

The Test1 produces string with spaces as in your question:

s3://Parent-LoggingBucket/data/ApplicationLogs1/, s3://Parent-LoggingBucket/data/ApplicationLogs2/, s3://Parent-LoggingBucket/data/ApplicationLogs3/

In contrast, Test2 does not have space:

s3://Parent-LoggingBucket/data/ApplicationLogs1/,s3://Parent-LoggingBucket/data/ApplicationLogs2/,s3://Parent-LoggingBucket/data/ApplicationLogs3/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM