AWS SAM Multiple Functions with same Inline Policy
Asked Answered
L

3

8

In the AWS SAM .yaml template I can declare an inline policy for each lambda function like so:

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

However if I want multiple functions to share the same inline policy document, do we declare it in the 'Globals' section of the template?

So far the documentation leads me to believe that the cleanest way to do this would be creating a role with the attached policies and simply declaring the role to each function instead like so:

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

Is there a way to declare an inline policy within the template and simply reference it on each function instead?

Lanettelaney answered 25/10, 2020 at 12:44 Comment(0)
A
0

If I want multiple functions to share the same inline policy document, do we declare it in the 'Globals' section of the template? Yes. Here is an example:

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'
Athirst answered 25/10, 2020 at 16:20 Comment(4)
Thanks this is exactly what I was looking for!Lanettelaney
I don't think this is possible - Policies is not supported in Globals: docs.aws.amazon.com/serverless-application-model/latest/…Footlambert
This does not work unfortunately: "samtranslator.plugins.globals.globals.InvalidGlobalsSectionException: ('Globals', "'Policies' is not a supported property of 'Function'. Must be one of the following values..."Thirzia
This would attach those policies to every function in the stack (if it did work).Sarcocarp
S
2

An inline policy can’t be referenced and reused. However, you can create and reference an AWS Managed Policy or a SAM policy template instead of an inline policy.

If you want to use a reusable custom policy, you will have to create a Customer Managed Policy and attach to the Lambda functions via the Role property.

Squirmy answered 25/10, 2020 at 12:56 Comment(3)
Unfortunately I don't have dispensation to create custom managed policies to reference, otherwise I agree this would be cleaner.Lanettelaney
A AWS::IAM::Policy resource doesn't get included by being referenced. Rather, any number of roles can be specified under its Roles: property, which it will then be attached to.Sarcocarp
I would say that this feels unintuitive (it seems like listing !Refs to custom policies under a Role or Function definition would be appropriate. However, that functionality currently appears to be unavailable.Sarcocarp
S
2

What you want to do ought to work, but it currently doesn't.

What you can do is define a AWS::IAM::Role which can be assumed by one or more functions. Then define your AWS::IAM::Policy policies individually and apply each of them to one or more roles.

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
Sarcocarp answered 11/9, 2021 at 11:22 Comment(0)
A
0

If I want multiple functions to share the same inline policy document, do we declare it in the 'Globals' section of the template? Yes. Here is an example:

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'
Athirst answered 25/10, 2020 at 16:20 Comment(4)
Thanks this is exactly what I was looking for!Lanettelaney
I don't think this is possible - Policies is not supported in Globals: docs.aws.amazon.com/serverless-application-model/latest/…Footlambert
This does not work unfortunately: "samtranslator.plugins.globals.globals.InvalidGlobalsSectionException: ('Globals', "'Policies' is not a supported property of 'Function'. Must be one of the following values..."Thirzia
This would attach those policies to every function in the stack (if it did work).Sarcocarp

© 2022 - 2024 — McMap. All rights reserved.