Lenetではクラウドインフラを宣言的構成で管理するようにしていて、メインのクラウドプロバイダーとしてGCPを、インフラのコード管理のためにTerraformを使用しています。
背景
インフラを変更するときは編集者権限を持つインフラチームが手元のPCでterraform
コマンドを実行するというのが基本の流れでした。閲覧権限しか持たないバックエンドエンジニアなどがインフラを変更したい場合はインフラチームに要件を伝え依頼するか、Terraformを書いてプルリクを送り実行を依頼するという運用になっていました。
Terraformモノレポ
Lenetでは複数のGCPプロジェクトを利用していて、プロジェクト単位でTerraform管理しています。Terraformのリソースはモノレポで保存しており、リポジトリルートにプロジェクト名でディレクトリを作成しその配下にtfファイルが配置されています。
├── lenet │ ├── gke.tf │ ├── iam.tf | ... ├── lenet-stg ...
少しずつ問題が発生してくる
Terraformを実行するためにインフラチームは強めの権限を持っていて、GCPのWebコンソールからも編集や削除が行える状況になっています。そのため、Webコンソールから設定内容を確認するときに誤って設定を上書きしてしまいそうになったりと、ちょっとしたヒヤリが発生していました。
また、手元のPCからGCPの編集や削除ができるとなるとPCのセキュリティ管理も一層重要になりより注意を払うことになります。
その他にも、手元で実行するが故に最新のmasterブランチで実行されることが保証されなかったり、インフラチーム以外が実行するときに閲覧権限だけではterraform plan
が実行できなかったりと小さな問題が発生していました。
これらの問題を解決するためにTerraformを実行する環境を構築することにしました。
Terraform実行環境
上記問題を解決するためにCI環境でTerraformを実行するようにし、段階的にインフラエンジニアのGCPの権限を弱くしていくことにしました。
CI環境でTerraformを実行するということは、CI環境が強い権限を持つことになります。セキュリティを考えるとCIサービスに無期限で使えるアクセスキーを登録することは避けたかったため、GCP上で実行するかOIDCが使えるCIサービスから選ぶことになります。
今回は短期間しか使えないとはいえ強力な権限を持ったアクセスキーが外部に出ることを避けるため、GCPのCloudBuildで実行するようにしました。
以下の図が今回作成した実行環境の構成図です。詳細と選択理由を説明していきます。
専用プロジェクトで実行する
それぞれのプロジェクト内のCloudBuildで実行することも考えましたが、GitHubへの接続設定やその他SaaSのアクセスキーの登録を全てのプロジェクトで行うのは効率が悪いため、専用のGCPプロジェクトを用意してそこで全プロジェクトのTerraformを実行するようにしました。
キーレスにするために
CloudBuildにはジョブ環境に自動的に設定されるサービスアカウントを任意のサービスアカウントに指定する機能があります。
この機能を使うことでTerraformを実行するために永続的なサービスアカウントキーを保存する必要がなくなります。加えて、このサービスアカウントに直接権限をもたせることをせず、「サービスアカウントの権限借用」機能を使うことにします。
サービスアカウントの権限を借用すると一時的にそのサービスアカウントになりすますことができます。これによりTerraformコマンドを実行するときだけ必要な権限を得ることができ、さらに安全性を高めることができます。
悪意を持ったユーザーのTerraform実行を防ぐ
この手の対応はどこまでやるかが難しいところですが、簡単にできる対策はいれることにしました。
masterマージ時にterraform apply
を、それ以外のpushでterraform plan
が実行されるようになっていますが、それぞれでサービスアカウントを別にし権限を分けるようにしています。これによりCloudBuildで実行するコマンドを書き換えてもCloudBuildのトリガー設定で指定されたサービスアカウントを変更しない限り想定した権限が強制されることになります。つまり、plan用のジョブでapplyを実行しようとしても権限が足りずエラーになります。
プロジェクトごとにplanとapply用のサービスアカウントを設定しているため、異なるプロジェクトに対してterraform
コマンドを実行することもできなくなっています。
masterへのマージやプッシュができるとapplyコマンドが実行できることになり、CloudBuildのトリガー設定を変更できるため使用するサービスアカウントも変更できますが、GitHubの「ブランチ保護ルール」機能を使ってmasterへのプッシュ禁止、レビュー必須としているため、apply用のCIが悪用される可能性も低くなっています。
おわりに
今回作成した環境によってヒューマンエラーを防ぎつつセキュアな環境でTerraformを実行できるようになったかと思います。まだ稼働して日が浅いため想定した通りに運用が回るかはわかりませんが、安心安全なインフラ運用ができるように改善を続けていきたいと思います。
ホワイトプラスでは、ビジョンやバリューに共感していただけるエンジニアを募集しています!
ネットクリーニングの「リネット」など「生活領域×テクノロジー」で事業を展開している会社です。 どんな会社か気になった方はオウンドメディア「ホワプラSTYLE」をぜひご覧ください。
オンラインでカジュアル面談もできますので、ぜひお気軽にお問い合わせください。