Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
250 lines (243 sloc) 7.3 KB
AWSTemplateFormatVersion: "2010-09-09"
Description: Serverless deployment pipeline for a website powered by Hexo, including a CDN, HTTPS/Cert and Route53 records
Parameters:
GithubOauthToken:
Type: String
GithubRepoOwner:
Type: String
GithubRepoName:
Type: String
GithubRepoBranch:
Type: String
Default: master
ApexDomainName:
Type: String
RedirectDomainName:
Type: String
Description: All hits on this domain will be redirected to ApexDomainName (usually needed to redirect www. to the APEX domain)
ErrorDocument:
Type: String
Description: Path to a custom error document in S3
DeploymentStage:
Type: String
Default: prod
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Source Code Repository
Parameters:
- GithubRepoOwner
- GithubRepoName
- GithubRepoBranch
- GithubOauthToken
Conditions:
HasErrorDocument: !Not [!Equals [!Ref ErrorDocument, '']]
Resources:
WebsiteBucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: PublicRead
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: !If [HasErrorDocument, !Ref ErrorDocument, !Ref 'AWS::NoValue']
WebsiteBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref WebsiteBucket
PolicyDocument:
Version: "2012-10-17"
Statement:
Effect: Allow
Principal: "*"
Action: s3:GetObject
Resource: !Sub arn:aws:s3:::${WebsiteBucket}/*
ArtifactStoreBucket:
Type: AWS::S3::Bucket
Properties:
VersioningConfiguration:
Status: Enabled
AccessControl: BucketOwnerFullControl
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
RoleArn: !GetAtt PipelineRole.Arn
ArtifactStore:
Location:
Ref:
ArtifactStoreBucket
Type: S3
Stages:
- Name: Source
Actions:
- Name: SourceAction
ActionTypeId:
Category: Source
Owner: ThirdParty
Version: 1
Provider: GitHub
InputArtifacts: []
OutputArtifacts:
- Name: SourceOutput
Configuration:
Owner: !Ref GithubRepoOwner
Repo: !Ref GithubRepoName
Branch: !Ref GithubRepoBranch
OAuthToken: !Ref GithubOauthToken
RunOrder: 1
- Name: DeployWebsite
Actions:
- Name: DeployWebsiteAction
ActionTypeId:
Category: Build
Owner: AWS
Version: 1
Provider: CodeBuild
InputArtifacts:
- Name: SourceOutput
OutputArtifacts:
- Name: DeployWebsiteActionOutput
Configuration:
ProjectName:
Ref: DeployWebsiteBuild
RunOrder: 2
PipelineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
Effect: Allow
Principal:
Service: codepipeline.amazonaws.com
Action: sts:AssumeRole
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AdministratorAccess
DeployWebsiteBuild:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/nodejs:10.1.0
Type: LINUX_CONTAINER
EnvironmentVariables:
- Name: WEBSITE_BUCKET
Value: !Ref WebsiteBucket
Name: !Sub DeployWebsiteBuild-${DeploymentStage}
ServiceRole: !Ref DeployWebsiteRole
Source:
Type: CODEPIPELINE
BuildSpec: |
version: 0.1
phases:
install:
commands:
- npm install
build:
commands:
- node_modules/.bin/hexo deploy
post_build:
commands:
- aws s3 sync public/ s3://$WEBSITE_BUCKET/ --delete
DeployWebsiteRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AdministratorAccess
WebsiteCdn:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Aliases:
- !Ref ApexDomainName
PriceClass: PriceClass_100
Origins:
- DomainName: !Sub ${WebsiteBucket}.s3-website-${AWS::Region}.amazonaws.com
Id: Origin
CustomOriginConfig:
OriginProtocolPolicy: http-only
DefaultCacheBehavior:
Compress: true
DefaultTTL: 300
ForwardedValues:
QueryString: false
TargetOriginId: Origin
ViewerProtocolPolicy: redirect-to-https
Enabled: true
ViewerCertificate:
AcmCertificateArn: !Ref WebsiteCertificate
SslSupportMethod: sni-only
HttpVersion: http2
# Logging:
# Bucket: !GetAtt WebsiteCdnLogBucket.DomainName
# IncludeCookies: true
WebsiteCertificate:
Type: AWS::CertificateManager::Certificate
Properties:
DomainName: !Ref ApexDomainName
DomainValidationOptions:
- DomainName: !Ref RedirectDomainName
ValidationDomain: !Ref ApexDomainName
- DomainName: !Ref ApexDomainName
ValidationDomain: !Ref ApexDomainName
SubjectAlternativeNames:
- !Ref RedirectDomainName
S3BucketRedirect:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: !Ref RedirectDomainName
WebsiteConfiguration:
RedirectAllRequestsTo:
HostName: !Ref ApexDomainName
Protocol: https
CloudFrontDistributionRedirect:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Aliases:
- !Ref RedirectDomainName
PriceClass: PriceClass_100
Origins:
- DomainName: !Sub ${S3BucketRedirect}.s3-website-${AWS::Region}.amazonaws.com
Id: Origin
CustomOriginConfig:
OriginProtocolPolicy: http-only
DefaultCacheBehavior:
Compress: true
DefaultTTL: 300
ForwardedValues:
QueryString: false
TargetOriginId: Origin
ViewerProtocolPolicy: redirect-to-https
Enabled: true
ViewerCertificate:
AcmCertificateArn: !Ref WebsiteCertificate
SslSupportMethod: sni-only
HttpVersion: http2
DNS:
Type: AWS::Route53::RecordSetGroup
Properties:
HostedZoneName: !Sub ${ApexDomainName}.
RecordSets:
- Name: !Ref ApexDomainName
Type: A
AliasTarget:
# Magic AWS number: For CloudFront, use Z2FDTNDATAQYW2.
HostedZoneId: Z2FDTNDATAQYW2
DNSName: !GetAtt WebsiteCdn.DomainName
- Name: !Ref RedirectDomainName
Type: A
AliasTarget:
# Magic AWS number: For CloudFront, use Z2FDTNDATAQYW2.
HostedZoneId: Z2FDTNDATAQYW2
DNSName: !GetAtt CloudFrontDistributionRedirect.DomainName