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

时间:2017-08-16 12:13:23

标签: yaml aws-lambda amazon-cloudformation

我一直在我的C​​loudFormation 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指出这不是阵列问题所以我调整了我的问题。

进一步的调查显示,它不是一个完整的云层问题,而是非常特定于AWS::Serverless::Function资源类型和内部的Policies属性。我怀疑它与事实有关Policies属性在它可以接受的内容方面非常灵活。它可以接受引用策略名称或Arns的字符串,也可以接受描述新策略的策略文档。我怀疑这意味着它无法支持这些功能。

2 个答案:

答案 0 :(得分:2)

显然,没有什么问题!元素数组中的子函数。

我尝试在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 ...

答案 1 :(得分:0)

解决方法

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

  1. 直接通过Policies属性参考策略,让框架创建一个具有这些策略的角色。
  2. Role属性可以引用已包含策略的角色。
  3. 我使用的是选项1,但选项2证明可以解决!Sub函数的问题。

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

    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
        ...