この記事は terraform Advent Calendar 2024 の 3 日目です。
- 前日: raki さんによる Terraform のバージョン制約
- 翌日 bgpat さんによるTerraform の Provider-defined Function はどうやって実装されているのか
tl; dr
- 安全に試行錯誤できるサンドボックス環境を用意し、まずは手作業でリソースを組み上げる
- 概ねでき上がったら
import
ブロックを活用しながらローカル環境でterraform plan
/apply
を行う - 最終的な tf ファイルの Pull Request を出す
問題意識
AWS 等におけるクラウドリソースをいきなり Terraform で記述することは簡単ではないことも多いです。
特に、そのサービスを触るのが初めての時などは、どのリソースを使用するべきかというところからして自明でないことも多いでしょう。
また、Terraform のような IaC ツールは、チームや企業で使ってこそ本来の威力を発揮するものだと思います。ですが、通常利用者の間には Terraform や対象のクラウドサービスについての習熟度にばらつきがあるものです。より広く Terraform を活用してもらうためには、なるべく難しくないやり方を提供する必要があるでしょう。
想定読者
- 企業で Terraform の CI/CD パイプラインといったプラットフォームの構築に関わる方
- 「どのように使ってもらうのか」を考えて明確にする助けになればと思います
- 業務の中で Terraform を利用する必要があるが、苦手意識がある方
- 「こんなふうにやればいいのか」と感じていただければ幸いです
- ただし、この記事の内容を実践するには前提としてのプラットフォームも必要です。それらを構築する役割の人々が別にいるなら、その人々とよく話しながら具体化すると良いでしょう
この記事における前提
- そのクラウドサービスを利用する上での安全なサンドボックス環境がある
- サンボックス環境に対して、ローカルから
terraform plan
/apply
を実行できる状態になっている - Terraform のための CI/CD パイプラインが存在し、利用できる
手順1: サンドボックス環境上で手作業でリソースを組み上げる
おいおい、手作業で構築なんかしちゃって大丈夫なのかい、と思う方もいるかもしれません。
ですが、ここで重要なのは、「手作業でも問題のない環境を用意」して、「手作業で問題のないことだけをやる」です。
「手作業でも問題のない環境」というのは以下のようなものを指します:
- 本番環境等の問題が起きたら困る環境とは完全に切り離されている
- ログインには SSO のような安全のような方法を利用する
- AWS であれば、IAM User のような秘密鍵が漏れると危ない方法は利用しない
- 危ない設定をしてしまっても、自動的・継続的に検知されるような状態になっている
- AWS であれば Seucurity Hub や GuardDuty などが利用できます
- どの程度の設定ができている必要があるか、は企業の規模や起こり得るリスクなどによっても変わるでしょう
- コストが高すぎたり急激な変化があった時には気づける状態になっている
- AWS であれば Cost Anomaly Detection 等が利用できます
- 攻撃によりビットコイン等のマイニングが行われるような場合だけでなく、検証が終わってるのに放置されているリソースでの無駄遣いにも気づけると良いでしょう
また、「手作業で問題のないこと」というのは以下を指します:
- あくまでも検証・学習のための試行錯誤として作るものであり、最悪壊れても構わないものとして構築する
- (問題のない環境で満たされるが) 間違っても本番環境等の設定を変更するようなことはしない
- 間違った環境での作業を避けるため、本番環境ではそのための権限をそもそも割り当てなかったり、割り当てるとしても PIM のような仕組みを使うのが良いでしょう
そしてここでの重要なポイントは、「以下に小さなサイクルで高速に試行錯誤を繰り返すか」です。
初めてのサービスにおいては、そもそもどのようなリソースにどのようなパラメータを渡す必要があるのか、どのようなリソースを組み合わせる必要があるのか、ビジネス上の要件を満たすにはどのような設定にする必要があるのか、ということを検証して行く必要があります。
そのためには、GitHub に Terraform のコードを push して、CI/CD パイプラインの完了を待って、問題があったらまた修正して push して… というサイクルでは時間がかかり過ぎます。
試行錯誤を高速に回すことの重要性は以前にも書いています:
手順2: import
ブロックを活用しながらローカル環境で terraform plan
/apply
を行う
手作業での構築が完了し、どういったリソースが必要なのかの全体像が見えたら、そこで初めて Terraform のコードに落とし込みます。
この作業については、2023 年に Terraform v1.5.0 で登場した import
ブロックにより圧倒的にやりやすくなりました。 (それまでは terraform import
コマンドを使ってひとつひとつインポートするような作業が必要でとても面倒でした)
インポート対象のリソースは Provider のドキュメントから探し、インポートに必要な ID を特定します。基本的にドキュメントの最下部に書いてあります:
ドキュメントを見ながらわかる範囲でパラメータを指定し、terraform plan
を実行してエラーが出たら修正し、plan に差分があるようなら必要な範囲でパラメータを追加して差分を無くして行くことで基本的な流れです。
もちろん、作業の過程でより正しい設定値に気づくこともあるので、その差分が意図に合致するものであればそのまま terraform apply
してしまっても良いでしょう。
手順1でやるべきことは「リソースを正しい状態で組み上げること」で、そのための試行錯誤をできるだけ高速に繰り返すということでした。
そこから「そのリソースを Terraform で表現するコードに落とし込む」ための試行錯誤をできるだけ高速に繰り返すのがこの手順2です。
手順3: 最終的な tf ファイルの Pull Request を出す
手順1, 2 はサンドボックス環境での作業でした。
これを本番環境なり、その手前の環境に持って行くのがこの手順 3 です。
基本的には手順 2 で作ったコードをコピペする感じですが、その環境に依存する値がある場合は修正が必要になります。AWS であれば AWS アカウント ID を含む ARN 等がこれにあたります。
この辺はうまく変数化して抽象化することで、変数だけ書き換えれば良い状態の tf ファイルにすることもできますが、この辺はまぁやりながら慣れていくしかないですかね…
その他のアプローチ
terraformer を使う
terraformer は既存のクラウドリソースをもとに tf ファイルを生成するものです。
もし対象リソースがものすごく多いような場合は、手順 2 のステップをこれを使ってやることも考えられますが、対象のリソースを指定するには正しくタグを指定しておく必要があるなど、そんなに簡単ではない印象です。
手順 2 で手作業で tf ファイルを書いて行くのは面倒でもありますが、対象のリソースに対する学習も必要なのだとすると、差分となるパラメータを調べながらやって行くことも無駄ではないとは思います。
終わりに
私が初めて触るサービスのリソースを Terraform 化するときの手順を紹介しました。
私自身、常にこの手順を厳密に守ってやっているわけではなく、対象リソースの多さや複雑さなどによってもグラデーションがあります。
ここで大事なのは常にこの手順を遵守することではなく、「今の自分の問題を解決するために、どうやったら試行錯誤をできるだけ速く繰り返せるか」を意識することだと思います。
Terraform を利用する上で工夫しているやり方などあれば、是非はてなブックマークや X で @yuya_takeyama までコメントいただければ幸いです。