How to Create, Automate & Deploy a Static Blog Using Publii, AWS(S3, Route53, CloudFront), Terraform & Namecheap Part 1

Photo by SwapnIl Dwivedi on Unsplash

Fo years I have been wanting to create a blog where I can post continuously, cost almost nothing, have global distribution and more important set it and forget it in terms of infrastructure. I have looked into different tech stacks through the years like using hosting companies with Wordpress as the CMS or creating my own HTML/CSS and uploading it to an S3 bucket. But, there are two problems I always run into with these stacks. The first one Is that I have to do a lot of maintenance stuff on Wordpress after sometime; The second one being, if I do a static blog, then it gets cumbersome to keep adding blog posts to the HTML manually.  Well I found a solution that seems to work for me and I want to show how it works. Today I will teach you how to create, automate & deploy a static blog using Publii, AWS(S3, Route53, CloudFront), Terraform & NameCheap.

Architectural Diagram of the services and tools used to create Import Knowledge
Diagram of Tools & Services that makes up Import Knowledge


The architecture is simple enough to maintain using terraform while blog posts and website  is managed by the Publii CMS. I believe that this is a great set up for any blogger that can code or is up to the task and wants to concentrate on its blog content while not worrying about maintenance or costs. Due to all of the detailed tasks this tutorial, it will be split into multiple parts.

Setting up Terraform

Before we start it is assumed that you bought your domain on Namecheap. If not, do so now. You should forward any email sent to your domain as instructed in this article by Namecheap. By doing this you will be able to finish the certificate portion of this tutorial. be aware that Namecheap can take up to a day to forward emails at the beginning when you start forwarding emails.

If you have never used terraform download it from here. After downloading Terraform, unzip the package. Terraform runs as a single binary named terraform. Any other files in the package can be safely removed and Terraform will still function.

Verify that the installation worked by opening a new terminal session and listing Terraform's available subcommands.

$ terraform -help
Usage: terraform [-version] [-help] <command> [args]

The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.

Add any subcommand to terraform -help to learn more about what it does and available options.

$ terraform -help plan

If you use a mac you can enable tab completion for Terraform commands. To enable autocomplete, run the following command and then restart your terminal.

$ terraform -install-autocomplete

Now that Terraform is installed we can proceed with creating our infrastructure code. In order for a website to be available we have to spin up a S3 buckets, use Route53 for DNS, cache the website with CloudFront and serve the content under HTTPS which requires a certificate.

First step is to create the certificate for the domain by creating all of the necessary files needed by Terraform.

provider "aws" {

access_key ="${var.aws_access_key}"

secret_key ="${var.aws_secret_key}"

region ="${var.aws_region}"


This script above should be called the This script is the one that handles all of the login details and which services will Terraform will connect to. In this particular file we are telling terraform that it will connect to the provider AWS and when connecting it will use an access key, secret key and region to work on.

variable "aws_access_key" {}

variable "aws_secret_key" {}

variable "aws_region" {

default ="us-east-1"


variable "domain_name" {

default =""


variable "sub_domain_name" {

default ="*"

This script is called This is where we define the variables used in and other scripts used by Terraform. In this script you are defining the access key, secret key, region and setting it default to us-east-1, domain name and doing a wildcard search on any subdomain as part of your certificate. You might have noticed that the region is in bold in the paragraph. Theres a reason for this:

AWS Certificate Manager can be used to automatically issue SSL certificates for other AWS services, like CloudFront. There's a gotcha, though:

To use an ACM Certificate with CloudFront, you must request or import the certificate in the US East (N. Virginia) region.

Thus, variable "aws_region" {default ="us-east-1"} as the variable value. 

After that we create the code to make the SSL certificate using a module by a third part called Cloudposse. Yes we could have created the entire code ourselves but I found this module very complete and easy to use. Remember to always stand on the shoulders of giants. Which is a metaphor that means "Using the understanding gained by major thinkers who have gone before in order to make intellectual progress".

module "acm_request_certificate" {

source ="git::"

domain_name ="${var.domain_name}"

process_domain_validation_options =true

ttl ="300"

subject_alternative_names =["${var.sub_domain_name}" ]

validation_method ="EMAIL"

 Last thing we have to do is to create a file to store the sensitive data for the access key and secret key. That file will be called terraform.tfvars
aws_access_key = "your access key"

aws_secret_key = "secret key"

This is the file where you input your sensitive access info. I recommend you create a terraform user in your AWS account by using this guide. After creating the user you will be able to fill in the access key and secret key variables in terraform.tfvars
Thats pretty much it in terms of infrastructure code to create an SSL certificate for your website. Now we open our terminal and change directory to wherever you have your terraform code.
The you write:
 terraform init

Now that terraform is initialized we can plan and apply all of the code you wrote before.

The plan output mentions that it will use the AWS API to create an SSL certificate. Everything but the domain name, subdomain and validation method will be set after creation. Once you are ready input terraform apply and then write yes.

If terraform ran successfully you should see it at the end with 1 resource added. Also since the certificate operation was successful you should get an email from AWS that looks like this:


After approval, your SSL certificate has been created and you're first part into this tutorial is done!


 The next part will be to spin up all of the AWS resources to serve future static blog content.