In this blog post, we'll show how Terraform can create a running instance of Discourse on DigitalOcean in one command.
Following the release of Terraform 0.2, we wanted to publish the first of several examples of using Terraform to automate the creation and management of infrastructure.
Terraform is abstract, so it can be hard to grasp and understand it's capabilities without seeing and using it in a real world example. Even if you don't intend to keep Discourse running, this may be a good chance to learn more about Terraform.
Discourse is a discussion platform "built for the next decade of the Internet". That means it uses modern frameworks and tools to run. Because of this, installing Discourse can be challenging for new and inexperienced users.
Terraform, of course, is intended for a technical audience, but there's also potential to build tooling around it to take advantage of it's automation and friendly declarative configuration.
Discourse 1.0 was just released, so we find it fitting to use it to see Terraform in action. This configuration was based on the beginner installation guide published by Discourse.
Before running terraform apply
, you'll need to have accounts and access information for the configured providers.
Note: This example uses the DigitalOcean and Mailgun providers, but you could modify the configuration to use any other Terraform providers in place or in addition, like Route53 or DNSimple. For a full list of providers, visit the documentation.
curl -X GET "https://api.digitalocean.com/v2/account/keys" -H "Authorization: Bearer $ACCESS_TOKEN"
example.com
) and point the nameservers at DigitalOcean.Terraform is configured by .tf
files. By default, Terraform collects all *.tf
files in a directory and merges them together.
You'll need to clone the following example repository with Git:
$ git clone https://github.com/pearkes/discourse-terraform.git
Once the repository is retrieved from GitHub, we can try running Terraform.
Although not required for a terraform apply
, terraform plan
helps you visualize what Terraform will do. In this case, you should see output similar to the following:
$ terraform plan \
-var 'developer_email=YOUR_ACCESS_KEY' \
-var 'smtp_password=YOUR_SECRET_KEY' \
-var 'domain=YOUR_DOMAIN' \
-var 'ssh_key_id=YOUR_SSH_KEY_ID' \
-var 'do_token=YOUR_DO_TOKEN' \
-var 'mailgun_key=YOUR_MAILGUN_KEY' \
-var 'ssh_key_path=YOUR_KEY_PATH'
...
+ digitalocean_domain.discourse
ip_address: "" => "${digitalocean_droplet.discourse.ipv4_address}"
name: "" => "YOUR_DOMAIN"
+ digitalocean_droplet.discourse
backups: "" => "<computed>"
image: "" => "ubuntu-14-04-x64"
ipv4_address: "" => "<computed>"
ipv4_address_private: "" => "<computed>"
ipv6: "" => "<computed>"
ipv6_address: "" => "<computed>"
ipv6_address_private: "" => "<computed>"
locked: "" => "<computed>"
name: "" => "discourse"
private_networking: "" => "<computed>"
region: "" => "nyc2"
size: "" => "2gb"
ssh_keys.#: "" => "1"
ssh_keys.0: "" => "YOUR_SSH_KEY_ID"
status: "" => "<computed>"
+ mailgun_domain.mail
name: "" => "YOUR_DOMAIN"
receiving_records.#: "" => "<computed>"
sending_records.#: "" => "<computed>"
smtp_login: "" => "<computed>"
smtp_password: "" => "YOUR_SECRET_KEY"
spam_action: "" => "disabled"
wildcard: "" => "<computed>"
If you're happy with the output, you can move on to apply and create the resources.
$ terraform apply \
-var 'developer_email=YOUR_ACCESS_KEY' \
-var 'smtp_password=YOUR_SECRET_KEY' \
-var 'domain=YOUR_DOMAIN' \
-var 'ssh_key_id=YOUR_SSH_KEY_ID' \
-var 'do_token=YOUR_DO_TOKEN' \
-var 'mailgun_key=YOUR_MAILGUN_KEY' \
-var 'ssh_key_path=YOUR_KEY_PATH'
...
This will create your infrastructure, showing you the output along the way. In this example, the following steps occur:
The whole process takes some time, depending on several factors, as the provisioner on the server is installing, configuring and restarting Discourse. Under the hood, this uses Docker, which Terraform happily provisions on top of the DigitalOcean droplet.
Additionally, DigitalOcean DNS may take some time to propagate.
If you're interested in seeing detailed logs of what Terraform is doing, run the command with TF_LOG=1 ...
prepended.
Setting up Discourse with Terraform is an interesting example of what kind of automation is possible.
Part of the value of Terraform is how it combines resources, as demonstrated with Mailgun, and the resulting provisioning of SMTP credentials for the application to read.
If you're interested in learning more about Terraform, follow the links below.
How one technologist’s Terraform certification journey helped him refresh his career as a practitioner after being a CTO at a small firm.
Terraform Cloud Operator for Kubernetes adds more Day 2 operations. Users can now start runs using workspace resource annotations.
The newest enhancements to HashiCorp Terraform Cloud’s run task feature empower users to seamlessly expand their use of essential third-party integrations.