Update deployment to use cloudfront and s3

Bootstrap the environment using:

./site init-env <stack-name> <cf-bucket> <cnames>

- stack-name :: is the stack name used for the infrastructure bootstrap cloudformation template
- cf-bucket :: is the name of the S3 bucket that holds the cloudformation stack that will bootstrap
the environment
- cnames :: is a comma separated list of domains to be used as CNames with this deployment

Note: this can also be run directly with ./init-env.sh

Once the environment has been bootstraped, the site can be deployed using the variables given
in its output.

AWS_DEFAULT_REGION=<region> \
AWS_ACCESS_KEY_ID=<access-key> \
AWS_SECRET_ACCESS_KEY=<secret-key> \
S3_BUCKET=<s3-bucket> \
./site deploy

Signed-off-by: Collin J. Doering <collin.doering@rekahsoft.ca>
This commit is contained in:
Collin J. Doering 2017-04-23 20:00:30 -04:00
parent 2e3e7c5906
commit e91eba5dfb
Signed by: rekahsoft
GPG Key ID: 7B4DEB93212B3022
4 changed files with 237 additions and 7 deletions

174
blog-rekahsoft.yaml Normal file
View File

@ -0,0 +1,174 @@
AWSTemplateFormatVersion: '2010-09-09'
Description: RekahSoft blog stack
#
# Parameters
#
Parameters:
AlternateURLs:
Type: CommaDelimitedList
Default: ''
Description: A list of URLs that act as aliases for accessing the cloudfront site
PriceClass:
Type: String
AllowedValues: [PriceClass_100, PriceClass_200, PriceClass_All]
Default: PriceClass_100
Description: The cloud front price class to use with the web distribution
#
# Conditions
#
Conditions:
NoAlternateURLs: !Equals [!Join [',', !Ref AlternateURLs], '' ]
#
# Resources
#
Resources:
User:
Type: AWS::IAM::User
AccessKeyUser:
Type: AWS::IAM::AccessKey
Properties:
UserName: !Ref User
S3Bucket:
Type: AWS::S3::Bucket
Properties:
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: error.html
S3BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
PolicyDocument:
Id: S3BucketPolicy
Version: '2012-10-17'
Statement:
- Sid: ListAccess
Action:
- s3:ListBucket
Effect: Allow
Resource: !Join ['', ['arn:aws:s3:::', !Ref S3Bucket]]
Principal:
AWS: !GetAtt User.Arn
- Sid: ReadWriteAccess
Action:
- s3:GetObject
- s3:PutObject
- s3:DeleteObject
Effect: Allow
Resource: !Join ['', ['arn:aws:s3:::', !Ref S3Bucket, '/*']]
Principal:
AWS: !GetAtt User.Arn
- Sid: PublicReadAccess
Action:
- s3:GetObject
Effect: Allow
Resource: !Join ['', ['arn:aws:s3:::', !Ref S3Bucket, '/*']]
Principal: '*'
Bucket: !Ref S3Bucket
LogsBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
PolicyDocument:
Id: LogsBucketPolicy
Version: '2012-10-17'
Statement:
- Sid: ReadWriteAccess
Action:
- s3:GetObject
- s3:PutObject
- s3:DeleteObject
Effect: Allow
Resource: !Join ['', ['arn:aws:s3:::', !Ref LogsBucket, '/*']]
Principal:
AWS: !GetAtt User.Arn
Bucket: !Ref LogsBucket
LogsBucket:
Type: AWS::S3::Bucket
CloudfrontDistribution:
Type: AWS::CloudFront::Distribution
DependsOn:
- S3Bucket
- LogsBucket
Properties:
DistributionConfig:
Origins:
- DomainName: !GetAtt S3Bucket.DomainName # mybucket.s3.amazonaws.com
Id: S3Origin
S3OriginConfig:
OriginAccessIdentity: ''# origin-access-identity/cloudfront/S3Origin
Enabled: true
Comment: Some comment
DefaultRootObject: index.html
Logging:
IncludeCookies: false
Bucket: !GetAtt LogsBucket.DomainName # mylogs.s3.amazonaws.com
Prefix: myprefix
Aliases: !If [NoAlternateURLs, !Ref 'AWS::NoValue', !Ref AlternateURLs ]
CacheBehaviors:
- AllowedMethods:
- GET
- HEAD
- OPTIONS
TargetOriginId: S3Origin
MaxTTL: 0
MinTTL: 0
DefaultTTL: 0
PathPattern: index.html
ForwardedValues:
QueryString: 'false'
Cookies:
Forward: none
# TrustedSigners:
# - 1234567890EX
# - 1234567891EX
ViewerProtocolPolicy: allow-all
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
- OPTIONS
TargetOriginId: S3Origin
ForwardedValues:
QueryString: 'false'
Cookies:
Forward: none
# TrustedSigners:
# - 1234567890EX
# - 1234567891EX
ViewerProtocolPolicy: allow-all
PriceClass: !Ref PriceClass
Restrictions:
GeoRestriction:
RestrictionType: whitelist
Locations:
- CA
ViewerCertificate:
CloudFrontDefaultCertificate: 'true'
#
# Outputs
#
Outputs:
WebAddress:
Value: !GetAtt CloudfrontDistribution.DomainName
S3Bucket:
Value: !Ref S3Bucket
LogsBucket:
Value: !Ref LogsBucket
UserAccessKey:
Value: !Ref AccessKeyUser
UserSecretKey:
Value: !GetAtt AccessKeyUser.SecretAccessKey

53
init-env.sh Executable file
View File

@ -0,0 +1,53 @@
#!/bin/bash
display_help() {
cat <<EOF
Usage: init_env.sh [create|update] <stack-name> <cf-bucket> <cnames>
init_env.sh info <stack-name>
init_env.sh [help|--help|-h]
EOF
}
display_info() {
# Get parameters needed for gitlab-ci.yaml
S3_BUCKET=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query "Stacks[*].Outputs[?OutputKey=='S3Bucket'].OutputValue" --output text)
USER_ACCESS_KEY=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query "Stacks[*].Outputs[?OutputKey=='UserAccessKey'].OutputValue" --output text)
USER_SECRET_KEY=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query "Stacks[*].Outputs[?OutputKey=='UserSecretKey'].OutputValue" --output text)
echo "S3 Bucket: ${S3_BUCKET}"
echo "Access Key: ${USER_ACCESS_KEY}"
echo "Secret Key: ${USER_SECRET_KEY}"
}
# Variables set by the user using cli arguments
OP="$1"
STACK_NAME="$2"
BUCKET="$3"
CNAMES="$4"
case "$OP" in
update|create)
# Push cloudformation template to provided bucket
echo aws s3 cp blog-rekahsoft.yaml "s3://${BUCKET}"
# Create cloudformation stack
echo aws cloudformation "${OP}-stack" --stack-name "$STACK_NAME" --template-url "https://${BUCKET}.s3.amazonaws.com/blog-rekahsoft.yaml" --parameters ParameterKey=AlternateURLs,ParameterValue=\"${CNAMES}\" --capabilities CAPABILITY_IAM
echo aws cloudformation wait stack-update-complete --stack-name "$STACK_NAME"
display_info
;;
info)
display_info
;;
help|--help|-h)
display_help
;;
*)
echo "Invalid operation! See $0 --help"
exit 1
;;
esac
# Exit gracefully
exit 0

15
site
View File

@ -1,6 +1,5 @@
#!/bin/bash
CABAL="/usr/bin/cabal"
CONFIGURE_SITE="configure --enable-tests"
BUILD_SITE="build"
RUN_SITE="run --verbose=0 blog-rekahsoft-ca"
@ -20,18 +19,22 @@ case "$1" in
fi
# Test site
$CABAL $TEST_SITE
cabal $TEST_SITE
;;
clear)
$CABAL clean
cabal clean
;;
configure)
$CABAL $CONFIGURE_SITE
cabal $CONFIGURE_SITE
;;
make)
$CABAL $BUILD_SITE
cabal $BUILD_SITE
;;
init-env)
shift
./init-env.sh "$@"
;;
*)
$CABAL $RUN_SITE "--" "$@"
cabal $RUN_SITE "--" "$@"
;;
esac

View File

@ -92,7 +92,7 @@ pandocWriterOptions = defaultHakyllWriterOptions
myConfig :: Configuration
myConfig = defaultConfiguration
{ deployCommand = "echo '\nDeploying website...' && " ++
"rsync -rpogtzcv --delete -e ssh _site/ collin@rekahsoft.ca:~/public_html/blog/"
"aws s3 sync _site/ s3://$S3_BUCKET"
, previewPort = 3000
}