{"id":26229991,"url":"https://github.com/spofibo/terraform-digitalocean-ha-wordpress","last_synced_at":"2026-04-07T09:31:15.354Z","repository":{"id":174155783,"uuid":"437039450","full_name":"Spofibo/terraform-digitalocean-ha-wordpress","owner":"Spofibo","description":"Deploy one or more highly available/load-balanced WordPress websites on DigitalOcean, with a dedicated MySQL cluster via Terraform and Ansible","archived":false,"fork":false,"pushed_at":"2022-02-06T09:13:23.000Z","size":43,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-12T22:18:52.600Z","etag":null,"topics":["ansible","digitalocean","highavailable","loadbalancer","mysql","terraform","wordpress"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Spofibo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-10T16:14:19.000Z","updated_at":"2024-05-16T14:08:12.000Z","dependencies_parsed_at":null,"dependency_job_id":"7312d098-b356-4c19-8760-eb575899246a","html_url":"https://github.com/Spofibo/terraform-digitalocean-ha-wordpress","commit_stats":null,"previous_names":["spofibo/terraform-do-ha-wordpress","spofibo/terraform-digitalocean-ha-wordpress"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spofibo%2Fterraform-digitalocean-ha-wordpress","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spofibo%2Fterraform-digitalocean-ha-wordpress/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spofibo%2Fterraform-digitalocean-ha-wordpress/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spofibo%2Fterraform-digitalocean-ha-wordpress/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Spofibo","download_url":"https://codeload.github.com/Spofibo/terraform-digitalocean-ha-wordpress/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243301225,"owners_count":20269317,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","digitalocean","highavailable","loadbalancer","mysql","terraform","wordpress"],"created_at":"2025-03-12T22:18:54.770Z","updated_at":"2025-12-30T21:46:20.583Z","avatar_url":"https://github.com/Spofibo.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Highly available WordPress sites on DigitalOcean with Terraform and Ansible\n\nThis repository contains [Terraform](https://www.terraform.io/) and [Ansible](https://www.ansible.com/) configurations to launch and configure the infrastructure on DigitalOcean, and will create the following infrastructure using Terraform:\n\n- One private VPC\n- Two 1 GB Droplets in the FRA1 datacenter running Ubuntu 21.10\n- One managed MySQL cluster with two DBs and two users\n- One DigitalOcean Load Balancer to route HTTPS traffic to the Droplets\n- One DigitalOcean Cloud Firewall to lock down communication between the Droplets and the outside world\n\nWe will then use Ansible to run the following tasks on both Droplets:\n\n- Update all packages\n- Install the DigitalOcean monitoring agent, to enable resource usage graphs in the Control Panel\n- Install the Nginx web server software\n- Install a demo `index.html` that shows Sammy and the Droplet's hostname\n\n\n## Prerequisites\n\n- **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](https://www.digitalocean.com/community/tutorials/how-to-use-ssh-keys-with-digitalocean-droplets).\n- **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](https://www.digitalocean.com/community/tutorials/how-to-use-the-digitalocean-api-v2)\n\nWhen you have the software, an SSH key, and an API token, proceed to the first step.\n\n\n## Step 1 — Clone the Repository and Configure\n\nFirst, download the repository to your local computer using `git clone`, and enter the directory:\n\n```shell\n$ git clone https://github.com/Spofibo/terraform-do-ha-wordpress.git\n$ cd terraform-do-ha-wordpress\n```\n\nWe 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.\n\nThen, copy the example file to to a new file, removing the `.example` extension:\n\n```shell\n$ cp terraform.tfvars.example terraform.tfvars\n```\n\nOpen the new file in your favorite text editor, and update the content of the variables with your parameters:\n\n```\ndo_token = \"\"\nssh_fingerprint = \"\"\n```\n\nFill in each variable:\n\n- **do_token:** is your personal access token for the DigitalOcean API\n- **ssh_fingerprint:** the DigitalOcean API refers to SSH keys using their _fingerprint_, which is a shorthand identifier based on the key itself.\n\n  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:\n\n  ```\n  $ ssh-keygen -E md5 -lf ~/.ssh/id_rsa.pub | awk '{print $2}'\n  ```\n\n  The output will be similar to this:\n\n  ```\n  MD5:ac:eb:de:c1:95:18:6f:d5:58:55:05:9c:51:d0:e8:e3\n  ```\n\n  **Copy everything _except_ the initial `MD5:`** and paste it into the variable.\n\nNow we can initialize Terraform. This will download some information for the DigitalOcean Terraform _provider_, and check our configuration for errors.\n\n```\n$ terraform init\n```\n\nYou should get some output about initializing plugins. Now we're ready to provision the infrastructure and configure it.\n\n\n## Step 2 — Run Terraform and Ansible\n\nWe can provision the infrastructure with the following command:\n\n```\n$ terraform apply\n```\n\nTerraform 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).\n\nIf all looks well, type `yes` to proceed.\n\nTerraform 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:\n\n```\nApply complete! Resources: 5 added, 0 changed, 0 destroyed.\n\nOutputs:\n\nwordpress_lb_ip = 203.0.113.11\n```\n\nThis 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!\n\nLet's fix that by running Ansible to finish setting up the servers:\n\n```\n$ cd ansible/\n$ ansible-galaxy install -r requirements.yaml\n$ ansible-playbook -i inventory playbook.yaml\n```\n\nAnsible 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.\n\nGo 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:\n\n![Demo web page with Sammy the shark and a hostname](https://assets.digitalocean.com/articles/tf-ansible-demo/demo-page.png)\n\nIf 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).\n\nTake 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:\n\n![DigitalOcean load balancer interface ](https://assets.digitalocean.com/articles/tf-ansible-demo/load-balancer.png)\n\nIn 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:\n\n![DigitalOcean firewall rules interface](https://assets.digitalocean.com/articles/tf-ansible-demo/firewall.png)\n\nWhen you're done exploring, you can destroy all of the demo infrastructure using Terraform:\n\n```\n$ terraform destroy\n```\n\nThis 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.\n\n## TODO\n- Move this list to GH issues\n- README\n  - Refine docs\n  - Add architecture diagram\n- Terraform\n  - Combine with Packer to build hardened images ans use them as base\n- Ansible\n  - Cron for cloudflare script\n  - Valid self-signed ssl cert for Nginx\n  - NFS for wp-content to be shared between droplets\n    - How to address scaling up and down, in regards to the registration/deregistration of nodes?\n  - Install \u0026 use wp-cli to install sites\n  - Move sections from playbook to their individual roles\n  - Simplify PHP configuration by removing external dependency or disabling some parts of it (i.e. apache stuff)\n  - Create different linux user for each website\n- CI/CD (GH Actions) ?\n  - Separate into two envs (dev \u0026 prod)\n  - Build a hardened image from https://github.com/Spofibo/packer-build-hardened-images\n  - \n\n\u003c!-- BEGIN_TF_DOCS --\u003e\n## Requirements\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"requirement_terraform\"\u003e\u003c/a\u003e [terraform](#requirement\\_terraform) | \u003e= 1.0.0 |\n| \u003ca name=\"requirement_digitalocean\"\u003e\u003c/a\u003e [digitalocean](#requirement\\_digitalocean) | ~\u003e 2.16 |\n\n## Providers\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"provider_digitalocean\"\u003e\u003c/a\u003e [digitalocean](#provider\\_digitalocean) | 2.16.0 |\n| \u003ca name=\"provider_http\"\u003e\u003c/a\u003e [http](#provider\\_http) | 2.1.0 |\n| \u003ca name=\"provider_local\"\u003e\u003c/a\u003e [local](#provider\\_local) | 2.1.0 |\n\n## Modules\n\nNo modules.\n\n## Resources\n\n| Name | Type |\n|------|------|\n| [digitalocean_database_cluster.mysql](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/database_cluster) | resource |\n| [digitalocean_database_db.website1](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/database_db) | resource |\n| [digitalocean_database_db.website2](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/database_db) | resource |\n| [digitalocean_database_firewall.mysql](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/database_firewall) | resource |\n| [digitalocean_database_user.website1](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/database_user) | resource |\n| [digitalocean_database_user.website2](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/database_user) | resource |\n| [digitalocean_droplet.wordpress](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/droplet) | resource |\n| [digitalocean_firewall.wordpress](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/firewall) | resource |\n| [digitalocean_loadbalancer.wordpress](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/loadbalancer) | resource |\n| [digitalocean_vpc.this](https://registry.terraform.io/providers/digitalocean/digitalocean/latest/docs/resources/vpc) | resource |\n| [local_file.ansible_inventory](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file) | resource |\n| [http_http.myip](https://registry.terraform.io/providers/hashicorp/http/latest/docs/data-sources/http) | data source |\n\n## Inputs\n\n| Name | Description | Type | Default | Required |\n|------|-------------|------|---------|:--------:|\n| \u003ca name=\"input_do_token\"\u003e\u003c/a\u003e [do\\_token](#input\\_do\\_token) | n/a | `string` | n/a | yes |\n| \u003ca name=\"input_name_prefix\"\u003e\u003c/a\u003e [name\\_prefix](#input\\_name\\_prefix) | n/a | `string` | `\"terraform2\"` | no |\n| \u003ca name=\"input_region\"\u003e\u003c/a\u003e [region](#input\\_region) | n/a | `string` | `\"fra1\"` | no |\n| \u003ca name=\"input_ssh_fingerprint\"\u003e\u003c/a\u003e [ssh\\_fingerprint](#input\\_ssh\\_fingerprint) | n/a | `string` | n/a | yes |\n\n## Outputs\n\n| Name | Description |\n|------|-------------|\n| \u003ca name=\"output_wordpress_lb_ip\"\u003e\u003c/a\u003e [wordpress\\_lb\\_ip](#output\\_wordpress\\_lb\\_ip) | n/a |\n\u003c!-- END_TF_DOCS --\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspofibo%2Fterraform-digitalocean-ha-wordpress","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspofibo%2Fterraform-digitalocean-ha-wordpress","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspofibo%2Fterraform-digitalocean-ha-wordpress/lists"}