Part 2 sprouting some website goodness - A practical example for DevOps on AWS

If you've read my first post (and you have, haven't you), you either thought "that's absolute crap, why would I bother" or "hey, that's pretty neat, but what can I do with it". If you were the former, then avert your eyes because this post is targeted firmly at the latter.
In this post I will be covering how to extend an Inception Pipeline to do something useful. In this instance, it is creating the infrastructure to host a single page application. On the projects I'm currently involved with, this is always the first piece of infrastructure we need (well, after first inceptioning up the pipeline).
The obvious first prerequisite is an existing Inception Pipeline. So, if you don't have one, jump across to the original post and create yourself one.
The next prerequisite is to manually create a couple of AWS resources:
us-east-1 region. This is the only region that CloudFront will look for the certificate. So, unless you're creating the stack in us-east-1, you're going to need to create it yourself. This also gives you the option to verify the certificate by email or DNS (email is the only option when it is created via CloudFormation). You can find out more here.HostedZoneId as it is a parameter to the CloudFormation template discussed below.An optional step, at least until September 2017, is to create a DNS CAA record. Having the CAA record helps if you are attempting to get a good grade on services like SSL Labs.
Incidentally, using the CloudFormation template discussed in this post will get you an 'A' grade.
What this template does for you:
403 and 404 errors to the index.html page. This is needed for single page applications (like AngularJS/Angular) that create browser friendly URLs that do not map to S3 files. The high-level flow is the S3 gives 403, CloudFront serves the index.html which kicks off the SPA that reads the URI and starts serving the right content.The files are on the Part 2 branch in the GitHub repository.
| File | Description |
|---|---|
| aws_infrastructure.yml | The magnum opus; the CloudFormation template that makes it all work |
| aws_infrastructure.json | These are the parameters used by the CloudFormation template during execution |
| aws_seed.yml | Gets a new CloudFormation deployment action snippet as described below which executes the aws_infrastructure.yml template. |
Getting started is super simple and easy.
Add the following parameter to your aws_seed.json file. Obviously, you need to replace the value with the CloudFormation stack name of your choosing:
"StageAdministerInfrastructureStackName": "@@StageAdministerInfrastructureStackName@@"
Add the following snippet to the Parameters section of your aws_seed.yml:
StageAdministerInfrastructureStackName:
Type: String
Description: The name of the stack that administers the website infrastructure
Add the following snippet under the AdministerPipeline stage in the CodePipeline resource in aws_seed.yml:
- Name: 'AdministerInfrastructure'
Actions:
- Name: 'AdministerWebsiteInfrastructure'
ActionTypeId:
Category: Deploy
Owner: AWS
Provider: CloudFormation
Version: '1'
Configuration:
ActionMode: REPLACE_ON_FAILURE
RoleArn: !GetAtt [CloudFormationDeployActionRole, Arn]
StackName: !Ref StageAdministerInfrastructureStackName
TemplateConfiguration: !Join ['', [!Ref RepositoryName, 'Source', '::aws_infrastructure.json']]
TemplatePath: !Join ['', [!Ref RepositoryName, 'Source', '::aws_infrastructure.yml']]
InputArtifacts:
- Name: !Join ['', [!Ref RepositoryName, 'Source']]
RunOrder: '10'
Copy the aws_infrastructure.yml and aws_infrastructure.json into the same folder as aws_seed.yml
Replace the parameter values in aws_infrastructure.json with appropriate values.
Commit the changes and push to CodeCommit.
If you sit and watch the pipeline execution, you'll notice its starts executing, realises there is a structural change and then restarts execution from the top. In my not-so-humble opinion, this is one of the best features of an Inception Pipeline; it just manages itself effortlessly.
In this post I covered how you can extend an Inception Pipeline to do something useful. And in the next post, we'll take this idea one step further...