具有相同内联策略的 AWS SAM 多个函数

AWS SAM Multiple Functions with same Inline Policy

在 AWS SAM .yaml 模板中,我可以像这样为每个 lambda 函数声明一个内联策略:

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources:
  MyFunction:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: index.handler
      Runtime: nodejs8.10
      CodeUri: 's3://my-bucket/function.zip'
      Policies:
      - Statement:
        - Sid: SSMDescribeParametersPolicy
          Effect: Allow
          Action:
          - ssm:DescribeParameters
          Resource: '*'
        - Sid: SSMGetParameterPolicy
          Effect: Allow
          Action:
          - ssm:GetParameters
          - ssm:GetParameter
          Resource: '*'

但是,如果我希望多个函数共享同一个内联策略文档,我们是否在模板的 'Globals' 部分声明它?

到目前为止,文档让我相信最简洁的方法是创建一个带有附加策略的角色,然后简单地向每个函数声明角色,而不是像这样:

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Resources: 
  MyFunction:
    Type: 'AWS::Serverless::Function' 
    Properties:
      Handler: index.handler
      Runtime: nodejs8.10
      CodeUri: 's3://my-bucket/function.zip' 
      Role: arn:aws:iam::111111111111:role/SAMPolicy

有没有一种方法可以在模板中声明内联策略并在每个函数上简单地引用它?

无法引用和重复使用内联策略。但是,您可以创建和引用 AWS Managed Policy or a SAM policy template 而不是内联策略。

如果您想使用可重复使用的自定义策略,则必须创建 Customer Managed Policy and attach to the Lambda functions via the Role property

如果我想让多个函数共享同一个内联策略文档,我们是否在模板的'Globals'部分声明它? 是的。这是一个例子:

AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'

Globals:
  Function:
    Policies:
      - Statement:
          - Sid: SSMDescribeParametersPolicy
            Effect: Allow
            Action:
              - ssm:DescribeParameters
            Resource: '*'
          - Sid: SSMGetParameterPolicy
            Effect: Allow
            Action:
              - ssm:GetParameters
              - ssm:GetParameter
            Resource: '*'

Resources:
  MyFunction:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: index.handler
      Runtime: nodejs8.10
      CodeUri: 's3://my-bucket/function.zip'
  MyOtherFunction:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: index.handler
      Runtime: nodejs8.10
      CodeUri: 's3://my-bucket/other-function.zip'

你想做的事情应该有效,但目前没有。

你可以做的是定义一个 AWS::IAM::Role 可以由一个或多个函数承担。然后单独定义您的 AWS::IAM::Policy 政策,并将每一项政策应用于一个或多个角色。

Function1:
  Type: AWS::Serverless::Function
  Properties:
    FunctionName: function-1
    CodeUri: functions/func-1
    Description: Does stuff with DynamoDB and calls another Lambda function
    Role: !GetAtt Role1.Arn
    Environment:
      Variables:
        TABLE_NAME: !Ref DynamoDBTable1

Function2:
  Type: AWS::Serverless::Function
  Properties:
    FunctionName: function-2
    CodeUri: functions/func-2
    Description: Does stuff with the main database
    Role: !GetAtt Role2.Arn
    Layers:
      - !Ref Libraries
    Environment:
      Variables:
        PGHOST: !GetAtt MainDB.Endpoint.Address
        PGPORT: !GetAtt MainDB.Endpoint.Port

Role1:
  Type: AWS::IAM::Role
  Properties:
    ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    AssumeRolePolicyDocument:
      Version: "2012-10-17"
      Statement:
        - Effect: Allow
          Principal:
            Service:
              - lambda.amazonaws.com
          Action:
            - sts:AssumeRole
    Policies:
      - PolicyName: allow-dynamodb-write
        PolicyDocument:
          Version: 2012-10-17
          Statement:
            - Action: dynamodb:PutItem
              Resource: !GetAtt EventTable.Arn
              Effect: Allow

Role2:
  Type: AWS::IAM::Role
  Properties:
    ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    AssumeRolePolicyDocument:
      Version: "2012-10-17"
      Statement:
        - Effect: Allow
          Principal:
            Service:
              - lambda.amazonaws.com
          Action:
            - sts:AssumeRole

AllowInvokeFunctionPolicy:
  Type: AWS::IAM::Policy
  Properties:
    PolicyName: allow-invoke-function
    PolicyDocument:
      Version: 2012-10-17
      Statement:
        - Action: lambda:InvokeFunction
          Resource: !GetAtt LogEventFunction.Arn
          Effect: Allow
    Roles:
      - Ref: Role1
        Ref: Role2

AllowDBAccessPolicy:
  Type: AWS::IAM::Policy
  Properties:
    PolicyName: allow-rds-connect
    PolicyDocument:
      Version: 2012-10-17
      Statement:
        - Action: rds-db:connect
          Resource: !Sub arn:aws:rds:${AWS::Region}:${AWS::AccountId}:db:${MainDB}
          Effect: Allow
    Roles:
      - Ref: Role2