しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Terraform Cloud を使った Azure リソースの管理を試した

今後も Terraform を使っていくことが多そうですが、状態ファイルの意識した CI / CD パイプラインの作成は地味に手間です。その辺りを簡単にするために Terraform Cloud を試してみました。

正直 GitHub Actions や Azure Pipelines で良いと思っていましたが、当然ながら Terraform に特化した機能が用意されているので結構便利に使えました。5 ユーザーまで無料です。

無料以上のプランにするとユーザー数課金になるので、思ったより高くなりそうだなという印象です。

今回は GitHub で公開していた以下のリポジトリを使って試しています。Monorepo で dev / prd を管理するようになっていますが、Monorepo はあまりお勧めしないようなことがドキュメントに書いてありました。

一先ずは GitHub で Pull Request を作成して、それをマージすれば Azure 上の環境に反映されるというところまで試しました。最低限の内容ですが、はまるポイントは状態ファイルの扱いなので十分です。

環境毎の分離や、本番環境でのフロー構築は Terraform Cloud の機能で十分実現できそうだったので、そっち方面にはあまり深掘りはしていません。

Workspace を作成する

Terraform CLI にも workspace という機能がありますが、Terraform Cloud の Workspace はまた別の概念になっています。Workspace 単位で状態が管理されるので、こっちの方が分かりやすいと思います。

1 repo に対して複数の Workspace を作れるので、環境毎に分けるのが基本的な構成でしょう。

f:id:shiba-yan:20200910155619p:plain

Workspace を作成すると Configuration のチェックが走って、しばらくすると terraform plan を UI から実行できるようになります。CI SaaS ではよくある手動トリガーですね。

f:id:shiba-yan:20200910160002p:plain

とりあえず適当に実行してみると、よく見る Terraform CLI の実行結果が表示されます。Terraform 専用だからか CI SaaS を使うよりも、スピンアップがかなり速いように感じます。

f:id:shiba-yan:20200910160040p:plain

今回のサンプルは envs/dev 以下にメインとなる tf ファイルを置いているので、Terraform Cloud でも Workspace の設定から Terraform CLI を実行するディレクトリを設定しておきます。

この辺りの構成についてはドキュメントにも書いてあるので読んでおくと良いです。Monorepo にも Terraform Cloud は対応できますが、構成ごとに repo を分けつつ、Private Module を利用することを推奨しています。

Terraform CLI を実行するディレクトリは設定にある "Terraform Working Directory" で指定します。

f:id:shiba-yan:20200909174746p:plain

これで正しく Terraform CLI の実行が行えるようになります。必要な remote backend の設定は Terraform Cloud が自動的にやってくれるため、tf ファイルに backend を追加する必要はありません。

Azure Resource Manager の認証情報を設定する

Workspace の設定後に Plan を実行すると、今度は Azure CLI 周りのエラーが出ます。

f:id:shiba-yan:20200910160432p:plain

これはお馴染みの Azure 認証情報が未設定のエラーなので、対象となるサブスクリプションに対する権限を持つ Service Principal を作成して環境変数に設定します。

Service Principal の作成方法と環境変数名はドキュメントにまとめられています。

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret

作成した Service Principal の情報は Workspace の Variables から環境変数として設定します。

f:id:shiba-yan:20200909174606p:plain

メジャーなパブリッククラウド向けには入力補助があると嬉しいなと思いました。これで再度 Terraform Plan を実行すると、今度は正常に終了します。

f:id:shiba-yan:20200910160747p:plain

デフォルトでは Terraform Plan が成功すると、今度は Apply 待ちの状態になるため手動で承認するかどうかを選ぶ必要があります。この辺りは CLI での実行に近いです。

f:id:shiba-yan:20200910161020p:plain

ここで Apply を選ぶと、Azure にリソースが作成されて正常に実行されたことを確認できます。

f:id:shiba-yan:20200910161713p:plain

GitHub Actions や Azure Pipelines を使って自前で Terraform の CI / CD パイプラインを作成するよりも、Terraform Cloud なら圧倒的に簡単に用意できました。

作成された tfstate ファイルは UI から簡単に確認できますし、差分も分かりやすく見られます。

f:id:shiba-yan:20200910194954p:plain

Azure の場合は Blob Storage に tfstate を保存するための設定やリソースを用意する必要がありましたが、その辺りも Terraform Cloud では不要なのがかなり良いです。

GitHub との連携を確認する

最後に基本的な GitHub を利用したフローを確認しておきます。と言っても Pull Request ベースでの話です。

Terraform Cloud の設定済みの repo で Pull Request を作成すると、他の CI SaaS を利用した時と同様に Terraform Plan が走ります。GitHub から結果のサマリーを確認できるのは地味に良いです。

f:id:shiba-yan:20200910162159p:plain

当然ながら Pull Request の場合は Terraform Plan までの実行で Apply までは進みません。何故かこのログは Workspace の実行履歴からは見られないので、Pull Request から飛ぶ必要があります。

マージを実行すると Apply まで進みますが、デフォルトの設定だと以下のように手動での承認が必要です。

f:id:shiba-yan:20200910162516p:plain

Plan の確認が終わった後にマージされるのが基本なので、設定を変えて自動で Apply されるようにします。デフォルトでは Manual apply になっているので、ここを Auto apply に変更します。

f:id:shiba-yan:20200910162609p:plain

実際の運用フェーズに入ると GitHub と Terraform Cloud を行ったり来たりはしたくないので、マージ出来る人を GitHub で制限する方が便利そうです。

これで再び Pull Request を作成して、マージすると自動で Apply まで実行されて変更が反映されます。

f:id:shiba-yan:20200910163450p:plain

Terraform は状態を常に 1 つだけ持つので、GitHub の Branch protection rules から "Require branches to be up to date before merging" を有効化しておくと、Pull Request のマージ先ブランチが更新された時に、取り込まないと進めなくなるので安全です。

f:id:shiba-yan:20200910163352p:plain

最初にも書きましたが Terraform Cloud は 5 ユーザーまで無料で使えるのと、はまりやすい状態ファイルの管理から解放されるので、利用を検討する価値はあると思います。

アプリケーションのビルドとデプロイは GitHub Actions、リソースの管理は Terraform Cloud という形での使い分けが一番良いのかもと思い始めました。

こういうドメインに特化したサービスは今後さらに増えそうです。便利なので使っていきたいです。