How to setup a HA Hugo Stack with AWS, Terraform, Ansible, Docker Swarm, Nginx, Traefik & EBS
So I decided to finally setup my hugo blog to share my journey through programming and systems administration, to do so I decided I would require some form of redundancy; if one server for some reason fails or goes offline, I wouldn’t want my whole website to go with it, on the other hand I have already been running a Docker Swarm cluster for various other projects so deploying it would be a breeze, however I wanted to demonstrate my journey and share how you too can setup your own redundant hugo site!
Prerequisites
- An AWS account (or any other cloud provider, take note the code I share here is written for deployment with AWS)
- Terraform installed on your machine
- Ansible installed on your machine
- VS Code or any other text editor for editing a small amount of code
- A domain name
Step 1: Getting setup
First of all I have stored all the code for this project over at my Github so first go ahead and clone that to wherever you wish on your machine
git clone https://github.com/tmclo/hugo-stack.git
Once you have done that, you should be able to open the main.tf
file, we will need to potentially edit
a few things in here before we can setup our infrastructure
At the very top of the file look for line 11
and edit the shared_credentials_file
location, you must
set the file path to the location on your disk where your AWS keys are located, this enables us to
communicate with AWS and deploy the infrastructure.
Next, take a look at line 14
, you will need to change the public_key
location to the area where your
public SSH key is stored on your disk.
Once we have done the following, we’re good to go, however this configuration I have provided only
created 2 AWS A1.medium instances, if you wish to add more, you should copy and modify the
aws_instance.docker2
block and update it accordingly, you must also copy and paste the
aws_volume_attachment.ebs_att2
and update it so that it attached the EBS volume to your additional
instances.
Assuming all is in order, we’re ready to start deploying our infrastructure!
Run the following command to initialise Terraform,
terraform init
This command must be run in the same directory as our project, so please ensure you have a terminal opened in the correct directory before hand!
Next, lets check what changes we’re going to make before actually potentially causing any damage, we can do this using the plan command as follows,
terraform plan
Check over everything on the output of this command before continuing, we don’t want to accidentally destroy something we’re not supposed to!
Next, let’s fire up the infrastructure ready for setting up our cluster! Run the following command and confirm when asked to do so :)
terraform apply
This might take a while but right now is the perfect time for a coffee while we wait for our infrastructure to be deployed!
Once thats complete we’re done with Terraform! we can now move on to using Ansible to actually deploy our project!
Step 2: Deploy the swarm with Ansible
Now before we get started with ansible, have you noticed we have a new file named ips
that was created
during the terraform process?
Good! This file contains all the ips for our instances, a good rule of thumb is to place the ip on the
first line of this file as our “manager” node and the remaining ips below that into the “workers”
section of our hosts file
Once you’ve updated the hosts file accordingly we’re ready to fire up ansible and get our docker swarm setup
To do this we will be running the following command
ansible-playbook -i hosts -u ubuntu --private-key "~/.ssh/id_ed25519" docker-swarm.yml
Take extra note of the --private-key
section in this command, you will need to update that with the
correct location of your SSH PRIVATE KEY.
Once you have set the correct location of your private key we’re ready to press return and wait for the successful deployment of our docker swarm, this will configure each node in the swarm and initialise all the connections required for the swarm, we don’t even need to login!
Now that ansible has completed, you should be able to login to the first (manager) node and type the following command:
docker node ls
Provided that ansible has successfully setup the swarm you should see all the nodes that we created earlier listed in the output, this means our swarm is working!
Step 3: Deploy the Hugo stack with ansible
Now that we have a docker swarm setup successfully we can now instruct Ansible to login to our manager
node for us and setup the entire Hugo cluster, to do this we first need to modify a few things in the
docker-compose.yml
file
However to speed things up, we can just run the following command first leaving only two things to update in our docker compose file,
sed -i 's/example.com/new-domain.com/g' docker-compose.yml
This command looks for the occurance of “example.com” and changes it to our actual domain.
Once we’ve done that we need to edit the file and look for the sections where we need to edit out cloudflare API details
Look for the following,
- CLOUDFLARE EMAIL
- CLOUDFLARE DNS API
Once these are updated we’re ready to deploy our cluster by running the following command,
ansible-playbook -i hosts -u ubuntu --private-key "~/.ssh/id_ed25519" docker-deploy.yml
Once that’s finished you should be left with a fully functional Hugo stack on your brand new docker swarm cluster!
Thank you for reading!