【问题标题】:Serverless Framework - Choose between static iam resource ARN and reference from Resources section无服务器框架 - 在静态 iam 资源 ARN 和资源部分的参考之间进行选择
【发布时间】: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


【解决方案1】:

问题的关键在于意识到 SLS,正如人们常说的,主要是 CloudFormation (CFN) 的包装器。比我想象的要多。 CFN 脚本在 CFN 部署期间执行,而不是 SLS 解释。

因此,DynDB SLS 资源和自定义表达式之间的任何关联都是纯语法的。在我们的 IAM 资源中插入 "Fn::GetAtt": [ TunesTable, Arn ] 不是在知道 SLS 中 TuneTable 的上下文中,它不会计算和替换,它字面上将字符串粘贴到 CFN 模板中,成为以后无论好坏都会被处决。

知道将问题缩小到“CFN 中的哪些表达式可以工作并且 SLS 可以生成它们”这导致了来自 https://www.npmjs.com/package/serverless-plugin-ifelse 的插件解决方案。我希望该功能包含在未来的基本 SLS 版本中(但语法更简单)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    • 2015-02-09
    相关资源
    最近更新 更多