/serverless-deploy-user.yaml
Forked from bsamuel-ui/serverless-deploy-user.yaml
Created Apr 17, 2018
Cloudformation template to deploy permissions for deploying a serverless project.
AWSTemplateFormatVersion: 2010-09-09 | |
Description: > | |
Constructs a managed IAM policy to deploy a serverless project. | |
This template assumes the stack is being deployed in the current region and account. | |
You can then attach this policy to other IAM objects, such as users or roles. | |
Based on the work done in: https://github.com/serverless/serverless/issues/1439 | |
Parameters: | |
UserName: | |
Description: >- | |
The name of the IAM User to construct. | |
Type: String | |
# From https://docs.aws.amazon.com/IAM/latest/APIReference/API_UpdateUser.html | |
AllowedPattern: '[A-Za-z0-9+=,.@-]+' #' | |
Service: | |
Description: >- | |
A name for this serverless service. | |
Type: String | |
Stage: | |
Description: >- | |
The stage for this project. | |
Type: String | |
MayInvoke: | |
Description: >- | |
Allow the constructed user to invoke lambdas. | |
Type: String | |
AllowedValues: [allow, deny] | |
Default: deny | |
MayDeployFunction: | |
Description: >- | |
Allow the user to deploy a single function. This is ignored if you don't create a CfnRole. | |
Type: String | |
AllowedValues: [allow, deny] | |
Default: allow | |
CreateCfnRole: | |
Description: >- | |
Create a role to assign to the `provider.cfnRole` variable, rather than rely on the user's permissions. | |
Type: String | |
AllowedValues: [create, skip] | |
Default: skip | |
Conditions: | |
AllowInvoke: !Equals [!Ref MayInvoke, allow] | |
UserFullPermissions: !Or [!Equals [!Ref MayDeployFunction, allow], !Equals [!Ref CreateCfnRole, ignore]] | |
CreateCfnRole: !Equals [!Ref CreateCfnRole, create] | |
Resources: | |
DeployUser: | |
Type: AWS::IAM::User | |
Properties: | |
UserName: !Ref UserName | |
Policies: [] # Prefer managing policies separately. | |
CfnRole: | |
Condition: CreateCfnRole | |
Type: AWS::IAM::Role | |
Properties: | |
Policies: [] | |
AssumeRolePolicyDocument: | |
Version: 2012-10-17 | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: | |
- !Sub 'cloudformation.${AWS::URLSuffix}' | |
Action: | |
- sts:AssumeRole | |
DeployPolicy: | |
# Cumulative inline policy size cannot exceed 2,048 characters for IAM Users. | |
# Cloudformation will hang waiting for an update exceeding this amount to complete. | |
# https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html | |
Type: AWS::IAM::ManagedPolicy | |
Properties: | |
Users: | |
- !Ref DeployUser | |
ManagedPolicyName: !Sub '${Service}-${Stage}-DeployPolicy' | |
PolicyDocument: | |
Version: 2012-10-17 | |
Statement: | |
- Sid: ListDeploymentBucket | |
Effect: Allow | |
Action: | |
- s3:GetBucketLocation | |
- s3:ListBucket | |
Resource: | |
# See https://docs.aws.amazon.com/AmazonS3/latest/dev/s3-arn-format.html | |
# Also https://docs.aws.amazon.com/govcloud-us/latest/UserGuide/using-govcloud-arns.html | |
- !Sub 'arn:${AWS::Partition}:s3:::${Service}-${Stage}-serverlessdeploymentbucket-*' | |
- Sid: ReadWriteAccessToDeploymentObjects | |
Effect: Allow | |
Action: | |
- s3:GetObject* | |
- s3:PutObject | |
- s3:DeleteObject | |
Resource: | |
- !Sub 'arn:${AWS::Partition}:s3:::${Service}-${Stage}-serverlessdeploymentbucket-*/*' | |
- Sid: ValidateTemplate | |
Effect: Allow | |
Action: | |
- cloudformation:ValidateTemplate | |
Resource: '*' | |
- Sid: ReadAccessToCloudFormation | |
Effect: Allow | |
Action: | |
- cloudformation:Describe* | |
- cloudformation:List* | |
- cloudformation:Get* | |
- cloudformation:PreviewStackUpdate | |
Resource: | |
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-iam-template.html | |
- !Sub 'arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${Service}-${Stage}/*' | |
- Sid: WriteAccessToCloudFormation | |
Effect: Allow | |
Action: | |
- cloudformation:CreateStack | |
- cloudformation:UpdateStack | |
- cloudformation:DeleteStack | |
Resource: | |
- !Sub 'arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${Service}-${Stage}/*' | |
- Sid: GetLambdaRole | |
Effect: Allow | |
Action: | |
- iam:GetRole | |
Resource: | |
- !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${Service}-${Stage}-${AWS::Region}-lambdaRole' | |
DeployViaRole: | |
Condition: CreateCfnRole | |
Type: AWS::IAM::Policy | |
Properties: | |
Users: | |
- !Ref DeployUser | |
PolicyName: !Sub '${Service}-${Stage}-DeployViaRole' | |
PolicyDocument: | |
Version: 2012-10-17 | |
Statement: | |
- Sid: PassRoleToCloudFormation | |
Effect: Allow | |
Action: | |
- iam:PassRole | |
Resource: | |
- !GetAtt CfnRole.Arn | |
UpdateServicePolicy: | |
Type: AWS::IAM::ManagedPolicy | |
Properties: | |
Users: | |
- !If [UserFullPermissions, !Ref DeployUser, !Ref 'AWS::NoValue'] | |
Roles: | |
- !If [CreateCfnRole, !Ref CfnRole, !Ref 'AWS::NoValue'] | |
ManagedPolicyName: !Sub '${Service}-${Stage}-UpdateServicePolicy' | |
PolicyDocument: | |
Version: 2012-10-17 | |
Statement: | |
- Sid: DropDeploymentBucket | |
Effect: Allow | |
Action: | |
- s3:DeleteBucket | |
Resource: | |
- !Sub 'arn:${AWS::Partition}:s3:::${Service}-${Stage}-serverlessdeploymentbucket-*' | |
- Sid: ReadAccessToDeploymentObjects | |
Effect: Allow | |
Action: | |
- s3:GetObject* | |
Resource: | |
- !Sub 'arn:${AWS::Partition}:s3:::${Service}-${Stage}-serverlessdeploymentbucket-*/*' | |
- Sid: Lambdas | |
Effect: Allow | |
Action: | |
- lambda:Get* | |
- lambda:List* | |
- lambda:UpdateFunctionCode | |
- lambda:UpdateFunctionConfiguration | |
- lambda:PublishVersion | |
- lambda:CreateAlias | |
- lambda:DeleteAlias | |
- lambda:UpdateAlias | |
- lambda:AddPermission | |
Resource: | |
- !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:${Service}-${Stage}*' | |
- Sid: CloudwatchEvents | |
Effect: Allow | |
Action: | |
- events:Put* | |
- events:Remove* | |
- events:Delete* | |
- events:Describe* | |
Resource: | |
- !Sub 'arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/${Service}-${Stage}*' | |
- Sid: CloudwatchLogs | |
Effect: Allow | |
Action: | |
- logs:CreateLogGroup | |
- logs:CreateLogStream | |
- logs:DeleteLogGroup | |
- logs:DeleteLogStream | |
- logs:DescribeLogStreams | |
- logs:FilterLogEvents | |
Resource: | |
- !Sub 'arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${Service}-${Stage}*:log-stream:*' | |
- Sid: CloudwatchLogGroups | |
Effect: Allow | |
Action: | |
- logs:DescribeLogGroups | |
Resource: | |
- !Sub 'arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group::log-stream:*' | |
- Sid: IamRole | |
Effect: Allow | |
Action: | |
- iam:GetRole | |
- iam:PassRole | |
- iam:CreateRole | |
- iam:DeleteRole | |
- iam:DetachRolePolicy | |
- iam:PutRolePolicy | |
- iam:AttachRolePolicy | |
- iam:DeleteRolePolicy | |
Resource: | |
- !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/${Service}-${Stage}-${AWS::Region}-lambdaRole' | |
ApiGwPolicy: | |
Type: AWS::IAM::Policy | |
Properties: | |
Users: | |
- !If [UserFullPermissions, !Ref DeployUser, !Ref 'AWS::NoValue'] | |
Roles: | |
- !If [CreateCfnRole, !Ref CfnRole, !Ref 'AWS::NoValue'] | |
PolicyName: !Sub '${Service}-${Stage}-ApiGwPolicy' | |
PolicyDocument: | |
Version: 2012-10-17 | |
Statement: | |
- Sid: ApiGwEvents | |
Effect: Allow | |
Action: | |
- apigateway:GET | |
- apigateway:POST | |
- apigateway:PUT | |
- apigateway:DELETE | |
Resource: | |
- !Sub 'arn:${AWS::Partition}:apigateway:${AWS::Region}:::/restapis' | |
- !Sub 'arn:${AWS::Partition}:apigateway:${AWS::Region}:::/restapis/*' | |
InvokeLambdaPolicy: | |
Condition: AllowInvoke | |
Type: AWS::IAM::Policy | |
Properties: | |
Users: | |
- !Ref DeployUser | |
PolicyName: !Sub '${Service}-${Stage}-InvokeLambdaPolicy' | |
PolicyDocument: | |
Version: 2012-10-17 | |
Statement: | |
- Sid: InvokeFunction | |
Effect: Allow | |
Action: | |
- lambda:InvokeFunction | |
Resource: | |
- !Sub 'arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:${Service}-${Stage}*' | |
Outputs: | |
cfnRole: | |
Description: 'The `provider.cfnRole` value to use, or empty string if no role was created.' | |
Value: !If [CreateCfnRole, !GetAtt CfnRole.Arn, ''] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment