Deploy, manage, and scale an application on Heroku
Heroku is a Platform as a Service (PaaS) provider that enables developers to build, run, and operate applications in the cloud. While you can use Heroku's dashboard or CLI to manage your application resources, using Terraform provides you with several benefits:
Safety and consistency - Defining your infrastructure as code (IaC) reduces risk of human error. IaC enables you to manage similar infrastructure across your environments using a consistent workflow.
Full lifecycle management - Terraform can create, update, and delete tracked resources without requiring you to inspect the dashboard or API to identify those resources.
Graph of relationships - Terraform tracks dependency relationships between resources. For example, since a Heroku formation needs to be associated with an application and a build, Terraform will wait for the application and build to successfully deploy before attempting to create a formation.
In this tutorial, you will use Terraform to manage your Heroku application's lifecycle. First, you will deploy an application and database to Heroku. Then, you will scale and add logging to the application using Terraform.
Prerequisites
To complete this tutorial, you will need:
- the Terraform v0.14+ CLI installed locally
- a Heroku account
Note
This tutorial uses Heroku formation which requires you to use a Heroku account with payment information. If you destroy your resources by the end of the tutorial, you should not be charged. We are not responsible for any charges that may incur.
Generate Heroku authorization token
Terraform uses a Heroku authorization token to authenticate to Heroku and manage your resources.
After signing in to Heroku, go to the Application page of your Heroku Account.
Click on "Create authorization" under the authorization section. Then, enter "Terraform" in the description field and leave the expiration field blank. Click on the "Create" button to create the authorization token.
The dashboard will present the authorization token. Copy this token and export
it as an environment variable named HEROKU_API_KEY
.
In addition to the authorization token, Terraform needs your Heroku account's
email address. You can find this in your
account settings. Export your account's
email as an environment variable named HEROKU_EMAIL
.
Clone example repository
In your terminal, clone the example repository. This repository contains a demo application and a complete Terraform configuration that deploys the application and a database to Heroku.
Navigate to the cloned repository.
Note
The example repository contains both the application code and Terraform configuration for demo purposes. In practice, you should store application code and Terraform configuration in separate repositories.
Review configuration
Open versions.tf
, which defines the required Terraform version and provider
versions.
A
terraform
block that specifies the providers required by this configuration and the compatible Terraform versions. This configuration uses the Terraform Heroku provider v4.6.x to interact with Heroku. It also specifies that you must use at least Terraform v0.14+.versions.tf
Open main.tf
. This file contains the Terraform configuration that deploys an
application and a database. This file contains:
A
provider
block that configures the Heroku provider. Though you can configure your credentials in this block, it is safer to use theHEROKU_API_KEY
andHEROKU_EMAIL
environment variables. This prevents you from adding your sensitive credentials to the configuration and accidentally pushing them to version control.main.tf
The
heroku_app.example
resource defines a new Heroku application namedlearn-terraform-heroku
in the US region.main.tf
The
heroku_addon.postgres
resource defines a new Postgres instance. This resource references theheroku_app.example
resource so Heroku knows to deploy the database in the application.main.tf
The
heroku_build.example
resource deploys source code to a Heroku application. Like the Postgres resource, this resource setsapp
toheroku_app.example.id
. The resource expects the source code to live in./app
.main.tfTip
You can specify the source as a URL that responds to a
GET
request with a tarball containing source code. Review theheroku_build
resource documentation for more information.The
app_quantity
variable defines a Terraform variable you can use to set the number of dynos you want in your formation. By defining a variable, you're able to scale your application without changing your configuration.main.tfThe
heroku_formation.example
resource defines a formation for your application. This enables you to scale your application over its lifecycle. Notice that this resource uses thedepends_on
meta-argument to define an explicit dependency between the formation and theheroku_build
resource. Terraform will wait for the build resource to complete before creating the formation.main.tf
Open outputs.tf
, which defines an output value for the deployed application's URL.
Review demo application
The demo NodeJS application lives in the /app
directory of the repository
you cloned. The application connects to the Postgres database and defines
endpoints that allow you to read and write values from a test table.
The demo application uses the PORT
and DATABASE_URL
environment variables.
The Heroku application adds these environment variables to the application on
deployment.
Apply configuration
Initialize the Terraform configuration.
Next, apply the configuration. Respond yes
to the prompt to confirm.
Verify provisioned resources
Use cURL to send a request to the app_url
output value to verify Terraform
provisioned the application and database correctly. The -raw
flag removes
surrounding quotes from the output value.
Now, send a request to the db/seed
path to create the test database table.
Insert items into the database.
Read the value from the database. The db
endpoint returns all rows in the
test table. The db/query/<KEY>
endpoint returns a specific key from the table.
Update application
The heroku_build
resource uses a checksum of your source code to determine if
the contents of your application have changed. If the checksums are different,
it will trigger a build on the next apply operation.
In app/index.js
, update your application's response.
Then, add a lifecycle
block to your heroku_build
resource. This
block allows Terraform to create the new build before destroying
the old version. Lifecycle management allows you to make changes without
interrupting your application uptime.
Apply your changes. Enter yes
when prompted to accept your changes.
Use cURL to send a request to the app_url
output value to verify Terraform
deployed the latest changes to your application.
Scale application
Scale your application by setting your app_quantity
variable to 2.
Create a new file named terraform.tfvars
with the following contents.
Terraform automatically uses values defined in this file to override any
variable defaults.
Apply your changes. Enter yes
when prompted to accept your changes.
Open your Heroku dashboard then select the learn-terraform-heroku
application.
Select "Resources" in the top menu. Observe that your application now has two
dynos.
Add logging to application
Add the following resource to main.tf
. This resource adds the Papertrail
resource to your application.
Apply your changes to add logging to your application. Enter yes
when
prompted to accept your changes.
Send multiple requests to your application URL to generate logs.
On your application overview page, click on "Papertrail" under the "Installed add-ons" section.
Agree to Papertrail's service agreement then click "Continue". You will find a set of logs for your application.
Clean up resources
Before moving on, destroy the infrastructure you created in this tutorial.
Enter yes
when prompted to destroy your resources.
Next steps
Over the course of this tutorial, you deployed an application and database to Heroku. Then, you scaled and added logging to the application. Terraform enables you to manage your application's lifecycle, from creating new resources to managing existing ones to destroying ones you no longer need.
For more information on topics covered in this tutorial, check out the following resources.
- Complete the Reuse Configuration with Modules tutorials to learn how to create reusable modules to enable repeatable workflows.
- Visit the Heroku provider documentation to learn more about the Heroku resources and data sources you can manage using Terraform.
- Visit Heroku's getting started with Terraform tutorial for additional examples and Heroku-specific best practices.