Rather than manually perform the steps described in http://docs.aws.amazon.com/lambda/latest/dg/automating-deployment.html, I wrote a CloudFormation template that performs the same functions. In other words, you can deploy my template and the result is a newly-created Code Commit repository and associated Code Pipeline which builds and deploys any SAM template you define to a new CloudFormation stack. All that you need to do is add a buildspec.yml and samTemplate.yaml to the newly-created Code Commit repo and push your changes.
My template is available at the link below. Please note it's an early draft and has much room for improvement... but it does closely mirror the AWS guide linked above: https://github.com/matwerber1/cloudformation-pipeline-template
Here's the template code, samTemplate.yaml:
AWSTemplateFormatVersion: '2010-09-09'
Description: Creates Private Code Commit repo and Deployment Pipeline to CloudFormation
Parameters:
ProjectNameParameter:
Type: String
Default: myProject
Description: "the name to assign to your newly-created code repo, build project, pipeline, and IAM resources."
CodeBuildS3BucketParameter:
Type: String
Default: "myCodeBuildS3Bucket"
Description: "a pre-existing S3 bucket in which to store Code Build artifacts."
CodePipelineS3BucketParameter:
Type: String
Default: "myCodePipelineS3Bucket"
Description: "a pre-existing S3 bucket in which to store Code Pipeline resources."
Resources:
MyRepo:
Type: "AWS::CodeCommit::Repository"
Properties:
RepositoryName: !Sub '${ProjectNameParameter}'
CloudFormationRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: !Sub "${AWS::Region}-${ProjectNameParameter}-cloudformation"
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- cloudformation.amazonaws.com
Action:
- "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: cloudformation-service
PolicyDocument:
Version: "2012-10-17"
Statement:
- Action:
- "*"
Resource: "*"
Effect: Allow
CodePipelineRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: !Sub "${AWS::Region}-${ProjectNameParameter}-codepipeline"
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- codepipeline.amazonaws.com
Action:
- "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: codepipeline-service
PolicyDocument:
Version: "2012-10-17"
Statement:
- Action:
- "codecommit:GetBranch"
- "codecommit:GetCommit"
- "codecommit:UploadArchive"
- "codecommit:GetUploadArchiveStatus"
- "codecommit:CancelUploadArchive"
Resource: "*"
Effect: Allow
- Action:
- "s3:GetObject"
- "s3:GetObjectVersion"
- "s3:GetBucketVersioning"
Resource: "*"
Effect: Allow
- Action:
- "s3:PutObject"
Resource:
- "arn:aws:s3:::codepipeline*"
- "arn:aws:s3:::elasticbeanstalk*"
Effect: Allow
- Action:
- "codedeploy:CreateDeployment"
- "codedeploy:GetApplicationRevision"
- "codedeploy:GetDeployment"
- "codedeploy:GetDeploymentConfig"
- "codedeploy:RegisterApplicationRevision"
Resource: "*"
Effect: Allow
- Action:
- "elasticbeanstalk:*"
- "ec2:*"
- "elasticloadbalancing:*"
- "autoscaling:*"
- "cloudwatch:*"
- "s3:*"
- "sns:*"
- "cloudformation:*"
- "rds:*"
- "sqs:*"
- "ecs:*"
- "iam:PassRole"
Resource: "*"
Effect: Allow
- Action:
- "lambda:InvokeFunction"
- "lambda:ListFunctions"
Resource: "*"
Effect: Allow
- Action:
- "opsworks:CreateDeployment"
- "opsworks:DescribeApps"
- "opsworks:DescribeCommands"
- "opsworks:DescribeDeployments"
- "opsworks:DescribeInstances"
- "opsworks:DescribeStacks"
- "opsworks:UpdateApp"
- "opsworks:UpdateStack"
Resource: "*"
Effect: Allow
- Action:
- "cloudformation:CreateStack"
- "cloudformation:DeleteStack"
- "cloudformation:DescribeStacks"
- "cloudformation:UpdateStack"
- "cloudformation:CreateChangeSet"
- "cloudformation:DeleteChangeSet"
- "cloudformation:DescribeChangeSet"
- "cloudformation:ExecuteChangeSet"
- "cloudformation:SetStackPolicy"
- "cloudformation:ValidateTemplate"
- "iam:PassRole"
Resource: "*"
Effect: Allow
- Action:
- "codebuild:BatchGetBuilds"
- "codebuild:StartBuild"
Resource: "*"
Effect: Allow
CodeBuildRole:
Type: "AWS::IAM::Role"
Properties:
RoleName: !Sub "${AWS::Region}-${ProjectNameParameter}-codebuild"
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- codebuild.amazonaws.com
Action:
- "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: codebuild-service
PolicyDocument:
Version: "2012-10-17"
Statement:
- Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource:
- !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${ProjectNameParameter}"
- !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${ProjectNameParameter}:*"
Effect: Allow
- Action:
- "s3:PutObject"
- "s3:GetObject"
- "s3:GetObjectVersion"
Resource: !Sub "arn:aws:s3:::codepipeline-${AWS::Region}-*"
Effect: Allow
- Action: "ssm:GetParameters"
Resource: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/CodeBuild/*"
Effect: Allow
- Action: "s3:PutObject"
Resource: !Sub "arn:aws:s3:::${CodeBuildS3BucketParameter}*"
Effect: Allow
MyBuild:
Type: "AWS::CodeBuild::Project"
Properties:
Artifacts:
Type: CODEPIPELINE
BadgeEnabled: false
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: "aws/codebuild/python:3.5.2"
Type: LINUX_CONTAINER
Name: !Sub '${ProjectNameParameter}'
ServiceRole: !Ref CodeBuildRole
Source:
Type: CODEPIPELINE
TimeoutInMinutes: 60
MyPipeline:
Type: "AWS::CodePipeline::Pipeline"
Properties:
ArtifactStore:
Location: !Ref CodePipelineS3BucketParameter
Type: S3
Name: !Sub "${ProjectNameParameter}"
RestartExecutionOnUpdate: false
RoleArn: !GetAtt CodePipelineRole.Arn
Stages:
- Name: "Source"
Actions:
- ActionTypeId:
Category: Source
Owner: AWS
Provider: CodeCommit
Version: "1"
Configuration:
RepositoryName: !GetAtt MyRepo.Name
BranchName: master
PollForSourceChanges: true
Name: Source
OutputArtifacts:
- Name: MyApp
RunOrder: 1
- Name: "Build"
Actions:
- ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: "1"
Configuration:
ProjectName: !Ref MyBuild
InputArtifacts:
- Name: MyApp
Name: "Build"
OutputArtifacts:
- Name: MyAppBuild
RunOrder: 2
- Name: "Staging"
Actions:
- ActionTypeId:
Category: Deploy
Owner: AWS
Provider: CloudFormation
Version: "1"
Configuration:
ActionMode: CHANGE_SET_REPLACE
StackName: !Ref ProjectNameParameter
Capabilities: CAPABILITY_NAMED_IAM
ChangeSetName: MyChangeSet
RoleArn: !GetAtt CloudFormationRole.Arn
TemplatePath: MyAppBuild::NewSamTemplate.yaml
InputArtifacts:
- Name: MyAppBuild
Name: "build_changeset"
RunOrder: 3
- ActionTypeId:
Category: Deploy
Owner: AWS
Provider: CloudFormation
Version: "1"
Configuration:
ActionMode: CHANGE_SET_EXECUTE
StackName: !Ref ProjectNameParameter
Capabilities: CAPABILITY_NAMED_IAM
ChangeSetName: MyChangeSet
Name: "execute_changeset"
RunOrder: 4