最近Herokuで動かしている個人のサービスの構成をTerraformで管理するようにしてみたので、そのあたりのTerraformの使い方とか移管方法とかを備忘がてらMEMOしておきます📝
Terraformとは
Write, Plan, Apply
https://www.terraform.io/
上述の通りオープンソースのcloudサービスを統一したインターフェイスでコード化出来るソフトウェアです。
TerraformにはRegistryにProviderとよばれる公式や第三者が提供しているものがあり、AWS、GCP、GitHub、Rollbarといった色々なサービスをコードで管理出来るようです👀
https://registry.terraform.io/browse/providers
Terraformをインストールする
Terraformを使うには以下のドキュメントを参考にインストールが必要です。
しかし、Providerによって対応しているバージョンが違ったりするのでtfenv
を使って複数バージョンを切り替えられるようにしておくと便利です。
Terraformの基本的な使い方
Write, Plan, Apply
https://www.terraform.io/
上記の記載にある通りシンプルで基本的にTerraformのコードを書いてplan
で実行計画を確認し、apply
で反映出来ます。
$ terraform plan # 実行計画の確認 $ terraform apply # 実行の反映
詳しいコマンドの説明は公式ドキュメントを参照してください。
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管理下に置くことが出来ます。
あとから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動かすときにも便利そうだったので)
Terraform、シンプルな構文で色々コード化出来て便利ですね✨