Skip to content

Instantly share code, notes, and snippets.

@NicolasRitouet
Last active November 28, 2019 14:56
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save NicolasRitouet/7b8367b79734e01deb36ef707dae91a4 to your computer and use it in GitHub Desktop.
Save NicolasRitouet/7b8367b79734e01deb36ef707dae91a4 to your computer and use it in GitHub Desktop.
---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Cloudformation stack to manage permission to deploy a serverless service'
Parameters:
ServiceName:
Description: Name of the Service you want to deploy
Type: String
ServiceName2:
Description: Name of the 2nd Service you want to deploy
Type: String
Resources:
## Users
ServerlessDeployBot:
Type: AWS::IAM::User
Properties:
ManagedPolicyArns: # Max 10 policies
- !Ref ServelessDeployCFPolicy
- !Ref ServelessDeployS3Policy
- !Ref ServelessDeployLogsPolicy
- !Ref ServelessDeployIAMPolicy
- !Ref ServelessDeployLambdaPolicy
ServerlessDeployBotAccessKey:
Type: AWS::IAM::AccessKey
Properties:
UserName: !Ref ServerlessDeployBot
## Managed policies
ServelessDeployCFPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: 'cloudformation:ValidateTemplate'
Resource: '*'
- Effect: Allow
Action:
- 'cloudformation:Describe*'
- 'cloudformation:List*'
- 'cloudformation:Get*'
- 'cloudformation:PreviewStackUpdate'
- 'cloudformation:CreateStack'
- 'cloudformation:UpdateStack'
Resource:
- !Sub 'arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${ServiceName}-*'
- !Sub 'arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${ServiceName2}-*'
ServelessDeployS3Policy:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 's3:Get*'
- 's3:List*'
Resource:
- !Sub 'arn:aws:s3:::${ServiceName}-*'
- !Sub 'arn:aws:s3:::${ServiceName2}-*'
- Effect: Allow
Action:
- 's3:*'
Resource:
- !Sub 'arn:aws:s3:::${ServiceName}-*/*'
- !Sub 'arn:aws:s3:::${ServiceName2}-*/*'
ServelessDeployLogsPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'logs:DescribeLogGroups'
Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group::log-stream:*'
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:DeleteLogGroup'
- 'logs:DeleteLogStream'
- 'logs:DescribeLogStreams'
- 'logs:FilterLogEvents'
Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*:log-stream:*'
ServelessDeployIAMPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'iam:GetRole'
- 'iam:PassRole'
- 'iam:CreateRole'
- 'iam:DeleteRole'
- 'iam:DetachRolePolicy'
- 'iam:PutRolePolicy'
- 'iam:AttachRolePolicy'
- 'iam:DeleteRolePolicy'
Resource:
- !Sub 'arn:aws:iam::${AWS::AccountId}:role/${ServiceName}-*-lambdaRole'
- !Sub 'arn:aws:iam::${AWS::AccountId}:role/${ServiceName2}-*-lambdaRole'
ServelessDeployLambdaPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'apigateway:GET'
- 'apigateway:POST'
- 'apigateway:PUT'
- 'apigateway:DELETE'
Resource: !Sub 'arn:aws:apigateway:${AWS::Region}::/restapis'
- Effect: Allow
Action:
- 'apigateway:GET'
- 'apigateway:POST'
- 'apigateway:PUT'
- 'apigateway:DELETE'
Resource: !Sub 'arn:aws:apigateway:${AWS::Region}::/restapis/*'
- Effect: Allow
Action:
- 'lambda:*'
Resource:
- !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${ServiceName}-*'
- !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${ServiceName2}-*'
- Effect: Allow
Action:
- 'ec2:DescribeSecurityGroups'
- 'ec2:DescribeSubnets'
- 'ec2:DescribeVpcs'
Resource: '*'
- Effect: Allow
Action:
- 'events:Put*'
- 'events:Remove*'
- 'events:Delete*'
- 'events:Describe*'
Resource:
- !Sub 'arn:aws:events::${AWS::AccountId}:rule/${ServiceName}-*'
- !Sub 'arn:aws:events::${AWS::AccountId}:rule/${ServiceName2}-*'
Outputs:
ServerlessDeployBotAccessKey:
Value: !Ref ServerlessDeployBotAccessKey
Export:
Name: !Sub '${AWS::StackName}-ServerlessDeployBotAccessKey'
@Jud
Copy link

Jud commented Jul 18, 2017

Did serverless change their naming convention? After creating a servicename-dev user I get the following:

 ServerlessError: User: arn:aws:iam::(accountno):user/servicename-dev-ServerlessDeployBot-SGETERZVD7YJ is not authorized to perform: cloudformation:DescribeStackResources on resource: arn:aws:cloudformation:us-east-1:(accountno):stack/servicename-dev/*

@sjernigan
Copy link

sjernigan commented Jul 19, 2017

Jud, I had the problems above. First, I think you should make sure you use kebab case (e.g., user-report). When it fails, it will likely leave the cloud formation in a bad state that will prevent redeploys. Manually delete the stack. My next problem was with S3. I noticed that it didn't replace the ${ServiceName} vars in the users S3 policy ARNs ("Resource": [
"arn:aws:s3:::${ServiceName}-",
"arn:aws:s3:::${ServiceName2}-
"
],
Also note that it will include the ServiceName2 ARN even if you leave it blank and you may be giving away more broader permissions than you want. Next, on the S3 policy, I needed to delete the last /* on line 71 and 72. Of course this opens up S3 more than desired but I wasn't able to figure the permission and ARN it required from the sls output. After this, I was able to deploy the hello world service.

@sjernigan
Copy link

How do you get the value of the access key after this runs? I have been deleting the generated key and creating a new one.

@ncloward
Copy link

ncloward commented Aug 17, 2017

Thanks for the template! I ended up changing a few things. One major thing @sjernigan said the S3 ServiceName was not being substituted so it needs !Sub added so on lines 64, 65, 72, and 72:

- !Sub 'arn:aws:s3:::${ServiceName}-*'
- !Sub 'arn:aws:s3:::${ServiceName2}-*'

Here is my version, but I also had to have it support SNS and DynamoDb: https://gist.github.com/ncloward/de2f73b78e09eb3d6dd6282be28fb4ff

@NicolasRitouet
Copy link
Author

thanks @ncloward, I updated this gist with the fix for the servicename

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment