Reputation: 207
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?
Upvotes: 9
Views: 2923
Reputation: 178
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
Upvotes: 2
Reputation: 17170
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'
Upvotes: 0
Reputation: 51684
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.
Upvotes: 2