Deploying Discourse with Terraform
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
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.
» Preparation Steps
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.
- Access or create a DigitalOcean Account
- Sign up or log in
- Get a write-enabled access token
- Add your SSH key and retrieve the ID with
curl -X GET "https://api.digitalocean.com/v2/account/keys" -H "Authorization: Bearer $ACCESS_TOKEN"
- Access or create a Mailgun Account
- Select your domain (
example.com
) and point the nameservers at DigitalOcean.
» Getting the Configuration
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.
» Running the Plan Command
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.
» Running the Apply Command
$ 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 domain is created on Mailgun.
- The droplet (server) is created, provisioned with SMTP details and other configurations.
- The DNS records are created for mail and the application, using the IP addressed assigned to the previously created droplet.
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.
» Conclusion
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.
Sign up for the latest HashiCorp news
More blog posts like this one
New Terraform integrations with Crowdstrike, Datadog, JFrog, Red Hat, and more
12 new Terraform integrations from 9 partners provide more options to automate and secure cloud infrastructure management.
Terraform delivers launch-day support for Amazon S3 Tables, EKS Hybrid Nodes, and more at re:Invent
The Terraform provider for AWS now enables users to manage a variety of new services just announced at re:Invent.
HashiCorp at re:Invent 2024: Infrastructure Lifecycle Management with AWS
A recap of HashiCorp infrastructure news and developments on AWS from the past year, from a new provider launch to simplifying infrastructure provisioning and more.