This repository contains Terraform and Ansible configurations to launch and configure the infrastructure on DigitalOcean, and will create the following infrastructure using Terraform:
- One private VPC
- Two 1 GB Droplets in the FRA1 datacenter running Ubuntu 21.10
- One managed MySQL cluster with two DBs and two users
- One DigitalOcean Load Balancer to route HTTPS traffic to the Droplets
- One DigitalOcean Cloud Firewall to lock down communication between the Droplets and the outside world
We will then use Ansible to run the following tasks on both Droplets:
- Update all packages
- Install the DigitalOcean monitoring agent, to enable resource usage graphs in the Control Panel
- Install the Nginx web server software
- Install a demo
index.html
that shows Sammy and the Droplet's hostname
- An SSH key set up on your local computer, with the public key uploaded to the DigitalOcean Control Panel. You can find out how to do that using our tutorial How To Use SSH Keys with DigitalOcean Droplets.
- A personal access token for the DigitalOcean API. You can find out more about the API and how to generate a token by reading How To Use the DigitalOcean API v2
When you have the software, an SSH key, and an API token, proceed to the first step.
First, download the repository to your local computer using git clone
, and enter the directory:
$ git clone https://github.com/Spofibo/terraform-do-ha-wordpress.git
$ cd terraform-do-ha-wordpress
We need to update a few variables to let Terraform know about our keys and tokens. Terraform will look for variables in any .tfvars
file. An example file is included in the repo.
Then, copy the example file to to a new file, removing the .example
extension:
$ cp terraform.tfvars.example terraform.tfvars
Open the new file in your favorite text editor, and update the content of the variables with your parameters:
do_token = ""
ssh_fingerprint = ""
Fill in each variable:
-
do_token: is your personal access token for the DigitalOcean API
-
ssh_fingerprint: the DigitalOcean API refers to SSH keys using their fingerprint, which is a shorthand identifier based on the key itself.
To get the fingerprint for your key, run the following command, being sure to update the path (currently
~/.ssh/id_rsa.pub
) to the key you're using with DigitalOcean, if necessary:$ ssh-keygen -E md5 -lf ~/.ssh/id_rsa.pub | awk '{print $2}'
The output will be similar to this:
MD5:ac:eb:de:c1:95:18:6f:d5:58:55:05:9c:51:d0:e8:e3
Copy everything except the initial
MD5:
and paste it into the variable.
Now we can initialize Terraform. This will download some information for the DigitalOcean Terraform provider, and check our configuration for errors.
$ terraform init
You should get some output about initializing plugins. Now we're ready to provision the infrastructure and configure it.
We can provision the infrastructure with the following command:
$ terraform apply
Terraform will figure out the current state of your infrastructure, and what changes it needs to make to satisfy the configuration in terraform.tf
. In this case, it should show that it's creating two Droplets, a load balancer, a firewall, and a null_resource (this is used to create the inventory
file for Ansible).
If all looks well, type yes
to proceed.
Terraform will give frequent status updates as it launches infrastructure. Eventually, it will complete and you'll be returned to your command line prompt. Take note of the IP that Terraform outputs at the end:
Apply complete! Resources: 5 added, 0 changed, 0 destroyed.
Outputs:
wordpress_lb_ip = 203.0.113.11
This is the IP of your new load balancer. If you navigate to it in your browser, you'll get an error: the Droplets aren't serving anything yet!
Let's fix that by running Ansible to finish setting up the servers:
$ cd ansible/
$ ansible-galaxy install -r requirements.yaml
$ ansible-playbook -i inventory playbook.yaml
Ansible will output some status information as it works through the tasks we've defined in ansible.yml
. When it's done, the two Droplets will both be serving a unique web page that shows the hostname of the server.
Go back to your browser and enter the load balancer IP again. It may take a few moments to start working, as the load balancer needs to run some health checks before putting the Droplets back into its round-robin rotation. After a minute or so the demo web page with Sammy the shark will load:
If you refresh the page, you'll see the hostname toggle back and forth as the load balancer distributes the requests between both backend servers (some browsers cache more heavily than others, so you may have to hold SHIFT
while refreshing to actually send a new request to the load balancer).
Take some time to browse around the DigitalOcean Control Panel to see what you've set up. Notice the two Droplets, demo-01
and demo-02
in your Droplets listing. Navigate to the Networking section and take a look at the demo-lb
load balancer:
In the Firewalls tab, you can investigate the demo-firewall
entry. Notice how the Droplets are set up to only accept web traffic from the load balancer:
When you're done exploring, you can destroy all of the demo infrastructure using Terraform:
$ terraform destroy
This will delete everything we've setup. Or, you could build upon this configuration to deploy your own web site or application! Read on for suggestions of further resources that might help.
- Move this list to GH issues
- README
- Refine docs
- Add architecture diagram
- Terraform
- Combine with Packer to build hardened images ans use them as base
- Ansible
- Cron for cloudflare script
- Valid self-signed ssl cert for Nginx
- NFS for wp-content to be shared between droplets
- How to address scaling up and down, in regards to the registration/deregistration of nodes?
- Install & use wp-cli to install sites
- Move sections from playbook to their individual roles
- Simplify PHP configuration by removing external dependency or disabling some parts of it (i.e. apache stuff)
- Create different linux user for each website
- CI/CD (GH Actions) ?
- Separate into two envs (dev & prod)
- Build a hardened image from https://github.com/Spofibo/packer-build-hardened-images
Name | Version |
---|---|
terraform | >= 1.0.0 |
digitalocean | ~> 2.16 |
Name | Version |
---|---|
digitalocean | 2.16.0 |
http | 2.1.0 |
local | 2.1.0 |
No modules.
Name | Type |
---|---|
digitalocean_database_cluster.mysql | resource |
digitalocean_database_db.website1 | resource |
digitalocean_database_db.website2 | resource |
digitalocean_database_firewall.mysql | resource |
digitalocean_database_user.website1 | resource |
digitalocean_database_user.website2 | resource |
digitalocean_droplet.wordpress | resource |
digitalocean_firewall.wordpress | resource |
digitalocean_loadbalancer.wordpress | resource |
digitalocean_vpc.this | resource |
local_file.ansible_inventory | resource |
http_http.myip | data source |
Name | Description | Type | Default | Required |
---|---|---|---|---|
do_token | n/a | string |
n/a | yes |
name_prefix | n/a | string |
"terraform2" |
no |
region | n/a | string |
"fra1" |
no |
ssh_fingerprint | n/a | string |
n/a | yes |
Name | Description |
---|---|
wordpress_lb_ip | n/a |