commit
a338ef4d47
|
@ -0,0 +1,62 @@
|
||||||
|
version: 2
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
docker:
|
||||||
|
- image: circleci/golang:latest
|
||||||
|
environment:
|
||||||
|
HUGO_VERSION: "0.53"
|
||||||
|
S3DEPLOY_VERSION: "2.3.0"
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- install-v1-{{ checksum ".circleci/config.yml" }}
|
||||||
|
- install-v1-
|
||||||
|
- run:
|
||||||
|
name: Make bin folder
|
||||||
|
command: mkdir -p $HOME/bin
|
||||||
|
- run:
|
||||||
|
name: Install Hugo
|
||||||
|
command: ./deploy/ci-install-hugo.sh
|
||||||
|
- run:
|
||||||
|
name: Install s3deploy
|
||||||
|
command: ./deploy/ci-install-s3deploy.sh
|
||||||
|
- save_cache:
|
||||||
|
key: install-v1-{{ checksum ".circleci/config.yml" }}
|
||||||
|
paths:
|
||||||
|
- /home/circleci/bin
|
||||||
|
- run:
|
||||||
|
name: Hugo Build
|
||||||
|
command: $HOME/bin/hugo -v --destination workspace/public
|
||||||
|
- persist_to_workspace:
|
||||||
|
root: workspace
|
||||||
|
paths:
|
||||||
|
- public
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
docker:
|
||||||
|
- image: circleci/golang:latest
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- install-v1-{{ checksum ".circleci/config.yml" }}
|
||||||
|
- install-v1-
|
||||||
|
- attach_workspace:
|
||||||
|
at: workspace
|
||||||
|
- run:
|
||||||
|
name: Deploy to S3
|
||||||
|
command: $HOME/bin/s3deploy -source=workspace/public/ -bucket=$BUCKET -region=$REGION
|
||||||
|
|
||||||
|
workflows:
|
||||||
|
version: 2
|
||||||
|
build:
|
||||||
|
jobs:
|
||||||
|
- build
|
||||||
|
- deploy:
|
||||||
|
requires:
|
||||||
|
- build
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- ga-cf-templates
|
|
@ -1,7 +1,6 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*~
|
*~
|
||||||
public
|
public
|
||||||
deploy
|
|
||||||
.*.swp
|
.*.swp
|
||||||
node_modules
|
node_modules
|
||||||
*.log
|
*.log
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
routes:
|
||||||
|
- route: "^.+\\.(js|css|svg|ttf|png|jpg)$"
|
||||||
|
# cache static assets for 20 years
|
||||||
|
headers:
|
||||||
|
Cache-Control: "max-age=630720000, no-transform, public"
|
||||||
|
gzip: true
|
||||||
|
- route: "^.+\\.(html|xml|json|js)$"
|
||||||
|
gzip: true
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Deploying the InfluxData Docs
|
||||||
|
|
||||||
|
Use the following command to deploy a CloudFormation stack using the template in this directory.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
aws cloudformation deploy \
|
||||||
|
--template-file docs-website.yml \
|
||||||
|
--stack-name="${STACK_NAME}" \
|
||||||
|
--capabilities CAPABILITY_IAM /
|
||||||
|
--no-execute-changeset \
|
||||||
|
--parameter-overrides \
|
||||||
|
AcmCertificateArn="${ACM_ARN}" \
|
||||||
|
DomainName="${DOMAIN_NAME}"
|
||||||
|
```
|
||||||
|
|
||||||
|
The `--no-execute-changeset` option will display the actions that will be taken. Remove the `--no-execute-changeset` option to actually deploy a change.
|
|
@ -0,0 +1,11 @@
|
||||||
|
HUGO_DOWNLOAD=hugo_extended_${HUGO_VERSION}_Linux-64bit.tar.gz
|
||||||
|
|
||||||
|
set -x
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Install Hugo if not already cached or upgrade an old version.
|
||||||
|
if [ ! -e $HOME/bin/hugo ] || ! [[ `$HOME/bin/hugo version` =~ v${HUGO_VERSION} ]]; then
|
||||||
|
wget https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/${HUGO_DOWNLOAD}
|
||||||
|
tar xvzf ${HUGO_DOWNLOAD} hugo
|
||||||
|
mv hugo $HOME/bin/hugo
|
||||||
|
fi
|
|
@ -0,0 +1,11 @@
|
||||||
|
S3DEPLOY_DOWNLOAD=s3deploy_${S3DEPLOY_VERSION}_Linux-64bit.tar.gz
|
||||||
|
|
||||||
|
set -x
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Install s3deploy if not already cached or upgrade an old version.
|
||||||
|
if [ ! -e $HOME/bin/s3deploy ] || ! [[ `$HOME/bin/s3deploy -V` =~ ${S3DEPLOY_VERSION} ]]; then
|
||||||
|
wget https://github.com/bep/s3deploy/releases/download/v${S3DEPLOY_VERSION}/${S3DEPLOY_DOWNLOAD}
|
||||||
|
tar xvzf ${S3DEPLOY_DOWNLOAD} s3deploy
|
||||||
|
mv s3deploy $HOME/bin/s3deploy
|
||||||
|
fi
|
|
@ -0,0 +1,230 @@
|
||||||
|
###############################################################################
|
||||||
|
### AWS Cloudformation Template
|
||||||
|
### InfluxData Documentation Website Hosting and Deployment
|
||||||
|
###############################################################################
|
||||||
|
AWSTemplateFormatVersion: 2010-09-09
|
||||||
|
Description: >
|
||||||
|
Cloudformation template to stand up the AWS resources for hosting the
|
||||||
|
InfluxData documentation static website created using Hugo. Cloudfront
|
||||||
|
distribution is used to cache requests to an S3 bucket configured as a static
|
||||||
|
website. A Lambda@Edge function rewrites requests with paths ending in
|
||||||
|
index.html and requests to old v1 docs endpoints, which reside in a second
|
||||||
|
bucket. Finally, a lambda is used to generate new versions of the docs using
|
||||||
|
the GitHub source based on event and webhook triggers.
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
Parameters:
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
AcmCertificateArn:
|
||||||
|
Type: String
|
||||||
|
Description: >
|
||||||
|
The ARN of the SSL certificate to use for the CloudFront distribution.
|
||||||
|
|
||||||
|
DomainName:
|
||||||
|
Type: String
|
||||||
|
Description: The website domain name.
|
||||||
|
Default: dev.docs.influxdata.com
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
Outputs:
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
DocsProdBucketArn:
|
||||||
|
Description: The ARN of the S3 bucket hosting the static content.
|
||||||
|
Value: !GetAtt DocsV2Bucket.Arn
|
||||||
|
Export:
|
||||||
|
Name: !Sub ${AWS::StackName}-bucket-arn
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
Resources:
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
DocsCloudFrontDistribution:
|
||||||
|
Type: AWS::CloudFront::Distribution
|
||||||
|
Properties:
|
||||||
|
DistributionConfig:
|
||||||
|
Aliases:
|
||||||
|
- !Ref DomainName
|
||||||
|
DefaultCacheBehavior:
|
||||||
|
Compress: true
|
||||||
|
ForwardedValues:
|
||||||
|
QueryString: false
|
||||||
|
TargetOriginId: !Ref DocsV2Bucket
|
||||||
|
ViewerProtocolPolicy: redirect-to-https
|
||||||
|
LambdaFunctionAssociations:
|
||||||
|
- EventType: origin-request
|
||||||
|
LambdaFunctionARN: !Ref DocsOriginRequestRewriteLambdaVersion
|
||||||
|
DefaultRootObject: index.html
|
||||||
|
CustomErrorResponses:
|
||||||
|
- ErrorCachingMinTTL: 300
|
||||||
|
ErrorCode: 403
|
||||||
|
ResponseCode: 404
|
||||||
|
ResponsePagePath: /404.html
|
||||||
|
Enabled: true
|
||||||
|
HttpVersion: http2
|
||||||
|
Origins:
|
||||||
|
- DomainName:
|
||||||
|
!Join [ "", [ !Ref DocsV2Bucket, ".s3.amazonaws.com" ] ]
|
||||||
|
Id: !Ref DocsV2Bucket
|
||||||
|
S3OriginConfig:
|
||||||
|
OriginAccessIdentity:
|
||||||
|
!Join [ "", [ "origin-access-identity/cloudfront/", !Ref DocsCloudFrontOriginAccessIdentity ] ]
|
||||||
|
- DomainName:
|
||||||
|
!Join [ "", [ !Ref DocsV1Bucket, ".s3.amazonaws.com" ] ]
|
||||||
|
Id: !Ref DocsV1Bucket
|
||||||
|
S3OriginConfig:
|
||||||
|
OriginAccessIdentity:
|
||||||
|
!Join [ "", [ "origin-access-identity/cloudfront/", !Ref DocsCloudFrontOriginAccessIdentity ] ]
|
||||||
|
PriceClass: PriceClass_200
|
||||||
|
ViewerCertificate:
|
||||||
|
AcmCertificateArn: !Ref AcmCertificateArn
|
||||||
|
MinimumProtocolVersion: TLSv1.1_2016
|
||||||
|
SslSupportMethod: sni-only
|
||||||
|
Tags:
|
||||||
|
- Key: Domain
|
||||||
|
Value: !Ref DomainName
|
||||||
|
|
||||||
|
DocsCloudFrontOriginAccessIdentity:
|
||||||
|
Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
|
||||||
|
Properties:
|
||||||
|
CloudFrontOriginAccessIdentityConfig:
|
||||||
|
Comment: !Sub 'CloudFront Origin Access Identity for ${DomainName}'
|
||||||
|
|
||||||
|
DocsV2Bucket:
|
||||||
|
Type: AWS::S3::Bucket
|
||||||
|
Properties:
|
||||||
|
BucketEncryption:
|
||||||
|
ServerSideEncryptionConfiguration:
|
||||||
|
-
|
||||||
|
ServerSideEncryptionByDefault:
|
||||||
|
SSEAlgorithm: AES256
|
||||||
|
Tags:
|
||||||
|
- Key: Domain
|
||||||
|
Value: !Ref DomainName
|
||||||
|
|
||||||
|
DocsV2BucketPolicy:
|
||||||
|
Type: AWS::S3::BucketPolicy
|
||||||
|
Properties:
|
||||||
|
Bucket: !Ref DocsV2Bucket
|
||||||
|
PolicyDocument:
|
||||||
|
Statement:
|
||||||
|
-
|
||||||
|
Action:
|
||||||
|
- s3:GetObject
|
||||||
|
Effect: Allow
|
||||||
|
Resource: !Join [ "", [ "arn:aws:s3:::", !Ref DocsV2Bucket, "/*" ] ]
|
||||||
|
Principal:
|
||||||
|
CanonicalUser: !GetAtt DocsCloudFrontOriginAccessIdentity.S3CanonicalUserId
|
||||||
|
|
||||||
|
DocsV1Bucket:
|
||||||
|
Type: AWS::S3::Bucket
|
||||||
|
Properties:
|
||||||
|
BucketEncryption:
|
||||||
|
ServerSideEncryptionConfiguration:
|
||||||
|
-
|
||||||
|
ServerSideEncryptionByDefault:
|
||||||
|
SSEAlgorithm: AES256
|
||||||
|
Tags:
|
||||||
|
- Key: Domain
|
||||||
|
Value: !Ref DomainName
|
||||||
|
|
||||||
|
DocsV1BucketPolicy:
|
||||||
|
Type: AWS::S3::BucketPolicy
|
||||||
|
Properties:
|
||||||
|
Bucket: !Ref DocsV1Bucket
|
||||||
|
PolicyDocument:
|
||||||
|
Statement:
|
||||||
|
-
|
||||||
|
Action:
|
||||||
|
- s3:GetObject
|
||||||
|
Effect: Allow
|
||||||
|
Resource: !Join [ "", [ "arn:aws:s3:::", !Ref DocsV1Bucket, "/*" ] ]
|
||||||
|
Principal:
|
||||||
|
CanonicalUser: !GetAtt DocsCloudFrontOriginAccessIdentity.S3CanonicalUserId
|
||||||
|
|
||||||
|
DocsOriginRequestRewriteLambda:
|
||||||
|
Type: AWS::Lambda::Function
|
||||||
|
Properties:
|
||||||
|
Description: >
|
||||||
|
Lambda function performing request URI rewriting.
|
||||||
|
Code:
|
||||||
|
ZipFile: |
|
||||||
|
const config = {
|
||||||
|
suffix: '.html',
|
||||||
|
appendToDirs: 'index.html',
|
||||||
|
removeTrailingSlash: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const regexSuffixless = /\/[^/.]+$/; // e.g. "/some/page" but not "/", "/some/" or "/some.jpg"
|
||||||
|
const regexTrailingSlash = /.+\/$/; // e.g. "/some/" or "/some/page/" but not root "/"
|
||||||
|
|
||||||
|
exports.handler = function handler(event, context, callback) {
|
||||||
|
const { request } = event.Records[0].cf;
|
||||||
|
const { uri } = request;
|
||||||
|
const { suffix, appendToDirs, removeTrailingSlash } = config;
|
||||||
|
|
||||||
|
// Append ".html" to origin request
|
||||||
|
if (suffix && uri.match(regexSuffixless)) {
|
||||||
|
request.uri = uri + suffix;
|
||||||
|
callback(null, request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append "index.html" to origin request
|
||||||
|
if (appendToDirs && uri.match(regexTrailingSlash)) {
|
||||||
|
request.uri = uri + appendToDirs;
|
||||||
|
callback(null, request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redirect (301) non-root requests ending in "/" to URI without trailing slash
|
||||||
|
if (removeTrailingSlash && uri.match(/.+\/$/)) {
|
||||||
|
const response = {
|
||||||
|
// body: '',
|
||||||
|
// bodyEncoding: 'text',
|
||||||
|
headers: {
|
||||||
|
'location': [{
|
||||||
|
key: 'Location',
|
||||||
|
value: uri.slice(0, -1)
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
status: '301',
|
||||||
|
statusDescription: 'Moved Permanently'
|
||||||
|
};
|
||||||
|
callback(null, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If nothing matches, return request unchanged
|
||||||
|
callback(null, request);
|
||||||
|
};
|
||||||
|
Handler: index.handler
|
||||||
|
MemorySize: 128
|
||||||
|
Role: !Sub ${DocsOriginRequestRewriteLambdaRole.Arn}
|
||||||
|
Runtime: nodejs8.10
|
||||||
|
Tags:
|
||||||
|
- Key: Domain
|
||||||
|
Value: !Ref DomainName
|
||||||
|
|
||||||
|
DocsOriginRequestRewriteLambdaVersion:
|
||||||
|
Type: AWS::Lambda::Version
|
||||||
|
Properties:
|
||||||
|
FunctionName: !Ref DocsOriginRequestRewriteLambda
|
||||||
|
Description: !Sub "URL rewriting for ${DomainName}"
|
||||||
|
|
||||||
|
DocsOriginRequestRewriteLambdaRole:
|
||||||
|
Type: AWS::IAM::Role
|
||||||
|
Properties:
|
||||||
|
AssumeRolePolicyDocument:
|
||||||
|
Version: 2012-10-17
|
||||||
|
Statement:
|
||||||
|
- Effect: Allow
|
||||||
|
Principal:
|
||||||
|
Service:
|
||||||
|
- edgelambda.amazonaws.com
|
||||||
|
- lambda.amazonaws.com
|
||||||
|
Action:
|
||||||
|
- sts:AssumeRole
|
||||||
|
ManagedPolicyArns:
|
||||||
|
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
|
Loading…
Reference in New Issue