Jekyll Blog with Terraform (OpenTofu) Using GitLab Pipelines
In this guide, I will provide a short manual for deploying a static blog, in this case Jekyll (with minor changes, you should be able to make it work for any other static website), to Amazon S3 using GitLab pipelines. All infrastructure will be managed in Terraform (or OpenTofu, as in our case).
This manual assumes that you are using Route 53 as your DNS provider, and all AWS infrastructure will be deployed to the US East (N. Virginia) region. If you want to use a different region, set the aws_region
variable accordingly in blog.tfvars
.
Step 1: Credential Setup and Creating the S3 Bucket
First, we need to set up AWS credentials and ensure that AWS CLI and Terraform (or OpenTofu) are already installed.
I used this manual to install OpenTofu:
Installing OpenTofu on .deb-based Linux
Here is the installation code:
To install Terraform, use this guide:
To install AWS CLI, follow the instructions here:
Installing or updating to the latest version of the AWS CLI
Once the installation is complete, set up your AWS credentials using the profile prod
(you can choose any profile name, but prod
is used for this manual):
After setting up your credentials, verify them by running cat ~/.aws/credentials
— it should return something like:
Test the credentials with the following command to ensure they work:
You should see output similar to:
Now, create the S3 bucket where the Terraform state file will be saved. Keep in mind that this name might already be taken, so use something unique. If you use a different name, make sure to update main.tf
accordingly.:
The output should look something like this:
Step 2: Setup Terraform Code
Most of the Terraform code was taken from the following repository:
GitHub terraform-aws-static-site
The author’s blog post explains in detail what each part of the code does:
pirx.io - Automated Static Site Deployment in AWS Using Terraform
However, I encountered a few issues with this code. First, it was missing the mandatory aws_s3_bucket_ownership_controls
resource. The solution was to add the aws_s3_bucket_ownership_controls
resource and update the aws_s3_bucket_acl
accordingly. Here is the full code snippet for the relevant part:
Additionally, we need to create an IAM user for deploying the blog via the GitLab pipeline. I copied the relevant code from here:
GitHub terraform-aws-s3-static-site
Add this code snippet to outputs.tf
to output the credentials needed for the pipeline:
To make things easier, I’ve consolidated all the code into a single repository:
GitHub jekyll-terraform-aws-s3
I chose to use a monolithic approach instead of modules for simplicity. You just need to set at least the domain
and route53_zone_id
variables in blog.tfvars
and you’re ready to deploy the infrastructure in AWS:
or using Terraform:
Once applied, the output will display variables to use later in the pipeline:
To retrieve sensitive variables, run:
or using Terraform:
Step 3: Setup GitLab Pipeline
The pipeline I use is directly copied from here:
SchenkTech Blog - Hosting a Jekyll Site in S3 Part 2
Since the author didn’t provide a Git repository for the code, I created one myself:
When you fork that repository or copy the files, you will need to set the following variables in GitLab CI/CD settings. Ensure they are masked and protected to safeguard sensitive information:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
CLOUDFRONT_DISTRIBUTION_ID
S3_BUCKET
Next, add your actual Jekyll code to the repository, commit, and push it:
And you’re done! Once the build completes, your website will be deployed, and you should see the Beautiful Jekyll template live.