Madogiwa Blog

主に技術系の学習メモに使っていきます。

Herokuの構成をTerraformで管理してみるMEMO📝

最近Herokuで動かしている個人のサービスの構成をTerraformで管理するようにしてみたので、そのあたりのTerraformの使い方とか移管方法とかを備忘がてらMEMOしておきます📝

Terraformとは

Write, Plan, Apply
https://www.terraform.io/

上述の通りオープンソースのcloudサービスを統一したインターフェイスでコード化出来るソフトウェアです。

TerraformにはRegistryにProviderとよばれる公式や第三者が提供しているものがあり、AWSGCPGitHub、Rollbarといった色々なサービスをコードで管理出来るようです👀

https://registry.terraform.io/browse/providers

Terraformをインストールする

Terraformを使うには以下のドキュメントを参考にインストールが必要です。

learn.hashicorp.com

しかし、Providerによって対応しているバージョンが違ったりするのでtfenvを使って複数バージョンを切り替えられるようにしておくと便利です。

github.com

Terraformの基本的な使い方

Write, Plan, Apply
https://www.terraform.io/

上記の記載にある通りシンプルで基本的にTerraformのコードを書いてplanで実行計画を確認し、applyで反映出来ます。

$ terraform plan  # 実行計画の確認
$ terraform apply # 実行の反映

詳しいコマンドの説明は公式ドキュメントを参照してください。

www.terraform.io

Heroku Providerを使ってみる

HerokuをTerraformで管理するためには以下の公式が提供しているHeroku Providerを利用します。

https://registry.terraform.io/providers/heroku/heroku

※2021/09/25時点ではHeroku Providerは0.12.xが推奨です link

以下のようなmain.tfといった任意の拡張子が.tfで終わるファイルを作成しterraform initでProviderのコードをinstallします。

provider "heroku" {}

あとはHerokuに接続するために以下のような形で環境変数を設定すればOKです 🙆‍♂️

export HEROKU_EMAIL="your heroku email"
export HEROKU_API_KEY="your heroku api key"

環境変数ではなくてproviderに直接渡すことも出来ます。

provider "heroku" {
  email   = "ops@company.com"
  api_key = var.heroku_api_key
}

以下からざっくりサンプルコードを載せていますが、詳しい説明は公式ドキュメントをご確認ください。

https://registry.terraform.io/providers/heroku/heroku/latest/docs

Appの作成

Appを作るにはresource heroku_appを使って以下のようなコードを記載します。

resource "heroku_app" "app" {
  name = "example-app"
  region = "us"
  # (Optional) not necessary if you are only using assets precompile.used only assets:precompile
  buildpacks = ["heroku/nodejs", "heroku/ruby"]
  # (Optional) enviroment variables.
  # config_vars = {
  #   FOOBAR = "baz"
  # }
  # sensitive_config_vars = {
  #   SENSITIVE_FOO_BAR = "baz"
  # }
}

Addonの追加

Addonの追加するにはresource heroku_addonに使いたいaddonと定義したAppを指定して以下のようなコードを記載します。

resource "heroku_addon" "database" {
  app = heroku_app.app.name
  plan = "heroku-postgresql:hobby-dev"
}

resource "heroku_addon" "redis" {
  app = heroku_app.app.name
  plan = "heroku-redis:hobby-dev"
}

Formationの追加

以下のようなProcfileを用意していてweb/workerを立てたいような場合には、

web: bin/rails server -p ${PORT:-5000} -e $RAILS_ENV
worker: bundle exec sidekiq 

以下のような形でheroku_formationを使用しweb/workerのsizeやquantityを管理することが出来ます。

resource "heroku_formation" "web" {
  app = heroku_app.app.name
  type = "web"
  size = "hobby"
  quantity = var.web_quantity
}

resource "heroku_formation" "worker" {
  app = heroku_app.app.name
  type = "worker"
  size = "hobby"
  quantity = var.worker_quantity
}

既存のHerokuの構成をimportする

すでにHerokuで構築しているサービスをあとからTerraformで管理するにはterraform importが便利です。 Terraformは構成情報をstateで管理しているのですが、importを使用すると現在の構成情報をstateに反映しTerraform管理下に置くことが出来ます。

www.terraform.io

あとからTerraformで管理する場合には以下のように管理したいResources単位でimportを行っていって、stateからterraformのコードを書くような形で段階的に移行するようなことも出来ます。

$ terraform import heroku_app.app example-app
$ terraform import heroku_addon.database database-addon-id
$ terraform import heroku_formation.web example-app:web

おわりに

今回記載した内容を元にRailsをHerokuで動かすときに使いそうな構成をTerraformで記載してみたものをGitHubに公開してみました🐙 (あとで自分でHerokuでRails動かすときにも便利そうだったので)

github.com

Terraform、シンプルな構文で色々コード化出来て便利ですね✨

参考

devcenter.heroku.com

dev.classmethod.jp

kazuhira-r.hatenablog.com