【发布时间】:2022-02-19 03:41:47
【问题描述】:
我正在使用无服务器框架来部署 lambda,并且可以选择 lambda 访问的 dynamo db 表。
在开发阶段,sls 将表格创建为完整的资源(因此我引用了表格)
或者,在生产阶段 sls 不会创建表,但自定义变量知道预创建表的 ARN
在制定 lambda 的 iam 策略文档的 Resource 子句时遇到问题,可能是因为我不了解 Cloudformation IF 语句和 sls 动态变量之间允许的混合。据我所知(缩写):
provider:
... unrelated stuff
iam:
role:
statements:
- Effect: 'Allow'
Action:
- dynamodb:DescribeTable
- ..more DynDB permissions
Resource:
- !If [ ${self:custom.slsMadeTheTable}, Fn::GetAtt:[MyDynDBTable, Arn], ${self:custom.staticArnOfPrecreatedTable} ]
地点:
${self:custom.slsMadeTheTable} 指的是来自自定义变量的布尔值字符串,它定义了 sls 是否创建了表(所以获取它的引用并在资源中使用它)或不(所以使用已知的静态 Arn)
${self:custom.staticArnOfPrecreatedTable} 是一个自定义变量,其值是预先创建的 DDB 表的文字 ARN 字符串
在这个特定配置中,我收到一个语法错误,提示我错误地将 Cloudformation if 与 sls 表达式组合在一起。
Cannot parse "serverless.yml": missed comma between flow collection entries in "../serverless.yml" (64:22)
64 | - !If [ ${self:custom.slsMadeTheTable}, Fn::Ge ...
---------------------------^
尝试了许多其他变体,没有一个成功。
寻求帮助制定策略, 根据决定变量(当然与阶段相关)处理创建的 DDB 表或表的预创建 ARN
--- 另一种失败的方法---
资源很乐意接受自定义变量中的 ARN 字符串,例如
Resource: ${self:custom.productionTableArn}
所以你会认为一个简单的默认表达式就可以解决问题,类似于
Resource:
${self:custom.devTableArn,
self:custom.productionTableArn}
其中 self:custom.devTableArn 包含创建的 DDB 表的内容。
但是对 sls ddb 表 arn:"Fn::GetAtt": [ TunesTable, Arn ] 的引用作为资源的直接条目工作得非常好,但在设置为 self:custom.devTableArn 的值时会失败:
devTableArn: "Fn::GetAtt": [ TunesTable, Arn ]
出现错误:
Cannot parse "serverless.yml": bad indentation of a mapping entry in "/home/rpc/tune-library-tunes/serverless.yml" (24:28)
24 | devTableArn: "Fn::GetAtt": [ TunesTable, Arn ]
【问题讨论】:
-
你在哪里见过这样的结构,在 sls 中有
IF? -
@Marcin - 在serverless.com/framework/docs/providers/aws/guide/iam#at-glance 它说:“与 provider.iam.role.statements 一起,托管策略也可以添加到此服务范围的角色中,在 provider.iam.role 中定义托管策略。 managedPolicies。这些也将被合并到生成的 IAM 角色中因此您也可以在此处使用 Join、Ref 或任何其他 CloudFormation 方法或功能。”
标签: if-statement amazon-cloudformation serverless-framework