Skip Navigation
Show nav
Heroku Dev Center
  • Get Started
  • ドキュメント
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
  • ドキュメント
  • 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 (アプリコンテナ)
    • スタック (オペレーティングシステムイメージ)
    • ネットワーキングと DNS
    • プラットフォームポリシー
    • プラットフォームの原則
  • コマンドライン
  • デプロイ
    • Git を使用したデプロイ
    • Docker によるデプロイ
    • デプロイ統合
  • 継続的デリバリー
    • 継続的統合
  • 言語サポート
    • Node.js
    • Ruby
      • Bundler の使用
      • Rails のサポート
    • Python
      • Django の使用
      • Python でのバックグランドジョブ
    • Java
      • Maven の使用
      • Java でのデータベース操作
      • Play Framework の使用
      • Java の高度なトピック
      • Spring Boot の使用
    • PHP
    • Go
      • Go の依存関係管理
    • Scala
    • Clojure
  • データベースとデータ管理
    • Heroku Postgres
      • Postgres の基礎
      • Postgres のパフォーマンス
      • Postgres のデータ転送と保持
      • Postgres の可用性
      • Postgres の特別なトピック
    • Heroku Redis
    • Apache Kafka on Heroku
    • その他のデータストア
  • モニタリングとメトリクス
    • ログ記録
  • アプリのパフォーマンス
  • アドオン
    • すべてのアドオン
  • 共同作業
  • セキュリティ
    • アプリのセキュリティ
    • ID と認証
    • コンプライアンス
  • Heroku Enterprise
    • Private Space
      • インフラストラクチャネットワーキング
    • Enterprise Accounts
    • Enterprise Team
    • Heroku Connect (Salesforce 同期)
    • シングルサインオン (SSO)
  • パターンとベストプラクティス
  • Heroku の拡張
    • Platform API
    • アプリの Webhook
    • Heroku Labs
    • アドオンのビルド
      • アドオン開発のタスク
      • アドオン API
      • アドオンのガイドラインと要件
    • CLI プラグインのビルド
    • 開発ビルドパック
    • Dev Center
  • アカウントと請求
  • トラブルシューティングとサポート
  • デプロイ
  • デプロイ統合
  • Heroku で Terraform を使用する

Heroku で Terraform を使用する

日本語 — Switch to English

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

最終更新日 2019年07月09日(火)

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:hobby-dev --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"

​heroku-postgresql​ アドオンを作成する場合、​hobby-dev​ データベースプランは無料で、多くのユースケースにはこれで十分です。パフォーマンスを最大化し、より重要なユースケースで可用性を向上させるには、​standard-0​ や ​premium-0​ などの​有料プラン​ を設定することを検討してください

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

​

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

​

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

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

​

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

​

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

​

設定

​

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

provider "heroku" {
  version = "~> 2.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​ を更新します。

provider "heroku" {
  version = "~> 2.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 = "${heroku_app.example.name}"
  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        = "${heroku_app.example.name}"
  type       = "web"
  quantity   = 1
  size       = "Standard-1x"
  depends_on = ["heroku_build.example"]
}

output "example_app_url" {
  value = "https://${heroku_app.example.name}.herokuapp.com"
}

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

​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  = "${heroku_app.example.name}"
  plan = "papertrail:choklad"
}

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

​

アプリをスケールする

​

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

resource "heroku_formation" "example" {
  app        = "${heroku_app.example.name}"
  type       = "web"
  quantity   = 2
  size       = "Standard-1x"
  depends_on = ["heroku_app_release.example"]

  provisioner "local-exec" {
    command = "./bin/health-check http://${heroku_app.example.name}.herokuapp.com""
  }
}

​

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"
    "us-west-2"      = "oregon"
    "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.name}"
  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 設定を示しています。

  • ​API ゲートウェイを使用したマイクロサービス​
  • ​パイプラインから slug をデプロイする​
  • ​Private Space と Amazon VPC をピアにする​
  • ​Private Space と Google Cloud Platform の間の VPN 接続を作成する​

​

ベストプラクティス

​

​

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

​

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

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

​

Terraform 化されたアプリの名前を変更しないようにする

​

Terraform にプロビジョニングされたアプリの名前を変更すると、先に手動で ​terraform.tfstate​ を新しい名前に改訂するまで、Terraform では、関連付けられているリソースにアクセスできなくなります。詳細については、​terraform-provider-heroku​ の ​#124​ と ​#93​ の Issues を参照してください。

​

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

​

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        = "${heroku_app.sushi.name}"
  type       = "web"
  quantity   = 2
  size       = "Standard-1x"
  depends_on = ["heroku_app_release.sushi"]

  provisioner "local-exec" {
    command = "./bin/health-check https://${heroku_app.sushi.name}.herokuapp.com/"
  }
}

​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 プロバイダーのドキュメント​

関連カテゴリー

  • デプロイ統合
実行可能な JAR ファイルのデプロイ slug チェックサム

Information & Support

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

Language Reference

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

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing

Subscribe to our monthly newsletter

Your email address:

  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Heroku Podcasts
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Facebook
  • Instagram
  • Github
  • LinkedIn
  • YouTube
Heroku is acompany

 © Salesforce.com

  • heroku.com
  • Terms of Service
  • Privacy
  • Cookies