AWS:cloudformation CommaDelimitedList 和手动列表不匹配

Posted

技术标签:

【中文标题】AWS:cloudformation CommaDelimitedList 和手动列表不匹配【英文标题】:AWS: cloudformation CommaDelimitedList and manual list not matching 【发布时间】:2020-12-20 14:30:21 【问题描述】:

我正在尝试创建一个具有默认值的 cloudformation 模板,并且我正在运行一些 !Sub 函数来将导入的参数替换到模板中。 但是,我正在将一个列表传递给一个 nodejs Lambda 函数,我需要在发送它之前将其传递给 !Sub

我正在编写的代码:

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

如果我将这些作为文字外部 DataTypes 参数 s3://logbucket/data/ApplicationLogs1/,s3://logbucket/data/ApplicationLogs2/,s3://logbucket/data/ApplicationLogs3/ 传递,它可以正常工作并转换为 ["s3://logbucket/data/ApplicationLogs1/","s3://logbucket/data/ApplicationLogs2/","s3://logbucket/data/ApplicationLogs3/"] 并由 Lambda 毫无问题地解释。 该参数通过CommaDelimitedList 类型进行解析,并毫无问题地传递给 Lambda。

问题出现在我尝试创建手动默认值时,因此我需要将!Sub 列表作为字符串,然后将!Split 作为实际列表传递给自定义 Lambda。这似乎并不是我尝试的每一种方式都有效,我不知道为什么。

我一直在检查成功(手动参数)和失败(默认,没有手动参数),我看不出有什么大的区别。 工作时显示的 lambda 事件:


    "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/"
        ]
    

当不工作时:

...

    "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/"
        ]
    

我有点卡在这里,我认为可能有一些类型不匹配,但我无法区分手册和参数之间的区别。

有人知道吗?

【问题讨论】:

您是否已将您的`s3://$LoggingBucket/data/ApplicationLogs1/,` 放在不同的行中?行尾更改为空格,因此您可以在 lambda 字符串的前面获得这个额外的空间。 理想情况下,为了便于阅读,我想找到一种方法使它们不在同一行。示例较短,但实际上有大约十几个 S3 URL。 【参考方案1】:

您可以使用引号和斜杠组合将字符串分成多行,同时防止将\n 更改为空格。

为了验证这一点,我针对您的情况使用了以下代理模板:


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"   

Test1 生成带有空格的字符串,如您的问题所示:

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

相比之下,Test2 没有空格:

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

【讨论】:

感谢您的回复,但是当我使用Test2 方法时,我仍然会得到空格。我一直在尝试几种不同的方法来对列表进行字符串化,它似乎总是输出相同的结果(带空格)。可能跟下面的!Split函数有关系,不过我一直在试验。 嗨@Marcin,进一步测试并回顾您的答案,看起来在使用您的Test2 示例时,我在每行末尾省略了`\`。添加斜线换行符解决了这个问题。谢谢!

以上是关于AWS:cloudformation CommaDelimitedList 和手动列表不匹配的主要内容,如果未能解决你的问题,请参考以下文章

AWS 批处理 cloudformation - “CannotPullContainerError”

将现有 AWS 资源整合到 CloudFormation 堆栈中

AWS Cloudformation的相关概念

CloudFormation - 将标签应用于其他 AWS 资源

AWS CloudFormation:Cognito LambdaTrigger CustomEmailSender - 属性“AWS CloudFormation 目前不支持。”和 CDK 的使用

AWS学习笔记--利用CloudFormation管理AWS资源