HashiCorp Terraform を使用した、コードとしての IAM アクセス制御の実装

Google Cloud Japan Team
※この投稿は米国時間 2022 年 12 月 6 日に、Google Cloud blog に投稿されたものの抄訳です。
今日のデジタル トランスフォーメーションには、セキュリティ トランスフォーメーションが欠かせません。Google Cloud のセキュリティ戦略における防衛の最前線として、Identity and Access Management(IAM)を活用できます。IAM は、Google Cloud アカウントのリソースに対して、どのユーザーがどの処理を実行できるかを管理者が定義できるようにするツールのコレクションです。組織のどのユーザーがどのリソースにアクセスする必要があるかを把握することは、安全なクラウド エクスペリエンスを実現するための最初のステップの一つです。
IAM で制御できるのは、ユーザーとグループだけではありません。ユーザーとグループを指定したら、どのようにアクセス権を与えるか考えなければなりません。許可ポリシー、ロール、プリンシパルは、いずれも Google Cloud の重要なコンセプトです。これらのコンセプトに加えて、サービス アカウントはサービス(人間ではないもの)が別のサービスを認証することを可能にします。Google Cloud の外部でワークロードを実行している場合は、Workload Identity 連携という機能を使用してワークロードを認証できます。また、組織のポリシーを使用して、コンプライアンスとガードレールを設定します。
IAM には、アカウントの保護に役立つさまざまなツールが用意されています。では、それらのツールやコンセプトを実装して管理するには、どうすればよいでしょうか?もちろん、Google Cloud の管理コンソールや Cloud コンソールを使って IAM のアクセス制御戦略を構築することはできますが、これらのプロセスを自動化する場合はどうでしょう?
Infrastructure as Code(IAC)は、運用チームの間ではかなり一般的となっています。HashiCorp Terraform のようなプロダクトは IAC を実現し、テキストベースのファイルを使ってインフラストラクチャのプロビジョニングとセットアップを自動化できるようにします。前述した IAM のコンセプトは伝統的なインフラストラクチャとは言えないかもしれませんが、インフラストラクチャとポリシーのハイブリッドと考えることができます。Terraform は、IAC としてだけでなく、アカウントのアクセス制御の実装にも活用できます。
Terraform を使用して Google Cloud アカウントのアクセス制御を実装する利点
スピード。Terraform では、一定の水準の自動化が可能です。アクセス制御をコードベースの形式で記述できるため、Terraform から Google Cloud アカウントへの API 呼び出しを通じて、プログラムによる Google Cloud アカウントとのやり取りを実行できます。これにより、開発 / 実装にかかる時間を短縮できます。
インテグレーション。バックエンドで API を使用しているため、特定のアクセス制御の構築を新規または既存のパイプラインに組み込めるようになりました。
バージョン管理。Terraform の .tf 構成ファイルを使用しているため、ソースコード リポジトリにコードをアップロードできます。また、git を使用して、すべての変更点とさまざまなバージョンのコードを管理できます。
コラボレーション。ソースコード リポジトリにコードを保存できるため、アクセス制御をチーム全体で共有できます。pull リクエストを利用することで、チームでの知識共有が促進されます。
整合性。アクセス制御をコードで定義しているため、Terraform のモジュールを使用してベスト プラクティスを適用できます。モジュールではさまざまな構成でコードを再利用できるため、整合性を保ちながら開発時間を短縮できます。
IAM の基本
では、IAM 戦略の基盤となる IAM の基本的な構成要素について、簡単に見ていきましょう。
ロール
ロールは個別の権限のコレクションです。権限は「そのサービスで実行できること」といえます。たとえば、Cloud Run 起動元ロールでは、run.jobs.run と run.routes.invoke を実行できます。
事前定義ロールとは、その責務に応じて特定の処理を実行できるようにする、Google が作成したロールです。事前定義ロールを使用すると影響が及ぶ範囲を制限できるため、アクセス制御戦略の強化につながります。
さらにセキュリティを高めるには、独自のカスタムロールを作成し、権限をきめ細かくプリンシパルに設定して、必要な権限だけにアクセスできるようにします。これは最小権限の原則と呼ばれる、アクセス制御のベスト プラクティスです。
ロール バインディング


ロール バインディングとは、あるロール(権限セット)をプリンシパルに関連付けることです。こうすることで、プリンシパルはそのロールを構成するすべての権限を使用できるようになります。これをさらに一歩進めたものが許可ポリシーです。許可ポリシーは、1 つ以上のプリンシパルを個々のロールにバインドするロール バインディングのコレクションです。
プリンシパル
プリンシパルとは、リソースへのアクセスを必要とするエンティティだと考えるとよいでしょう。プリンシパルには、ロール バインディングによって割り当てられる権限を通じて、リソースへのアクセス権を付与できます。
プリンシパルには、Google アカウント、サービス アカウント、Google グループ、Google Workspace アカウント、Cloud Identity ドメインなどを使用できます。各プリンシパルにはメールアドレスがあり、そのプリンシパルに権限を割り当てる際に識別子として使用します。
階層構造


Google Cloud の階層構造について見ていきましょう。Google Cloud では、この階層構造で 2 つのことを行っています。
所有権を階層的に編成
接続ポイントの提供と継承
これが意味することは、リソースを親に関連付けることができるということです。たとえば、DevOps チームを表すフォルダを作成します。そのフォルダの下にプロジェクトを作成し、リソースを関連付けます。この場合、プロジェクトの直接の祖先は(DevOps 部門を表している)DevOps フォルダです。そして、リソースの直接の祖先はプロジェクトになります。つまり、DevOps フォルダレベルで権限を付与すると、DevOps フォルダに関連付けられたプロジェクトやリソースは DevOps フォルダの直系の子孫にあたるため、この権限を継承します。Terraform を使用してアクセス制御を実装する場合、リソースにアクセス権を与えるレベルを把握しておく必要があります。
組織のポリシー
組織のポリシーでは、ガードレールを設定することで組織のセキュリティとコンプライアンスを確保します。また、制約を適用して、組織で認めるリソース構成を指定できます。では、制約の仕組みを見ていきましょう。


この図では、組織のポリシー管理者が階層の一番上に表示されています。このロール(コレクションまたは権限)は、組織レベルで付与する必要があります。組織のポリシー管理者には特定の権限セットが付与されているため、組織のポリシーを定義できます。このポリシーは、制約(制限とも呼びます)で構成されています。この制約が組織のポリシーの設計図となります。次に、ポリシーをリソース階層ノードに設定します。ここでは、フォルダレベルに設定したことにします。デフォルトでは、ポリシーは特定の GCP サービスに適用されます。このポリシーは、そのフォルダ以下のすべてのリソースに継承されます。
Terraform を使用した構築
では、コードを使用してポリシーを構築する方法を見ていきましょう。


resource - リソース ブロックとも呼ばれ、Terraform に何を構築するかを指定します。今回の場合、プロジェクト レベルで設定する組織のポリシーです。「auditlogging_policy」という名前は、Terraform 側で認識されるこのリソースの名前です(場合によっては、特定のリソースをターゲットにしたり、ユーザーに入力させたりすることもできます)。
project - ポリシーを適用するプロジェクトの ID です。
constraint - ポリシーが参照する制約の名前です。制約について詳しくは、こちらをご覧ください。
boolean_policy - ポリシーを適用するかどうかを指定する値です。
サービス アカウント
サービス アカウントはプリンシパルともリソースとも見なすことができます。その理由は、サービス アカウントにはロールを付与(ID など)することも、ポリシーを適用(リソースなど)することもできるからです。Google Cloud で使用しているサービスで相互通信が必要な場合、サービス アカウントを使用する必要があります。これにより、サービス間で安全に認証や API 呼び出しを行うことができます。


resource google_service_account - サービス アカウントを作成します。account_id には、サービス アカウント用メールアドレスを生成するために使用する名前を指定します。display_name は省略可能です。サービス アカウントの概要を指定します。
resource google_project_iam_member - サービス アカウントに権限を追加します。
resource google_service_account_iam_member - iam.serviceAccountUser ロール(role として参照)をユーザー(member として参照)に付与することにより、サービス アカウント(service_account_id)のユーザーとしてアクセス権を付与します。
ユースケース
基本をマスターしたので、実際のユースケースを見てみましょう。


Big Horn Inc. という SaaS 企業で働いているとしましょう。アクセス制御を自動化するパイプラインの構築を担当しており、2 つの問題の解決を課されています。
1. チームは、ステートレス アプリケーションをモダナイズし、コンテナを使用してマイクロサービスを作り、さまざまな Cloud Run サービスが Google Cloud の他のサービスと通信できるようにしたいと考えています。この場合、Cloud Run のサービス アカウントをいくつか作成する必要があります。このプロセスを自動化できると理想的です。


2. 現在、私たちは非常に幅広い権限を持っています。一部のプリンシパルには基本ロールが割り当てられています。Google Cloud のポリシー分析情報ツールを使用した結果、チームは一部のプリンシパルのアクセス権は過剰だと判断しました。組織が最小権限の原則を実践するには、より細かく権限を設定できるカスタムロールを作成する手段が必要です。


Terraform で IAM を実装し、Cloud Build を使用することにより、自動化された方法でこれらの問題を解決できます。
準備を整える


Terraform でアクセス制御の構築を始める前に、いくつか準備が必要なことがあります。
ローカルでの開発
Terraform と gcloud をインストールしたら、Terraform が使用できるサービス アカウントがあることを確認します。そのサービス アカウントに必要なすべての権限が割り当てられていることを確認してください。構築するものによっては、組織レベルで権限を付与し、プロジェクト レベル(サービス アカウントを作成するレベル)で継承されるようにする必要があります。次に、適切な認証方法を使用していることを確認します。ローカル開発での認証には、アプリケーションのデフォルト認証情報(ADC)を使うことをおすすめします。簡単な設定をするだけで、Terraform で gcloud 構成の認証情報を使用した自動認証が可能になります。
自動化された開発
パイプラインでは、作成したサービス アカウントに対する権限が Cloud Build に付与されます。これにより、Cloud Build はそのサービス アカウントの権限を引き継ぎ、Terraform 構成を認証できるようになります。
パイプライン
サービス アカウントと適切なツールが揃ったので、パイプラインを構築しましょう。以下のように yaml ファイルを使用して、Cloud Build のパイプラインを自動的に構築します。パイプラインの各ステップは、Docker コンテナを通じて組み込まれます。このパイプラインは、Terraform を使用して標準的な処理を実行します。
terraform init
terraform fmt
terraform plan
terraform apply


まとめ
Google Cloud でアクセスを保護することは、アカウントの安全性を確保する強力な防衛の最前線となります。IAM とその要となる機能を理解することは、アクセス制御を構築するための基盤です。アクセス制御を自動化することにより、時間とコストを節約し、必要となったときに構造化された方法で変更を加えることができるアジリティを獲得できます。cloud.google.com で無料のアカウントを作成できます。IAM を初めてお使いになる場合でも、Google がお手伝いしますのでご安心ください。まずはこちらの IAM チュートリアルをお試しください。