Reading Time: 9 minutes

Deploying and managing a robust WordPress website on cloud platforms such as Liquid Web or Amazon Web Services (AWS) becomes significantly easier when utilizing Infrastructure as Code (IaC) tools like Terraform to leverage the capabilities of modern cloud-based web hosting infrastructure. Liquid Web can provide the resources and guidance you need to get started.

Terraform streamlines your WordPress website's deployment, configuration, and management resources by allowing you to execute these tasks using code. This tutorial provides website owners a walkthrough of deploying and managing a basic WordPress website using the liquidweb provider on Terraform.

The following guides will help you best understand how all of the various cloud components involved work in concert:

Introduction to the Terraform Architecture

What is Terraform?

Terraform is a tool targeted at an Infrastructure as Code approach to managing asset inventory. It offers a declarative language to create configurations describing infrastructure. Given the configurations, you can rapidly create, remove, and recreate infrastructure. Since the configurations are plaintext, it allows easy versioning of the infrastructure state with Version Control Software (VCS), such as GitHub.

This code is written in a declarative manner, allowing users to specify what they want their infrastructure to look like, and Terraform takes care of making it a reality. The Terraform architecture is particularly valuable for managing multi-cloud environments because it provides a unified workflow that works across various cloud providers and on-premises infrastructure. This article assumes some basic familiarity with Terraform and Terraform modules.

Deploying a Basic/Simple WordPress Website Using Terraform

The files in this directory provide a simple WordPress Terraform deployment. This deployment is not intended for production — there are no backups. There are a few quirks, but it could be used as-is and makes a good starting point. This article explains how the parts fit together.

Environment Setup — Terraform Example

Before you can begin using Terraform, you must set up the environment, including the prerequisites and installation. Those parts are covered in the following sections.

Prerequisites

  • You must already have a Liquid Web account.
  • Your Liquid Web account or API user must be set to environment variables:
    • LWAPI_USERNAME — your account username
    • LWAPI_PASSWORD — your account password or auth token
  • For the ACME TLS provider, use these settings:
    • LIQUID_WEB_USERNAME — your account username (for ACME)
    • LIQUID_WEB_PASSWORD — your account password (for ACME)
  • You must have a DNS zone created for the domain you want to use. To use the example here in this article, the DNS zone should be managed at my.liquidweb.com.
  • You should create a .tfvars file to change the domain — see below.

Once you have those prerequisites established, deploy from this directory with the following commands:

terraform init
terraform apply

Tear down this deployment with the following command:

terraform destroy

Terraform Installation

To install Terraform, follow the steps below.

Step #1: Download Terraform

The official Terraform website has good instructions for installing Terraform, but it's likely easier to just use your operating system's package manager. Terraform can be installed via Homebrew for MacOS users or via Chocolatey for Windows users.

Step #2: Ensure Terraform is Working

Verify Terraform is properly installed with the following command:

$ terraform version

Output:

Terraform v1.6.1
on darwin_amd64

If it is not installed as expected or you do not see output similar to the above, please see the Terraform installation guide for further instructions. It is not critical to have the most recent version of Terraform; the version installed by your package manager likely suffices.

Credentials for the Liquid Web Terraform Provider

The liquidweb provider on Terraform (liquidweb/terraform-provider-liquidweb) requires access to your Liquid Web account to create resources you specify (servers, load balancers, etc.). We have a guide on creating an API account and API token on the Liquid Web platform; however, you may also use an additional API user or your main Liquid Web account. Once you have those credentials, to use our liquidweb provider on Terraform, you'll need to set those credentials as environment variables in your shell:

  • export LWAPI_USERNAME=<your username>
  • export LWAPI_PASSWORD=<your password>

If you want to use the acme provider on Terraform (vancluever/terraform-provider-acme) to get an SSL certificate as well, you'll also need to set a second set:

  • export LIQUID_WEB_USERNAME=<your username>
  • export LIQUID_WEB_PASSWORD=<your password>
  • export LIQUID_WEB_ZONE=”yourdomainname.tld”

Terraform Configuration Files

Example Repository

You can view an alternate version of this basic/simple WordPress Terraform example in our provider's repository. In that repository, you can also find all of the relevant files we are referencing here. The easiest step for our WordPress example would be to clone the files directly from the repository and then update the relevant config files:

  • $ git clone https://github.com/liquidweb/terraform-provider-liquidweb
  • $ cd terraform-provider-liquidweb/examples/simple-wordpress/

This is because you’ll need to keep the directory structure the same for your config and template files. The main files to edit then are server.tf and vars.tf files in order to add the values for your connection and top_domain information.

Configuration of Your Cloud Provider (Liquid Web on Terraform Example)

After the above repository has been cloned, there is a file data.tf that already includes the Terraform provider information used in this example. Terraform will automatically retrieve the provider based on this information once you are ready to run terraform init and terraform apply commands.

If you would like, you can update data.tf to explicitly specify the provider once in any of your configuration files, but it’s not necessary for this example. The option to do so gives you finer control over what version is used:

terraform {
  required_providers {
    liquidweb = {
      source  = "liquidweb/liquidweb"
      version = ">= 1.7.0"
    }
  }
}

Utilizing Variables and Input

Terraform promotes the use of variables for reusability. With that in mind, in our example, we've made one file — vars.tf — and put all of our variables in there for ease of use. In that file are blocks like the following examples:

variable "site_name" {
  type = string
  default = "simple.example.com"
}
variable "top_domain" {
  type = string
  default = "example.com"
}

We will draw on these blocks later on.

Scaffolding and Data

Next, for our general file, we used a data.tf file — sometimes named main.tf — as the file names are actually interchangeable.

Most of this file is creating templates for things that will later be used to install WordPress. None of the data.tf file's contents should need to be explicitly set or changed from the defaults provided in the example. There are first a few resource blocks to create random passwords:

resource "random_password" "server" {
  length  = 20
  special = false
}

However, also we create the content for a lot of files, which we will place later:

data "template_file" "wp-config" {
  template = file("${path.module}/templates/wp-config.php")
  vars = {
    dbhost = var.wordpress_dbhost
    dbname = var.wordpress_dbname
    dbuser = var.wordpress_dbuser
    dbpass = random_password.wordpress_dbpass.result
    salt = random_password.wordpress_salt.result
  }
}

We also create some DNS records for the server's hostname and the domain. We do not create the DNS zone, which is an important detail to make note of in this tutorial. As mentioned in the prerequisites sections above, this needs to be a DNS zone that already exists at my.liquidweb.com, and will not work using the liquidweb resource if the DNS is managed elsewhere:

resource "liquidweb_network_dns_record" "server_dns" {
  name  = liquidweb_cloud_server.simple_server.domain
  type  = "A"
  rdata = liquidweb_cloud_server.simple_server.ip
  zone  = var.top_domain
}

Do note that if you had your DNS zone hosted elsewhere, for example at Cloudflare, you could use the cloudflare provider on Terraform (cloudflare/terraform-provider-cloudflare) to create the required DNS records. Refer to Cloudflare's ample documentation resources for more information.

For googledomains, you can use the Google Domains DNS Challenge Provider as another example.

Getting an SSL Certificate

Included in this example, we use the acme provider on Terraform (vancluever/terraform-provider-acme) to retrieve an SSL certificate. Once again, this requires the DNS for your zone to be hosted with Liquid Web and on your account. However, if your DNS is with another provider, you can likely use the same acme provider to get an SSL certificate using DNS with that other host. All of this is in ssl.tf in the repository.

The configuration for this one is more with the external provider, but we've included the entire file here to make this simpler to follow — basically, this is what you need:

provider "acme" {
	server_url = "https://acme-v02.api.letsencrypt.org/directory"
}

resource "tls_private_key" "private_key" {
  algorithm = "RSA"
}

resource "acme_registration" "reg" {
  account_key_pem = tls_private_key.private_key.private_key_pem
  email_address   = "nobody@${var.site_name}"
}

resource "acme_certificate" "web_cert" {
  account_key_pem           = acme_registration.reg.account_key_pem
  common_name               = "${var.site_name}"
	key_type = "4096"
  # subject_alternative_names = ["www2.example.com"]

  dns_challenge {
    provider = "liquidweb"
  }
}

Once again, to use this, it requires that, in addition to setting your username/password as the variables LWAPI_USERNAME, you must also set them to LIQUID_WEB_USERNAME.

Defining WordPress Infrastructure on Terraform Example

The final bit is actually creating the server. However, this file has the most content and the most complexity. Again, none of these files need to be modified from the defaults in the example repository. The first chunk of this file defines the server itself:

resource "liquidweb_cloud_server" "simple_server" {
  zone      = data.liquidweb_network_zone.zonec.network_zone_id
  config_id = 1757
  template       = "ROCKYLINUX_8_UNMANAGED"
  domain         = "wordpress-host${random_id.server.dec}.us-midwest-2.${var.top_domain}"
  public_ssh_key = file("${path.root}/default.pub")
  password       = random_password.server.result

That block in that file is not closed, it goes on, but first breaking there we'd like to define some of those bits:

  • zone — denotes which zone/location to create the virtual machine (VM). In this example, rather than specifying the numeric zone, in the data.tf file, we instead got the zone by name and are using that now.
  • config_id — is the config of the server to create. Server configs specify the amount of RAM, number of CPUs, disk space, etc., allocated to each server.
  • template — is the Liquid Web template to start the server from, or the base OS to use.
  • domain — is the hostname of the server to create. Here, it is created automatically, but you can change that to just be a string.
  • password — is the automatically generated, random password.
  • public_ssh_key — is an SSH key to insert into the server during creation. Here, we are using the contents of a file default.pub in the same directory, if you do not want to automatically insert a pubkey ensure you adjust the connection section next.

Allowing Terraform to Connect to the Server During Creation

In order to let Terraform set up WordPress on this server, we have to configure Terraform to be able to get to that server. This is done with the connection block within that server's definition block — the below uses an SSH key:

 connection {
    type  = "ssh"
    user  = "root"
    agent = true
    host  = "self.ip"
  }

Alternatively, if you would rather use the root password:

connection {
  type = "ssh"
  user = "root"
  password = "${self.password}"
  host = "${self.ip}"
}

Once you have access to the server configured, in this example we use provisioner blocks to write files to the server, most from the result of templates:

provisioner "file" {
    content     = data.template_file.site-conf.rendered
    destination = "/etc/nginx/conf.d/site.conf"
}
We also use provisioner blocks to run commands on the server:
 provisioner "remote-exec" {
    inline = [
      "yum install -y epel-release",
      "yum install -y http://rpms.remirepo.net/enterprise/remi-release-8.rpm",
      "yum install -y wget curl nginx mysql mysql-common mysql-server php82-php-fpm php82-php-mysqlnd php82-php-mbstring"
    ]
  }

Typically, these software install steps would be done with another tool — Puppet, Ansible, cloud-init, etc. — as Terraform is mostly used to create the required server resources. However, to show a full end-to-end setup, everything in this example is done with Terraform alone.

Deployment Verification

  • Accessing Your WordPress Website: Your WordPress site should now be awaiting initial setup at the domain you configured.
  • Resource Verification in Your Cloud Provider: You can also open my.liquidweb.com to see your server, and verify the resources created with this provider.

Managing and Updating your WordPress Infrastructure — Terraform Example

Understanding Terraform State

Terraform maintains .terraform.lock.hcl that records providers and such are currently present for your install. It also keeps a terraform.tfstate file that tracks what assets it currently has deployed. You can see what assets it is managing with the terraform showcommand. These files should not be manually modified. You can refer to the Terraform website for more details regarding state management.

Modifying Configuration

If you need to make changes to your WordPress infrastructure (for example, adding more servers or adjusting network settings), you can modify your Terraform configuration files accordingly. After, running the terraform plan command will show you the proposed changes.

Applying Updates

If you have made changes to your configs, the terraform apply command will first show you the changes Terraform is set to make, then make them for you if you like.

If you run into the following error, try a terraform destroy command, and then the terraform apply command to regenerate the certificate signing request (CSR):

Error: acme: error: 403 :: POST :: https://acme-v02.api.letsencrypt.org/acme/new-acct :: urn:ietf:params:acme:error:unauthorized :: An account with the provided public key exists but is deactivated

│ 
│   with acme_registration.reg,
│   on ssl.tf line 9, in resource "acme_registration" "reg":
│    9: resource "acme_registration" "reg" {
│ 
╵

Conclusion — Terraform Example

This Terraform example article has used a demo WordPress install to try to run through the basics of Terraform. These procedures can be used to deploy and manage your infrastructure with Liquid Web.

Are You Ready to Deploy Your WordPress Website?

Liquid Web hosting is a great choice with several cloud WordPress hosting packages that you can choose from based on your budget and website requirements. We offer a secure, high-performance hosting environment optimized for WordPress, accompanied by 24/7 heroic support to ensure a seamless hosting experience.

Developers can also use the Liquid Web CLI, our official command line interface for the Liquid Web application programming interface (LW API), as a versatile tool for automating and efficiently managing Liquid Web cloud resources. With the LW CLI, you can perform tasks such as creating, cloning, and resizing servers, adjusting cloud firewalls and network settings, restoring server backups, and much more. This CLI can be used along with the Terraform command line interface (CLI), depending on the kind of task you want to perform.

The Liquid CLI proves to be the most effective tool for interacting with and managing our cloud servers, allowing you to configure servers before deploying your website and make adjustments as needed to scale resources up or down. To explore the capabilities of the LW CLI and how to utilize them, you can refer to this article on Using the Liquid Web Command Line Interface (LW CLI). If you need assistance getting started with Liquid or how to enhance the power of Liquid Web CLI, don’t hesitate to contact our support team.

Latest Articles

In-place CentOS 7 upgrades

Read Article

How to use kill commands in Linux

Read Article

Change cPanel password from WebHost Manager (WHM)

Read Article

Change cPanel password from WebHost Manager (WHM)

Read Article

Change the root password in WebHost Manager (WHM)

Read Article