AWS Cloud Formation !Sub & !Ref AWS::Serverless::Function Policies 中的函数

Posted

技术标签:

【中文标题】AWS Cloud Formation !Sub & !Ref AWS::Serverless::Function Policies 中的函数【英文标题】:AWS Cloud Formation !Sub & !Ref functions inside AWS::Serverless::Function Policies 【发布时间】:2018-01-24 13:55:00 【问题描述】:

我一直在我的 CloudFormation Yaml 模板中使用 !Sub 函数。当它用作对象属性值时,它适用于我

Object:
  Property1: !Sub some-value-with-a-$variable-in-it

变量的值按预期被替换。

但是,我不知道如何在字符串数组的元素中使用 !Sub 函数

Array:
  - !Sub some-value-with-a-$variable-in-it

该数组元素会被忽略。

我在创建 AWS::Serverless::Function 类型资源的 SAM 模板的上下文中尝试此操作。 Policies 属性可以接受一个字符串数组:

lambda:
  Type: AWS::Serverless::Function
  Properties:
    CodeUri: api
    FunctionName: !Sub api-$MyStageName
    Handler: Lambda:Api.Function::HandleAsync
    Runtime: dotnetcore1.0
    Policies: 
    - AWSLambdaBasicExecutionRole
    - !Sub arn:aws:iam::$AWS::AccountId:policy/some-policy
    - arn:aws:iam::123456789:policy/another-policy

!Sub 函数在此示例中的 FunctionName 属性中起作用。但我最终只获得了 2 个附加到我生成的角色的策略 - AWSLambdaBasicExecutionRolearn:aws:iam::123456789:policy/another-policy。包含!Sub 函数的那个​​会被忽略。

我尝试了将函数放在新行上的选项:

Array:
  - 
    !Sub some value with a $variable in it

谁能帮忙?

更新

@Tom Melo 指出这不是数组问题,所以我调整了我的问题。

进一步调查显示,这并不是 Cloud Formation 问题,而是非常具体到 AWS::Serverless::Function 资源类型和 in 中的 Policies 属性。我怀疑这与 @987654332 的事实有关@property 在它可以接受的方面非常灵活。它可以接受引用策略名称或 Arns 的字符串,也可以接受描述新策略的策略文档。我怀疑这意味着它无法支持这些功能。

【问题讨论】:

!Sub 与数组项或映射值一起使用应该没有区别。这似乎是一个错误,应该这样报告。我会尝试在!Sub 之后引用标量;也许这是一个解析器错误,如果是这样,这可能是一种解决方法。 感谢您的回复。引号不起作用,所以我会尝试记录错误 已创建问题:forums.aws.amazon.com/thread.jspa?threadID=261756 【参考方案1】:

显然,元素数组中的 !Sub 函数没有任何问题。

我已尝试在 Cloudformation 上创建以下堆栈,并且成功了:

AWSTemplateFormatVersion: '2010-09-09'
Description: 'IAM Roles Template'

Parameters:
  ArnBase:
    Type: String
    Default: arn:aws:iam::aws:policy/
  AWSLambdaFullAccess:
    Type: String
    Default: AWSLambdaFullAccess
  AmazonSESFullAccess:
    Type: String
    Default: AmazonSESFullAccess    

Resources:

  LambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          Effect: Allow
          Principal:
            Service: lambda.amazonaws.com
          Action: sts:AssumeRole          
      Policies:
        -
          PolicyName: CloudFormationFullAccess
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              -
                Effect: "Allow"
                Action: "cloudformation:*"
                Resource: "*"    
      ManagedPolicyArns:        
        - !Sub $ArnBase$AWSLambdaFullAccess        
        - !Sub $ArnBase$AmazonSESFullAccess
        - !Sub arn:aws:iam::$AWS::AccountId:policy/CustomAmazonGlacierReadOnlyAccess

这也应该可以使用 SAM...

【讨论】:

这很有趣。感谢您排除这一点。看起来我的问题需要更具体。可能是 SAM,也可能是无服务器函数类型的策略属性。我会进一步调查。【参考方案2】:

解决方法

AWS::Serverless::Function 资源类型支持多种访问配置方式。

    直接通过Policies 属性引用策略,并让框架创建一个具有这些策略的角色。 Role 属性可以引用已包含策略的角色。

我使用的是选项 1,但选项 2 被证明是解决 !Sub 函数问题的一种方法。

使用AWS::IAM::Role 使用我们想要的策略显式创建角色意味着我们可以在ManagedPolicyArns 属性中使用!Sub 函数。例如

role:
  Type: AWS::IAM::Role
  Properties:
    ...
    ManagedPolicyArns:
      - !Sub arn:aws:iam::$AWS::AccountId:policy/some-policy
    ...
lambda:
  Type: AWS::Serverless::Function
  Properties:
    ...
    Role: !GetAtt role.Arn
    ...

【讨论】:

以上是关于AWS Cloud Formation !Sub & !Ref AWS::Serverless::Function Policies 中的函数的主要内容,如果未能解决你的问题,请参考以下文章

AWS:Cloud Formation:是不是可以使用多个“DependsOn”?

如何在 AWS Cloud Formation 中实施嵌套堆栈?

AWS Cloud Formation 陷入 Review_In_Progress

如何在 AWS SAM Cloud-Formation 中使用 Route53 设置自定义域名

我能否在 SAM 模板中使用 AWS Cloud Formation 资源语法,反之亦然?

如何使用 Cloud Formation 模板自动扩展 DynamoDB?