Build static website with Headless CMS, AWS S3, CloudFront and CICD pipeline

In this blog, I will discuss how to build AWS Headless CMS static site using AWS S3 and AWS CloudFront. I will also cover how to automate the end-to-end deployments using a continuous integration and deployment (CICD) pipeline. i highly recommend  Gatsby (or any other headless CMS) for building static sites along with cloud technologies like AWS S3 and CloudFront as they bring significant cost savings along with other advantages to our customers.

AWS S3 with CloudFront offers significant advantages for hosting static websites like Scalability, Cost, Durability, Performance, Caching, and Certificate management. If you are new to headless CMS, you can checkout this link. Let’s get started.

Step-1: Source Code Management

The first step is to create a Git repo to host the source code for our AWS headless CMS site. Create a git repo in Github, BitBucket or any other source control management system of our choice. Implement a Gitflow like branching strategy and pull-requests for code reviews if needed. If there is any interest, I would be happy to share our favourite Git branching pattern in a future blog.

Step-2: Build your Site

Next, we need to setup API integration with backend APIs to fetch content and render it using page templates. The steps will differ based upon the backend technology stack for e.g. Nodejs, Golang, Nuxt.js, Java, or Php. We will discuss high level build steps and focus more on configuration here. The build steps can be run manually for local deployments but they should be executed automatically via CICD pipelines for production environments.

Step-3: S3 for hosting your website

Create a S3 static website to host the AWS headless CMS site. The name of the bucket should match your domain name e.g. coderise.io.

S3 bucket should publicly accessible and static website property should be enabled.

You can make the S3 bucket publicly accessible with all it’s content (use with caution) using this bucket policy:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<BUCKET_NAME_GOES_HERE>/*"
},
{
"Sid": "2",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EXKPOP1AUCSU1"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<BUCKET_NAME_GOES_HERE>/*"
}
]
}

Step-4: AWS Certificate Manager (ACM) for certificates

Create a HTTPS/SSL certificate for the domain using AWS Certificate Manager (ACM). There are some restrictions around regions, so my recommendation would be to select us-east-1 region for CloudFront compatibility.

Step-5: CloudFront for content delivery network

Create a CloudFront distribution pointing, for example

  • Origin: Should point to S3 bucket endpoint. 
  • Root: index.html
  • Domain: coderise.io, www.coderise.io
  • Viewer Protocol Policy: Redirect HTTP to HTTPS

Select rest of the configurations based upon your requirements.

  • Serve Index.html from sub-directory

To ensure that index.html files are served correctly from sub-directories, please make sure the origin points to S3 website endpoint (e.g. coderise.io.s3-website.us-east-1.amazonaws.com) and do not auto-select it from the drop-down. You can get the S3 website endpoint by selecting your bucket and navigating to property section.

Step-6: Route 53 to host DNS

You can host the domain for our AWS Headless CMS site on Route 53 or with any other provider. Create an A record and point it to the CloudFront distribution.

Step-7: CICD pipeline to enable automatic deployments

  • Create a CICD pipeline (you can use Github Actions, Code Pipeline, CircleCi or BitBucket pipelines as well). The pipeline will checkout code, build it using ( Npm build or Gatsby build), connect to AWS and upload the site to S3. This pipeline should auto-trigger based upon a branching and release workflow. Code reviews using pull requests should be integrated in the process for approvals. It’s always a good practice to invalidate CloudFront cache for major releases.

Detailed step on how to setup CICD pipeline is explained in here: https://blog.coderise.io/deploy-react-app-aws-s3-using-github-actions/ 

Step-8: Trigger pipeline

Push a commit to Git repository. This should auto-trigger the CICD pipeline which will build the site and deploy it to S3. The pipeline should also invalidate CloudFront cache for our AWS headless CMS static site.

Step-9: Launch static site using AWS headless CMS site using S3 and CloudFront

Open a browser and you should be able to access the site now. Congrats for launching your new static site using a headless CMS, AWS S3 and served using CloudFront. Announce it to the world by sharing the link on social sites and via other marketing channels.

Hope you enjoyed this blog. Please comment and let us know.