Google CloudリソースをTerraformで一元管理した話
はじめに
こんにちは!株式会社CastingONEでHR領域のSaaS開発を行っている@hiroakiです。
先日マルシンスパというサウナに行った際、アウフグースをしてもらいました!気持ち良いのはもちろん、熱波師さんのパフォーマンスが楽しく非常に心地よい体験でした✨
ということで今回はGoogle Cloudのリソースを全てTerraform管理にした話をしていきます。どのように進めていったか、どのようなメリットがあったかなどを紹介していきます。同じようにTerraformでリソース管理したい方々の参考になれば幸いです!
背景
CastingONEでは元々Cloud Deploy Manager(以降CDMと表記)でリソースを管理していました。CDMはGoogle Cloudのサービスであるため、Google Cloud内のリソースを統合的に管理するのに適していましたが、開発が2020年にストップしており新しいサービスやリソースタイプのサポートが難しくなっていました。そこで、新規リソースについてはTerraformを使って作成/管理することとなりました。
このような経緯から、リソースはCDM由来のものとTerraform由来のものが混在しており、リソースの管理が分散してしまいました。
この分散管理の問題を解決するために、全てのリソースをTerraformで一元管理することにしました。
進め方
Project発足
1人でやるのも大変 & 社内でTerraformを扱える人が多くなった方が今後良さそう!ということで有志でメンバーを募って進めていきました。
想像以上に興味を持ってもらい、最終的に7人で進めることになりました。
Ops周りの整備
複数人で進めるために、planやapplyのプロセスを整備しました。
planについてはCIに組み込み、PRをトリガーにterraform planが走るようにしました。また、tfcmtを用いてplan結果がPRのコメントに出力されるようにしました。
applyについてはCDに組み込むことも検討しましたが、planがうまくいってもapplyがうまくいかないこともあるため、他の方法を検討しました。代わりにPRのコメントに/terraform apply
と入力するとapplyが走り、その結果がPRのコメントに出力されるようにしました。
最終的な流れは以下の通りです。
- TerraformのPRを出す
- レビュアーはPlanの結果とコードをもとにレビュー
- approveをもらったらコメントにてapplyを実行
- applyの結果を確認し、問題がなければマージ
ちなみにPRでterraform applyできるのはdev環境のみで、prd環境等は限られたメンバーのみ実行できるようにしています。
環境
CastingONEではdev, qa, stg, prd環境を運用しています。
Directory構成は大まかには以下のようになっており、modulesで共通の型を用意し、各環境の変数は各環境のmain.tfやvariables.tfにて管理しております。
.
├── dev
├── modules
├── prd
├── qa
└── stg
移行の進め方としては、まずはdevを進めていきました。modulesとdevディレクトリを整えた上で、他の環境に横展開していきました。
移行作業
Terraform以外の手段で作成したリソースをTerraformで管理するためには、tfstateを書き換える必要があります。tfstateはTerraformのコードとリソースのIDを紐づける状態管理ファイルです。
この紐付けを行うために、importブロックを使用します。
例えば、以下のようなimportブロックを記述し、terraform applyを実行すると、Cloud TasksのTerraformコードとGoogle Cloudのリソースを紐づけることができます。
/****************************************
Cloud Tasks
****************************************/
import {
for_each = local.cloud_tasks_queues
id = "projects/${local.gcp_project}/locations/${local.region}/queues/${each.value.name}-${local.env}"
to = module.cloud_tasks.google_cloud_tasks_queue.default[each.value.name]
}
また、リソースによっては、今回のTerraform移行を機にfor文で書き換えたいリソースも出てきました。そのような場合は、以下のmoveブロックを記述してapplyを実行することで、moduleの移行をtfstateに記録することができます。
moved {
from = module.gcs_public.google_storage_bucket.default
to = module.gcs.google_storage_bucket.default["casone-lite-public-dev"]
}
このようにして、移行対象のTerraformコードとimport、moveブロックを記述し、Terraform移行作業を進めていきました。
importブロックの登場とそのメリット
importブロックはterraform v1.5(2023年5月)からリリースされたため、それ以前はコマンドによってimport管理をしていました。
例えば先ほど例に出したCloud Tasksのimportは以下のようなコマンドをたたく必要がありました。
terraform import module.cloud_tasks.google_cloud_tasks_queue.default[リソース名] projects/[project名]/locations/[region名]/queues/[リソース名]
コマンド1つだけだとそんなに大変ではないのですが、大量のリソースを一度にインポートする際には、個別のコマンド実行が煩雑で時間がかかり、間違いも発生しやすいという問題があります。importブロックの導入により、これらの課題が解消され管理が容易になりました。
全てのリソースをTerraform管理にして良かった話
全てのリソースをTerraformで管理することによるメリットは多くありました。
まず、リソースの管理が非常に楽になりました。CDMのファイルを確認する必要がなくなり、開発する際もTerraformのコードやapplyだけで済むようになりました。また、リソースの削除が迅速かつ簡単にできるようになったのも大きな利点です。
さらに、環境の分離が容易になったことも大きなメリットです。CastingONEでは、prd用とdev用のGCPプロジェクトを扱っていますが、以前はQA環境とSTG環境がprd用のプロジェクト内に存在しており、非常によろしくない状況でした。CDMとTerraformにリソースが分かれていた時は、この分離が困難でしたが、Terraformで一元管理することで、スムーズに環境を分離できるようになりました。
このように、全てのリソースをTerraformで管理することで、多くのメリットを享受することができました。
おわりに
今回はTerraformでGoogle Cloudのリソースを全て管理した話を書いてみました。Terraformでリソースを管理することで、リソースの管理が容易になり、環境の分離もスムーズに行えるようになりました。Terraformでリソース管理を検討している方は、ぜひ参考にしてみてください!
CastingONEではいっしょに働いてくれるエンジニアを募集中です。社員でもフリーランスでも大歓迎なので、ご気軽にご連絡ください!
Discussion