Skip Navigation
Show nav
Dev Center
  • Get Started
  • ドキュメント
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • ドキュメント
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log inorSign up
View categories

Categories

  • Heroku のアーキテクチャ
    • Dyno (アプリコンテナ)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • スタック (オペレーティングシステムイメージ)
    • ネットワーキングと DNS
    • プラットフォームポリシー
    • プラットフォームの原則
  • Developer Tools
    • コマンドライン
    • Heroku VS Code Extension
  • デプロイ
    • Git を使用したデプロイ
    • Docker によるデプロイ
    • デプロイ統合
  • 継続的デリバリーとインテグレーション
    • 継続的統合
  • 言語サポート
    • Node.js
      • Working with Node.js
      • Node.js Behavior in Heroku
      • Troubleshooting Node.js Apps
    • Ruby
      • Rails のサポート
      • Bundler の使用
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Python でのバックグランドジョブ
      • Python Behavior in Heroku
      • Django の使用
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Maven の使用
      • Spring Boot の使用
      • Troubleshooting Java Apps
    • PHP
      • PHP Behavior in Heroku
      • Working with PHP
    • Go
      • Go の依存関係管理
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • データベースとデータ管理
    • Heroku Postgres
      • Postgres の基礎
      • Postgres スターターガイド
      • Postgres のパフォーマンス
      • Postgres のデータ転送と保持
      • Postgres の可用性
      • Postgres の特別なトピック
      • Migrating to Heroku Postgres
    • Heroku Data For Redis
    • Apache Kafka on Heroku
    • その他のデータストア
  • AI
    • Working with AI
    • Heroku Inference
      • Inference API
      • Quick Start Guides
      • AI Models
      • Inference Essentials
    • Vector Database
    • Model Context Protocol
  • モニタリングとメトリクス
    • ログ記録
  • アプリのパフォーマンス
  • アドオン
    • すべてのアドオン
  • 共同作業
  • セキュリティ
    • アプリのセキュリティ
    • ID と認証
      • シングルサインオン (SSO)
    • Private Space
      • インフラストラクチャネットワーキング
    • コンプライアンス
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Team
    • Heroku Connect (Salesforce 同期)
      • Heroku Connect の管理
      • Heroku Connect のリファレンス
      • Heroku Connect のトラブルシューティング
  • パターンとベストプラクティス
  • Heroku の拡張
    • Platform API
    • アプリの Webhook
    • Heroku Labs
    • アドオンのビルド
      • アドオン開発のタスク
      • アドオン API
      • アドオンのガイドラインと要件
    • CLI プラグインのビルド
    • 開発ビルドパック
    • Dev Center
  • アカウントと請求
  • トラブルシューティングとサポート
  • Salesforce とのインテグレーション
  • デプロイ
  • デプロイ統合
  • Heroku で Terraform を使用する

Heroku で Terraform を使用する

日本語 — Switch to English

この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。

最終更新日 2024年05月30日(木)

Table of Contents

  • Terraform を設定する
  • Heroku プロバイダーを設定する
  • 空のアプリをプロビジョニングする
  • コードをアプリにデプロイする
  • 理解を深める
  • 例
  • ベストプラクティス
  • リファレンス

Heroku アプリのコレクションの数が増え、複雑さが増すにつれて、インフラストラクチャ全体 (アプリ、アドオン、ドメイン、Private Space など) のデプロイを自動化する機能が益々重要になります。

Hashicorp の Terraform​ は、幅広い統合化クラウドリソース (Heroku のリソースを含む) を HCL と呼ばれるシンプルな宣言型言語で設定およびデプロイできるようにするツールです。

この記事では、Heroku で Terraform を使用する方法を紹介します。一般的な Heroku のリソースを一般的な Terraform のベストプラクティス​と併せて設定するための設定例も用意しています。

Terraform を設定する

最初に、Terraform をダウンロード​してインストールします。

Terraform を使用する前に、設定の現在の状態​を保存するバックエンド​を検討します。この状態には、既存のすべてのリソースと、リソース間の関係の識別子が含まれます。Terraform は、この状態を使用して、特定のアクション (通常、作成または破棄) を完了するために行う必要がある作業を把握します

Terraform を初めて使用する場合は、デフォルトのローカルバックエンドでファイルに状態が保管されます。実際のプロジェクト用に Terraform を使い始めたら、Heroku Postgres などのリモートのバックエンドを使用して状態の情報を保存する必要が出てきます。

ローカルバックエンド

ローカルバックエンド​は、Terraform を立ち上げる最も簡単な方法です。Terraform の設定でバックエンドを指定していない場合は、ローカルバックエンドが使用されます。

このバックエンドにより、ローカルマシン上の terraform.tfstate​ ファイルにデプロイの状態が保管されます。terraform.tfstate ファイルをバージョン管理にチェックインしないでください。​このファイルには、秘密鍵などの機密情報が入っています。

ローカルバックエンドは、長期使用や共同作業にはお勧めしません。状態が個人のマシンにのみ保存されるので、他のチームメンバーはアクセスできず、不慮の損失を防ぐためのバックアップも行われません。この問題を解決するために、代わりに Postgres データベースなどのリモート​バックエンドを使用できます。

リモートの Postgres バックエンド

Heroku Postgres アドオン​と一緒に pg バックエンド​ を使用して、長期使用や共同作業のためのプロジェクトを設定します。pg バックエンドは、Terraform バージョン 0.12 以降​に含まれています。このリモートバックエンドを使用すると、(ローカルバックエンドのように) Terraform を個人貢献者のマシンで実行することも、Heroku アプリとして実行することもできます。Heroku の自動化されたデータベースバックアップ​とフェイルオーバー​により、Terraform の状態が使用可能になり、ハードウェア障害が発生した場合に復元できます。

pg バックエンドを使用するには、main.tf​ (またはその他の) 設定ファイルでそのバックエンドを指定します。

terraform {
  backend "pg" {
  }
}

次に、Heroku Postgres アドオンを使用して Heroku アプリを作成し、そのアプリの DATABASE_URL​ 環境設定を pg バックエンドの conn_str​ として使用します。

# Pick a unique app name
$ export APP_NAME=my-terraform-backend

# Create the database
$ heroku create $APP_NAME
$ heroku addons:create heroku-postgresql:essential-0 --app $APP_NAME

# On each machine where it's used, initialize Terraform
# with the database credentials
$ export DATABASE_URL=`heroku config:get DATABASE_URL --app $APP_NAME`
$ terraform init -backend-config="conn_str=$DATABASE_URL"

前の例では、Essential-0 Heroku Postgres データベースを使用しています。より重要なユースケースでの最高のパフォーマンスと可用性を確保するには、standard-0​ や premium-0​ などの Standard 層以上のプラン​を設定することを検討してください。

詳細な設定のオプションと例については、Terraform の pg バックエンドのドキュメント​を参照してください。

その他のリモートバックエンド

この記事では説明しませんが、さまざまなその他のリモートバックエンド​を使用できます。

Hashicorp も Remote State Management サービス​ とプレミアム Terraform Enterprise 製品​を提供しています。

Heroku プロバイダーを設定する

完全なドキュメントは、Heroku プロバイダーのドキュメント​で参照できます。

設定

Terraform をインストールした後で、主要設定ファイル​ (main.tf​) を作成して、Heroku プロバイダーを指定します。リモートの pg バックエンドを使用している場合は、このファイルにすでにバックエンドの設定が入っている可能性があります。

terraform {
  required_providers {
    heroku = {
      source  = "heroku/heroku"
      version = "~> 5.0"
    }
  }
}

アップグレード

Heroku プロバイダーの最新のリリースバージョン​を確認し、バージョンが古い場合は設定を更新できます。

セマンティックバージョニングの手法に従うと、マイナーおよびパッチバージョンのアップグレードには下位互換性があります。新しいメジャーバージョンに移行するには、アップグレードガイド​を参照してください。

認証

Terraform で Heroku プロバイダー​を使用すると、アプリ、アドオン、およびその他のリソースを作成するために Platform API​ へのリクエストが作成されます。Platform API へのリクエストには、認証トークン​が必要です。

Terraform に使用される認証トークンには、必要なさまざまなアクションを Heroku API で実行するためにグローバル​スコープが必要です。Terraform の機能を既存の Heroku アカウントから分離する必要がある場合は、Terraform で使用する専用の新しい​ Heroku アカウントを作成​できます。

認証トークンを取得する

最初に、Heroku CLI​ を使用して、Terraform で使用する Heroku アカウントにログインしていることを確認します。

$ heroku whoami

ID を切り替える必要がある場合は、次のように、ログアウトしてからログインします。

$ heroku logout
$ heroku login

次に、Heroku CLI を使用して、認証トークン​を生成します。--description​パラメータは、それぞれの認証の目的や識別子を示す、ユーザーが判読可能な名前です。

$ heroku authorizations:create --description terraform-my-app

返された Token​ 値と Heroku アカウントのメールアドレスを Terraform のローカル環境変数​として設定します。

$ export HEROKU_API_KEY=<TOKEN> HEROKU_EMAIL=<EMAIL>

環境変数は、使用するそれぞれの新しいターミナル / シェルで、もう一度エクスポートする必要があります。

Heroku CLI を使用して、今後もう一度使用する認証トークンを探します。すべての認証のリストを表示してから、目的の認証の ID のトークンを取得します。

$ heroku authorizations
$ heroku authorizations:info <ID>

初期化

Terraform に有効な認証トークンができたので、プロバイダーを初期化できます。

$ terraform init

pg バックエンドを使用している場合も、初期化中にデータベースの資格情報を設定します(「リモートの Postgres バックエンドを設定する)​」を参照してください)。

$ terraform init -backend-config="conn_str=$DATABASE_URL"

init​ が正常に完了したら、provider​ が変わった場合 (資格情報のローテーションなど)、または新しいコンピュータに Terraform を設定する場合以外は、再度この処理を実行する必要はありません。

空のアプリをプロビジョニングする

Terraform のリソースに関する完全なリファレンスは、Heroku プロバイダーのドキュメント​で参照できます。

アプリのリソースを追加する

Heroku アプリのリソース​を main.tf​ ファイルに追加します。

variable "example_app_name" {
  description = "Name of the Heroku app provisioned as an example"
}

resource "heroku_app" "example" {
  name   = var.example_app_name
  region = "us"
}

このファイルにより、terraform apply​ コマンドに指定する名前を使用して空の Heroku アプリをプロビジョニングするよう、Terraform に指示します。

アプリの Heroku 名とは別に、この特定のリソース用の Terraform の識別子は heroku_app.example​、リソースタイプ、およびリソースの名前です。この識別子は、設定や、インポート​または状態の表示​などの操作で変数​として使用される可能性があります。

プランと適用

terraform apply​ コマンド​を使用して、main.tf​ に保存した設定を適用します。

sushi​ をアプリの一意の名前に置き換えます。

$ terraform apply -var example_app_name=sushi

上記のコマンドを 2 つのコマンドに分割して、プランを確認してから正確に適用できるようにします。

$ terraform plan -var example_app_name=sushi -out=current.tfplan
$ terraform apply current.tfplan

Terraform のコアワークフロー​についての詳細を参照してください。

apply​ が正常に完了すると、Terraform によって作成されたリソースが Terraform の認証トークンに関連付けられている Heroku アカウントに提示されます。

Terraform の現在の状態を表示して、作成されているものを確認します。

$ terraform show

ローカルバックエンド​を使用する場合、terraform show​ の出力は terraform.tfstate​ ファイルの内容に基づきます。リモートバックエンドを使用する場合、この出力はバックエンドの状態ストアの内容に基づきます。

コードをアプリにデプロイする

Terraform を使用して「空のアプリをプロビジョニングする​」でプロビジョニングした空のアプリケーションにコードをデプロイするには、次のコードに合わせて main.tf​ を更新します。

terraform {
  required_providers {
    heroku = {
      source  = "heroku/heroku"
      version = "~> 5.0"
    }
  }
}

variable "example_app_name" {
  description = "Name of the Heroku app provisioned as an example"
}

resource "heroku_app" "example" {
  name   = var.example_app_name
  region = "us"
}

# Build code & release to the app
resource "heroku_build" "example" {
  app_id     = heroku_app.example.id
  buildpacks = ["https://github.com/mars/create-react-app-buildpack.git"]

  source {
    url     = "https://github.com/mars/cra-example-app/archive/v2.1.1.tar.gz"
    version = "2.1.1"
  }
}

# Launch the app's web process by scaling-up
resource "heroku_formation" "example" {
  app_id     = heroku_app.example.id
  type       = "web"
  quantity   = 1
  size       = "Standard-1x"
  depends_on = [heroku_build.example]
}

output "example_app_url" {
  value = heroku_app.example.web_url
}

設定を適用し、再びアプリ名を入力変数として渡します。

sushi​ を自分のアプリ名に置き換えます。

$ terraform apply -var example_app_name=sushi

terraform apply​ が正常に完了したら、設定の出力として入手できる Heroku アプリの URL にアクセスします。

$ terraform output example_app_url

サンプルを残しておく必要がない場合は、Terraform を使用してすべて消すことができます。

$ terraform destroy -var example_app_name=sushi

理解を深める

下の「例​」のセクションで、複雑なアーキテクチャのプロビジョニングに使用できる本格的な設定を示しています。このセクションでは、Terraform で行うことができるその他の作業を紹介するために、よりシンプルな一部分を示しています。

アプリとアドオンを作成する

この部分では、特定の Heroku チーム​と Heroku リージョン​にアプリリソース​とアドオンリソース​を作成しています。

variable "heroku_team" {
  description = "Name of the Team (must already exist)"
}

resource "heroku_app" "example" {
  name   = "${var.heroku_team}-example"
  region = "us"

  organization {
    name = var.heroku_team
  }
}

resource "heroku_addon" "papertrail_example" {
  app_id = heroku_app.example.id
  plan   = "papertrail:choklad"
}

この例のアプリの名前には、接頭辞としてチームの名前が使用されています。一貫してリソース名に接頭辞を付ける​と、Terraform によってプロビジョニングされたリソースの追跡がより簡単になります。

アプリをスケールする

この部分のスケールでは、Formation リソース​を使用して、既存のアプリをスケールしています。アプリが正常に起動するまで待機するために、ローカルコマンド (Provisioner のヘルスチェック)​ も実行しています。

resource "heroku_formation" "example" {
  app_id     = heroku_app.example.id
  type       = "web"
  quantity   = 2
  size       = "Standard-1x"
  depends_on = [heroku_app_release.example]

  provisioner "local-exec" {
    command = "./bin/health-check ${heroku_app.example.web_url}"
  }
}

Private Space を作成する

この部分では、Private Space リソース​を作成して、AWS リソースと同じリージョンに配置されるようにしています。

variable "heroku_enterprise_team" {
  description = "Name of the Enterprise Team (must already exist)"
}

variable "heroku_private_space" {
  description = "Name of the Private Space"
}

variable "aws_region" {
  description = "Amazon Web Services region"
  default     = "us-east-1"
}

variable "aws_to_heroku_private_region" {
  default = {
    "eu-west-1"      = "dublin"
    "eu-central-1"   = "frankfurt"
    "eu-west-2"      = "london"
    "ca-central-1"   = "montreal"
    "ap-south-1"     = "mumbai"
    "us-west-2"      = "oregon"
    "ap-southeast-1" = "singapore"
    "ap-southeast-2" = "sydney"
    "ap-northeast-1" = "tokyo"
    "us-east-1"      = "virginia"
  }
}

resource "heroku_space" "example" {
  name         = var.heroku_private_space
  organization = var.heroku_enterprise_team
  region       = lookup(var.aws_to_heroku_private_region, var.aws_region)
}

Google Cloud Platform への VPN 接続を作成する

この設定の一部では、Google Cloud VPC ネットワークを使用した Heroku Private Space の VPN 接続​ を設定します (完全な Terraform の例)​を参照してください)。

variable "heroku_vpn" {
  description = "Name of the Heroku VPN connection"
}

module "heroku_vpn_gcp" {
  source = "github.com/heroku-examples/terraform-heroku-vpn-gcp"

  // (config details omitted)
}

resource "heroku_space_vpn_connection" "google" {
  name           = var.heroku_vpn
  space          = heroku_space.example.id
  public_ip      = module.heroku_vpn_gcp.google_vpn_ip
  routable_cidrs = ["${module.heroku_vpn_gcp.google_cidr_block}"]
}

例

次の例では、Heroku のリソースに加え、Amazon AWS や Google Cloud Platform のリソースを設定する、詳細な Terraform 設定を示しています。

  • Private Space と Amazon VPC をピアにする
  • Private Space と Google Cloud Platform の間の VPN 接続を作成する

ベストプラクティス

設定がずれないように注意する

Terraform で管理されているリソースを Heroku Dashboard または Heroku CLI を使用して変更しないでください。​Terraform の設定が適用された後に Terraform の外部​からリソースを変更すると、Terraform が自身の設定と同期されていない状態になります。

dyno のスケーリング、環境設定の設定、およびアドオンの変更は、すべて Terraform の設定をアップデートして再適用することによって行う必要があります。そうしないと、設定の違いにより、ずれてしまった値を (新しいリソースに) インポートするか手動で状態をアップデートするまで、それ以上の適用または破棄ができなくなります。

詳細は、「Detecting and Managing Drift with Terraform​」(Terraform を使用したずれの検出と管理) を参照してください。

接頭辞に一貫した名前を使用する

Terraform で管理されているリソースを Heroku Dashboard または Heroku CLI で表示すると、リソースの相互関係がわかりにくくなる可能性があります。各設定内でリソース名に一貫した接頭辞を付けると、この関係性がかなり把握しやすくなります。

たとえば、次のように prefix​ 入力変数を使用します。

variable "prefix" {
  description = "High-level name of this configuration, used as a resource name prefix"
  type        = "string"
}

resource "heroku_app" "example-1" {
  name   = "${var.prefix}-example-1"
  region = "us"
}

resource "heroku_app" "example-2" {
  name   = "${var.prefix}-example-2"
  region = "us"
}

Terraform の設定ごとに 1 つの Heroku チームを使用する

Terraform 化されたリソースの管理の操作性を改善するために、Terraform の設定ごとに専用の Heroku チーム​を使用します。そうすると、専用の Heroku チームに Terraform でプロビジョニングされたものがすべて格納されます。入力変数としてチーム名を設定してから、その変数を使用して、設定内で各リソースにチームを設定します。

variable "heroku_team_name" {
  description = "Name of the Heroku Team owning this complete deployment."
  type        = "string"
}

resource "heroku_app" "example" {
  name   = "example"
  region = "us"

  organization = {
    name = var.heroku_team_name
  }
}

Provisioner のヘルスチェックを使用する

Terraform で作成されたリソースが、プロバイダーでは準備完了とされているのに、実際には「準備完了」ではないことがあります。このよい例が、HTTP ステータス 200 でリクエストに応答するまで準備完了とは見なされない Web アプリです。

Terraform では、この問題を Provisioner​ で解決します。Provisioner は、コマンドが失敗した場合に、Terraform でリソースの作成を待機し、デフォルトで失敗させる任意のコマンドです。

resource "heroku_formation" "sushi" {
  app_id     = heroku_app.sushi.id
  type       = "web"
  quantity   = 2
  size       = "Standard-1x"
  depends_on = [heroku_app_release.sushi]

  provisioner "local-exec" {
    command = "./bin/health-check ${heroku_app.sushi.web_url}"
  }
}

bin/health-check​ スクリプトの例を次に示します。

#!/bin/bash

# Check the health of the web service every thirty-seconds
# for up to ten minutes, until it responds with HTTP status 200.

fail_count=1
while true
do
  http_status=$(curl --write-out %{http_code} --silent --output /dev/null $1)

  if [ "$http_status" -eq "200" ]; then
    echo "$(date -u) health check succeeded to $1"
    exit 0
  else
    if [ "$fail_count" -eq "21" ]; then
      echo "$(date -u) health check failed (status $http_status) to $1"
      exit 2
    else
      echo "$(date -u) health check ${fail_count}/20 to $1"
      sleep 30
      fail_count=$[$fail_count +1]
    fi
  fi
done

インフラストラクチャと運用のリソースを設定する

Terraform を使用して、インフラストラクチャ​と運用​のリソースの組み合わせを設定できます。

インフラストラクチャリソースには、次のようなものがあります。

  • アプリ
  • アドオン
  • ドメイン
  • パイプライン
  • Private Space

これらのリソースがプロビジョニングされるときには、コードはまだ Heroku で稼働していません。コードは、引き続き、開発者がプラットフォームを通じて、またはTerraform で運用​リソースをプロビジョニングすることで、デプロイして起動する必要があります。

運用リソースには、次のようなものがあります。

  • ビルド
  • Slug
  • アプリのリリース
  • アプリの formation (つまり、dyno のスケール)

これらのリソースをプロビジョニングすると、Terraform でアプリのコードを直接デプロイして、完全なシステムを運用できます。これにより、複数のアプリを同時にリリースしたり、問題が発生した場合に共通のリリースロールバックを取りまとめたりすることができるようになります。

運用の設定に Terraform を使用している場合は、設定のずれ​が生じやすくなりますので注意してください。

リファレンス

  • Terraform のドキュメント
  • Terraform の Heroku プロバイダーのドキュメント

関連カテゴリー

  • デプロイ統合
slug チェックサム slug チェックサム

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices