A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://developer.hashicorp.com/terraform/tutorials/applications/heroku-provider below:

Deploy, manage, and scale an application on Heroku | Terraform

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:

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.

To complete this tutorial, you will need:

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.

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.

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.

$ git clone https://github.com/hashicorp-education/learn-terraform-heroku

Navigate to the cloned repository.

$ cd learn-terraform-heroku

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.

Open versions.tf, which defines the required Terraform version and provider versions.

Open main.tf. This file contains the Terraform configuration that deploys an application and a database. This file contains:

Open outputs.tf, which defines an output value for the deployed application's URL.

outputs.tf

output "app_url" {
  value       = heroku_app.example.web_url
  description = "Application 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.

Initialize the Terraform configuration.

$ terraform init
Initializing the backend...

Initializing provider plugins...
- Reusing previous version of heroku/heroku from the dependency lock file
- Installing heroku/heroku v4.6.0...
- Installed heroku/heroku v4.6.0 (signed by a HashiCorp partner, key ID 49ACC74D80C7B012)

Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to review
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Next, apply the configuration. Respond yes to the prompt to confirm.

$ terraform apply
Terraform used the selected providers to generate the
following execution plan. Resource actions are indicated
with the following symbols:
  + create

Terraform will perform the following actions:

  # heroku_addon.postgres will be created
  + resource "heroku_addon" "postgres" {
      + app         = (known after apply)
      + config_vars = (known after apply)
      + id          = (known after apply)
      + name        = (known after apply)
      + plan        = "heroku-postgresql:hobby-dev"
      + provider_id = (known after apply)
    }

    ## ...

Plan: 4 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + app_url = (known after apply)

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

heroku_app.example: Creating...
heroku_app.example: Creation complete after 7s [id=learn-terraform-heroku]
heroku_addon.postgres: Creating...
heroku_build.example: Creating...
heroku_addon.postgres: Creation complete after 1s [id=8a32cbe5-3b5d-497a-b54a-853367ffa5fe]
heroku_build.example: Still creating... [10s elapsed]
heroku_build.example: Still creating... [20s elapsed]
heroku_build.example: Still creating... [30s elapsed]
heroku_build.example: Creation complete after 34s [id=49ff566e-193a-453c-80f3-144da1996b57]
heroku_formation.example: Creating...
heroku_formation.example: Creation complete after 0s [id=af8bb93e-be1b-4b5b-a5cb-9ae09c5a8ebe]

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

Outputs:

app_url = "https://learn-terraform-heroku.herokuapp.com/"

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.

$ curl $(terraform output -raw app_url)
Hello World

Now, send a request to the db/seed path to create the test database table.

$ curl -X POST $(terraform output -raw app_url)db/seed
Successfully seeded database

Insert items into the database.

$ curl -d '{"terraform":"rocks", "hashicorp":"learn"}' -H "Content-Type: application/json" -X POST $(terraform output -raw app_url)db/upsert
Added data to 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.

$ curl $(terraform output -raw app_url)db/query/terraform
{"key":"terraform","value":"rocks"}

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.

app/index.js

 app.get('/', function (_, res) {
-  res.send('Hello World\n')
+  res.send('Hello Terraform!\n')
 });

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.

main.tf

resource "heroku_build" "example" {
  app = heroku_app.example.id

  source {
    path = "./app"
  }

  lifecycle {
    create_before_destroy = true
  }
}

Apply your changes. Enter yes when prompted to accept your changes.

$ terraform apply
heroku_app.example: Refreshing state... [id=learn-terraform-heroku]
heroku_addon.postgres: Refreshing state... [id=e4512647-6182-4d67-a451-a56e9aad40db]
heroku_build.example: Refreshing state... [id=5a0b0167-9e27-4ccb-8642-ce889224d0af]
heroku_formation.example: Refreshing state... [id=d0666a58-41c6-4790-8553-5b07ecf4745d]

## ...

────────────────────────────────────────────────────────

Terraform used the selected providers to generate the
following execution plan. Resource actions are indicated
with the following symbols:
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # heroku_build.example must be replaced
-/+ resource "heroku_build" "example" {
      ~ buildpacks        = [
          - "https://buildpack-registry.s3.amazonaws.com/buildpacks/heroku/nodejs.tgz",
        ] -> (known after apply)
      ~ id                = "5a0b0167-9e27-4ccb-8642-ce889224d0af" -> (known after apply)
      ~ local_checksum    = "SHA256:9c5550a5e3cc4726f075b423bea57ac963ae43a7a53eba4c56e7ba06d7b47c00" -> "SHA256:0739cab672bdac0844a412f16469ddfe09c5cf695853dcb3401a454bdc932b7f" # forces replacement
      ~ output_stream_url = "https://build-output.heroku.com/streams/ba/bafd93f4-1be4-4141-b23b-f49c0bf66e70/logs/5a/5a0b0167-9e27-4ccb-8642-ce889224d0af.log?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIQI6BAUWXGR4S77Q%2F20210721%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210721T152100Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host&X-Amz-Signature=dc2f5f00a627240f731bea494a0d82e31727ac67e302d977310d684a77859445" -> (known after apply)
      ~ release_id        = "2ae31be0-ef36-470e-bf7f-911ffc7d947d" -> (known after apply)
      ~ slug_id           = "6aaea84f-8b6e-4da9-aeb6-1d7074e5e5e7" -> (known after apply)
      ~ stack             = "heroku-20" -> (known after apply)
      ~ status            = "succeeded" -> (known after apply)
      ~ user              = [
          - {
              - email = "team-training@hashicorp.com"
              - id    = "9be75c65-bcfe-4e6c-b1ea-29852c2b320c"
            },
        ] -> (known after apply)
      ~ uuid              = "5a0b0167-9e27-4ccb-8642-ce889224d0af" -> (known after apply)
        # (1 unchanged attribute hidden)

      ~ source {
          + checksum = (known after apply)
            # (1 unchanged attribute hidden)
        }
    }

Plan: 1 to add, 0 to change, 1 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

heroku_build.example: Destroying... [id=5a0b0167-9e27-4ccb-8642-ce889224d0af]
heroku_build.example: Destruction complete after 0s
heroku_build.example: Creating...
heroku_build.example: Still creating... [10s elapsed]
heroku_build.example: Still creating... [20s elapsed]
heroku_build.example: Still creating... [30s elapsed]
heroku_build.example: Creation complete after 33s [id=f7a800bd-3c0d-43ac-94c8-a589b3cacc9d]

Apply complete! Resources: 1 added, 0 changed, 1 destroyed.

Outputs:

app_url = "https://learn-terraform-heroku.herokuapp.com/"

Use cURL to send a request to the app_url output value to verify Terraform deployed the latest changes to your application.

$ curl $(terraform output -raw app_url)
Hello Terraform!

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.

$ terraform apply
heroku_app.example: Refreshing state... [id=learn-terraform-heroku]
heroku_addon.postgres: Refreshing state... [id=8a32cbe5-3b5d-497a-b54a-853367ffa5fe]
heroku_build.example: Refreshing state... [id=49ff566e-193a-453c-80f3-144da1996b57]
heroku_formation.example: Refreshing state... [id=af8bb93e-be1b-4b5b-a5cb-9ae09c5a8ebe]

## ...

────────────────────────────────────────────────────────

Terraform used the selected providers to generate the
following execution plan. Resource actions are indicated
with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # heroku_formation.example will be updated in-place
  ~ resource "heroku_formation" "example" {
        id       = "af8bb93e-be1b-4b5b-a5cb-9ae09c5a8ebe"
      ~ quantity = 1 -> 2
        # (3 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

heroku_formation.example: Modifying... [id=af8bb93e-be1b-4b5b-a5cb-9ae09c5a8ebe]
heroku_formation.example: Modifications complete after 1s [id=af8bb93e-be1b-4b5b-a5cb-9ae09c5a8ebe]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

Outputs:

app_url = "https://learn-terraform-heroku.herokuapp.com/"

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 the following resource to main.tf. This resource adds the Papertrail resource to your application.

main.tf

resource "heroku_addon" "logging" {
  app  = heroku_app.example.id
  plan = "papertrail:choklad"
}

Apply your changes to add logging to your application. Enter yes when prompted to accept your changes.

$ terraform apply

## ...

Terraform used the selected providers to generate the
following execution plan. Resource actions are indicated
with the following symbols:
  + create

Terraform will perform the following actions:

  # heroku_addon.logging will be created
  + resource "heroku_addon" "logging" {
      + app         = "learn-terraform-heroku"
      + config_vars = (known after apply)
      + id          = (known after apply)
      + name        = (known after apply)
      + plan        = "papertrail:choklad"
      + provider_id = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

heroku_addon.logging: Creating...
heroku_addon.logging: Creation complete after 3s [id=304c8928-179b-4a1e-a3f4-35642fe00e4d]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

app_url = "https://learn-terraform-heroku.herokuapp.com/"

Send multiple requests to your application URL to generate logs.

$ for i in `seq 1 5`; do curl $(terraform output -raw app_url); done
Hello Terraform!
Hello Terraform!
Hello Terraform!
Hello Terraform!
Hello Terraform!

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.

Before moving on, destroy the infrastructure you created in this tutorial. Enter yes when prompted to destroy your resources.

$ terraform destroy
## ...

Plan: 0 to add, 0 to change, 5 to destroy.

Changes to Outputs:
  - app_url = "https://learn-terraform-heroku.herokuapp.com/" -> null

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

heroku_addon.postgres: Destroying... [id=8a32cbe5-3b5d-497a-b54a-853367ffa5fe]
heroku_formation.example: Destroying... [id=af8bb93e-be1b-4b5b-a5cb-9ae09c5a8ebe]
heroku_addon.logging: Destroying... [id=304c8928-179b-4a1e-a3f4-35642fe00e4d]
heroku_formation.example: Destruction complete after 0s
heroku_build.example: Destroying... [id=49ff566e-193a-453c-80f3-144da1996b57]
heroku_build.example: Destruction complete after 0s
heroku_addon.postgres: Destruction complete after 1s
heroku_addon.logging: Destruction complete after 1s
heroku_app.example: Destroying... [id=learn-terraform-heroku]
heroku_app.example: Destruction complete after 0s

Destroy complete! Resources: 5 destroyed.

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.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4