【问题标题】:AWS SAM Multiple Functions with same Inline Policy具有相同内联策略的 AWS SAM 多项功能
【发布时间】:2021-02-07 22:11:15
【问题描述】:

在 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: '*'

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

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

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

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

【问题讨论】:

    标签: amazon-web-services aws-lambda aws-sam


    【解决方案1】:

    你想做的事情应该工作,但目前不行。

    您可以做的是定义一个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
    

    【讨论】:

      【解决方案2】:

      如果我希望多个函数共享同一个内联策略文档,我们是否在模板的“全局”部分声明它? 是的。这是一个例子:

      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'
      

      【讨论】:

      • 谢谢,这正是我想要的!
      • 我不认为这是可能的 - Policies 在 Globals 中不受支持:docs.aws.amazon.com/serverless-application-model/latest/…
      • 不幸的是,这不起作用:"samtranslator.plugins.globals.globals.InvalidGlobalsSectionException: ('Globals', "'Policies' 不是 'Function' 的受支持属性。必须是以下之一价值观……”
      • 这会将这些策略附加到堆栈中的每个函数(如果它确实有效)。
      【解决方案3】:

      内联策略不能被引用和重用。但是,您可以创建和引用 AWS Managed PolicySAM policy template 而不是内联策略。

      如果您想使用可重复使用的自定义策略,则必须创建一个 Customer Managed Policy 并通过 Role property 附加到 Lambda 函数。

      【讨论】:

      • 不幸的是,我没有权限创建自定义托管策略以供参考,否则我同意这会更简洁。
      • A AWS::IAM::Policy 资源不会被引用包含在内。相反,可以在其Roles: 属性下指定任意数量的角色,然后将其附加到该属性。
      • 我会说这感觉不直观(似乎将!Refs 列在RoleFunction 定义下的自定义策略是合适的。但是,该功能目前似乎不可用.
      猜你喜欢
      • 2020-04-02
      • 2020-03-02
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      • 2022-01-07
      • 1970-01-01
      • 2020-11-14
      • 2018-09-28
      相关资源
      最近更新 更多