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
Fix the developers vs. security conflict by shifting further left
Resolve the friction between dev and security teams with platform-led workflows that make cloud security seamless and scalable.
HashiCorp at AWS re:Invent: Your blueprint to cloud success
If you’re attending AWS re:Invent in Las Vegas, Dec. 2 - Dec. 6th, visit us for breakout sessions, expert talks, and product demos to learn how to take a unified approach to Infrastructure and Security Lifecycle Management.
Speed up app delivery with automated cancellation of plan-only Terraform runs
Automatic cancellation of plan-only runs allows customers to easily cancel any unfinished runs for outdated commits to speed up application delivery.