仕事で Terraform をガッツリ触る機会があったのでキャッチアップでやったことや見た資料をざっと書く。Google Cloudに適用する、というコンテキスト。
雑に書くので結構間違いあるかもだがメモということで
必要なツールをインストール
Terraformのバージョンマネージャーである tfenv をインストールして tfenv install xxx
で対象バージョンのterraformをインストール。
.terraform-version
ファイルを用意してバージョン切り替えする。
補完やsyntax highlightの目的で、VSCodeなどの拡張機能を適宜インストール。
HashiCorp Terraform
インストールしたら対象のワークディレクトリで terraform init
してモジュールなどをダウンロード。
フォーマッタとtflintとバリデーションの整備
tflint やプロバイダーのplugin入れたり、CIやMakefileで実行したり、 tarraform-docs を導入して自動でドキュメントを生成したり。
tflint
terraform validate
terraform fmt
コマンドを叩いて色々確認
planコマンドを叩いたりapplyしてみたり
terraform plan
# 対象モジュール・リソース指定: 同時並行で色々やってるときに開発環境に試し適用するときに使ったり
terraform plan -target module.{module_name}
terraform plan -target module.{module_name}.{resource}.{resource_name}
terraform apply
terraform apply -target module.{module_name}
terraform apply -target module.{module_name}.{resource}.{resource_name}
terraform自体の勉強
基本的な書き方をキャッチアップしつつ以下の記事を読んで作法やTerraform利用時の課題感を理解
lifecycle {
prevent_destroy = true
}
でterraformからの誤った削除を防止したり
リソース自体に削除防止機能があればそれを有効化しておく。
Cloud SQLだと deletion_protection = true
を指定したり。
tosetで変数を使いたい場合はキーがknown valueじゃないといけないので、outputやリソース参照などknown valueじゃない場合は keyがknown valueなmapを使ったりして対応。
リソース名は変更するとdestroy/createになるので注意。 terraform mvとかmovedブロックを使うことになる。
dataブロックを使うとproviderの情報を良い感じに使うことができて便利
GitHub Actionsによる自動plan/apply
手元でデプロイしても良いが自動化したくなったりミスオペ怖かったりするのでCI/CDした。 手元でデプロイする場合も権限はCI/CDで実行するユーザ(workfload identity)にimpersonateするように調整した。
tfcmt というterraform plan/applyの結果をGitHubのPRにコメントしてくれるツールがあるのでそれを使ったり。tfaction は色々terraform系の処理をやってくれるGitHub Actionsのツール群。
plan時にplan fileを吐き出せて、そのplan fileを使ってapplyできる。 そうすることで追い越し実行時のstaleなapplyの実行を制御できたりするので堅牢な実行ができそう。
GitHub ActionsでGoogle Cloudに対してTerraformを実行するにあたり、Workload identityというOIDCな認証方式を利用した。 権限は比較的強い権限を与えても良いのだが、PikeというHCLファイルを読み取って必要な権限を出力してくれるツールがあるのでそれでカスタムロールを作って割り当てる方式でやったりしてる。ただ結構運用は大変。
import
importブロックを使って既存リソースをインポートを試す。
ちなみに terraformer という既存リソースをterraformで表現してくれるツールがあったりする。
リソースのリファレンスを読む
新規のリソースを書いたり設定をいじる場合にリファレンスを読んだ
tfstateの中身を読む
どういうデータが入っているのかをざっと見る。 注意しないとパスワードとかも意外と入っているよ、とか。
ignore_changesに入れて対応できればそれで、対応できなければ手動変更とか。
Gemini
だいたいわからないところがあれば初手でGeminiに聞いて、そのあとリファレンス見たりググったりして理解を深めた。 比較的良い感じな回答が返ってきたと思う。
基本機能や設計などの記事を読み込む
- Terraform設計ガイドライン
- Terraform ベストプラクティスを整理してみました。
- Terraform職人再入門2020
- Terraform職人入門: 日々の運用で学んだ知見を淡々とまとめる
- 「それ、どこに出しても恥ずかしくないTerraformコードになってるか?」
その他
何でもかんでもTerraformで管理、というよりは管理すべきものをそうでないものがありそう。 例えばDatadogのダッシュボードなんかは結構コード管理すると大変とか(コード化自体は難しくないが、そのあとの運用が回るイメージが無い) そもそもTerraform化できない要素もあるようなので、本番環境構築手順書的なものは無くならなそうとか。
ここは組織構成や習熟度とか課題感を見据えて各々ベストプラクティスを探っていくのが良いのかも。 多分モジュール設計もそんな感じっぽい。dev/stg/prodくらいの運用であればcommonモジュールだけ入れて差分は各環境のmain.tfなりで調整するのが良いのかなと思っていたりする。
まとめ
手を動かすのがマジで大事。
planとかapplyのコマンドを打ってupdateやdestroy/createのパターンを見てみる、とか。 plan fileでstaleな状態にさせてapplyするとどうなるか、とか。
あとWeb/DBなアプリだとある程度構成は似通うので横展開も比較的しやすそうなイメージ。