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 堆栈中
CloudFormation - 将标签应用于其他 AWS 资源
AWS CloudFormation:Cognito LambdaTrigger CustomEmailSender - 属性“AWS CloudFormation 目前不支持。”和 CDK 的使用