Skip to content

Instantly share code, notes, and snippets.

@daaru00
Created July 8, 2021 14:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daaru00/a61b29994ab6e2812e800dd837cce43c to your computer and use it in GitHub Desktop.
Save daaru00/a61b29994ab6e2812e800dd837cce43c to your computer and use it in GitHub Desktop.
A SAM template that describe an AWS CodeBuild pipeline that build a static website and deploy it to an S3 Bucket and invalidate the CloudFront distribution.
AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::Serverless-2016-10-31
# Template Information
Description: "Personal Website Deploy Pipeline"
# Template Parameters
Parameters:
BucketName:
Type: String
Description: "The the S3 bucket created by website stack"
DistributionId:
Type: String
Description: "The identifier of CloudFront distribution"
CacheControlMaxAge:
Type: Number
Description: "The max-age cache header to set fo uploaded objects"
Default: 31536000
GitHubRepo:
Type: String
Description: "The name of github repository"
GitHubUsername:
Type: String
Description: "The name of github username"
GitHubApiToken:
Type: String
Description: "The name of github api token"
NoEcho: true
GitHubBranch:
Type: String
Description: "The name of github branch"
Default: "master"
NpmBuildScript:
Type: String
Description: "The npm script name that generate the website"
Default: "build"
ArtifactPath:
Type: String
Description: "The path of the directory to upload"
Default: "./dist"
# Template Resources
Resources:
CodeBuildRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- codebuild.amazonaws.com
Action: sts:AssumeRole
Path: "/"
CodeBuildRolePolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: CodeBuildRolePolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/*
- Effect: Allow
Action: s3:ListAllMyBuckets
Resource: "*"
- Effect: Allow
Action:
- s3:PutObject
- s3:GetObjectAcl
- s3:GetObject
- s3:ListBucket
- s3:DeleteObject
- s3:PutObjectAcl
Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}
- !Sub arn:aws:s3:::${ArtifactBucket}/*
- !Sub arn:aws:s3:::${BucketName}
- !Sub arn:aws:s3:::${BucketName}/*
- Effect: Allow
Action:
- cloudfront:CreateInvalidation
Resource:
- !Sub arn:aws:cloudfront::${AWS::AccountId}:distribution/${DistributionId}
Roles:
- !Ref CodeBuildRole
CodeBuild:
Type: AWS::CodeBuild::Project
Properties:
Name: !Ref AWS::StackName
ConcurrentBuildLimit: 1
Artifacts:
Type: CODEPIPELINE
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/standard:5.0
Type: LINUX_CONTAINER
ServiceRole: !Ref CodeBuildRole
Source:
Type: CODEPIPELINE
BuildSpec: !Sub |
version: 0.2
phases:
install:
runtime-versions:
nodejs: 14
pre_build:
commands:
- npm install
build:
commands:
- npm run ${NpmBuildScript}
post_build:
commands:
- aws s3 sync --delete --no-progress --cache-control max-age='${CacheControlMaxAge}' ${ArtifactPath} s3://${BucketName}/
- aws cloudfront create-invalidation --distribution-id ${DistributionId} --paths "/*"
cache:
paths:
- 'node_modules/**/*'
artifacts:
files:
- '${ArtifactPath}/**/*'
Cache:
Type: S3
Location: !Sub "${ArtifactBucket}/cache"
Modes:
- LOCAL_CUSTOM_CACHE
- LOCAL_SOURCE_CACHE
Tags:
- Key: Stack
Value: !Ref AWS::StackName
TimeoutInMinutes: 10
CodePipelineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Sid: ""
Effect: Allow
Principal:
Service:
- codepipeline.amazonaws.com
Action: sts:AssumeRole
Path: "/"
CodePipelineRolePolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: CodePipelineRolePolicy
PolicyDocument:
Statement:
- Action:
- s3:GetObject
- s3:GetObjectVersion
- s3:GetBucketVersioning
Resource: "*"
Effect: Allow
- Action:
- s3:PutObject
Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}
- !Sub arn:aws:s3:::${ArtifactBucket}/*
Effect: Allow
- Action:
- codebuild:BatchGetBuilds
- codebuild:StartBuild
Resource: "*"
Effect: Allow
Roles:
- !Ref CodePipelineRole
CodePipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
Name: !Ref AWS::StackName
RoleArn: !GetAtt CodePipelineRole.Arn
Stages:
- Name: Source
Actions:
- Name: SourceAction
ActionTypeId:
Category: Source
Owner: ThirdParty
Version: "1"
Provider: GitHub
OutputArtifacts:
- Name: StaticSiteSource
Configuration:
Owner: !Ref GitHubUsername
Repo: !Ref GitHubRepo
Branch: !Ref GitHubBranch
OAuthToken: !Ref GitHubApiToken
RunOrder: 1
- Name: Build
Actions:
- Name: CodeBuild
InputArtifacts:
- Name: StaticSiteSource
ActionTypeId:
Category: Build
Owner: AWS
Version: "1"
Provider: CodeBuild
OutputArtifacts:
- Name: StaticSite
Configuration:
ProjectName: !Ref CodeBuild
RunOrder: 1
ArtifactStore:
Type: S3
Location: !Ref ArtifactBucket
ArtifactBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Delete
Properties:
BucketName: !Sub "${AWS::StackName}-artifact"
AccessControl: Private
# Template Outputs
Outputs:
CodePipelineName:
Description: "The name of the CodePipeline"
Value: !Ref CodePipeline
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment