After a week of reading and experimenting with CodePipeline and CodeBuild, I’m back with the second part of the Static Site on AWS Quickstart.
I must say that it was great fun discovering all the capabilities that CodePipeline has to offer, at a certain point during reading the documentation I felt like Alice going down the rabbit hole, it just kept on giving! Besides the docs, a great starting point was How to Do Continuous Integration and Continuous Deployment with AWS Lambda and AWS CodePipeline podcast which covered CI/CD for serverless applications using CodePipeline.
Even though it wasn’t exactly my use-case, it offered a valuable insight into what AWS CodePipeline can do. I just needed to adjust it to my needs. Here’s hoping that I did good!
- You will need to have the infrastructure boilerplate configured as described in Part 1
buildspec.yamlinside your staticsite github repository. See jekyll sample
You can get started by deploying the stack.
If you are not a big fan of launching stacks from the console, you can clone the repo and the
Makefile should provide you with what you need. I recommend keeping the parameters somewhere secure due to the sensitive nature of the github token.
# To create stack make STACK_NAME=staticsite-cd STACK=master PARAM_PATH=`pwd`/parameters REGION=us-west-1 create # To poll for events make STACK_NAME=staticsite-cd STACK=master REGION=us-east-1 watch # To see the stack outputs make STACK_NAME=staticsite-cd STACK=master REGION=us-east-1 output # To update the stack make STACK_NAME=staticsite-cd STACK=master PARAM_PATH=`pwd`/parameters REGION=us-east-1 update # To delete the stack make STACK_NAME=staticsite-cd REGION=us-east-1 delete
The master stack will create 2 stacks.
pipeline-roles.templatecontains the minimum set of roles needed by AWS Services to do the work on your behalf. Soon enough we’ll have service linked roles for every AWS Service, which should greatly simplify or maybe even eliminate this template.
pipeline.templatecontains the CodePipeline definition and custom lambda function for publishing files to s3.
There are 3 mandatory stages:
If you opted for staging environment you will get another stage in between Build and Production, called Staging (I know, very inspired naming)
The Source stage is configured with your github repo token and every time you do a commit, the hook will trigger the pipeline.
version: 0.0 containers: LambdaFunctions: phases: during_build: commands: - gem install jekyll - jekyll build artifacts: files: - _site/**/*
The Staging stage will invoke a lambda function, passing in the
_site.zip artifact and s3 destination. The lambda unpacks the artifact and does an
aws s3 sync with the staging bucket.
There’s an additional
Manual Approval step, which uses SNS to send an e-mail containing a hyperlink to the environment and awaits user response. This should be an IP whitelisted environment where you can validate that the site looks and behaves as you expect it to.
Approve the changes, leaving a comment justifying the action.
If approved, the Production stage will invoke the same lambda but this time with the production bucket as destination.
And Voilà!, your latest changes are live and the best part of it is that everything is automated, no more worrying about aws credentials and syncing up folders. Long live CodePipeline!
Tips & gotchas
Current setup expects that the result of your static site build process defined in buildspec generates a
Depending on which jekyll template you use, the buildspec
commands might also differ slightly, just use the ones that work on your local machine.
PS: If you can see this post, it means that the pipeline works!