コンテンツに移動
デベロッパー

Terraform コードにおける Google Cloud サービス アカウントの権限借用

2021年12月20日
Google Cloud Japan Team

※この投稿は米国時間 2021 年 12 月 4 日に、Google Cloud blog に投稿されたものの抄訳です。

Terraform はオープンソースの Infrastructure as Code ツールのなかでも特に普及している、Google Cloud でのリソース管理に最適なツールです。Google Cloud で Terraform を試してみる場合は、プロジェクト オーナーのロールを使うと非常に簡単です。プロジェクト オーナーのロールは権限に制限がないので IAM 権限の不足により生じる問題に悩まされることがなく、構文と機能の理解に集中できるからです。

ただし、本格的に使い始める場合や、作業中のプロジェクトでオーナーのロールを使えない場合は、自分の権限を制限し、適切な IAM ロールセットが割り当てられたサービス アカウントで Terraform コードを実行することをおすすめします。サービス アカウントは、API やサービスにアクセスするために Google Cloud プロジェクトのアプリケーションや仮想マシンで一般に使用される特別なアカウントです。アプリケーションとユーザーは、生成されたサービス アカウント キーを使用してサービス アカウントとして自分自身を認証できます。

このアプローチの欠点は、キーを生成して配布することがそのままセキュリティ リスクに直結することです。サービス アカウント キーのアクセス権を持つすべてのユーザーは、自身の権限に関係なく、サービス アカウントを使って自分自身を認証し、そのサービス アカウントに権限が付与されているすべてのリソースにアクセスできます。Terraform コードをサービスとして実行するにはもっと安全な方法があります。それがサービス アカウントの権限借用です。

サービス アカウントを使用してリソースを作成する

サービス アカウントを使用してリソースの作成を開始するには、2 つの手順が必要になります。まず、Terraform コードの実行に使用するサービス アカウントをプロジェクトに用意する必要があります。このサービス アカウントには、コードで参照されるリソースを作成する権限が必要です。次に、自分のユーザー アカウントにサービス アカウント トークン作成者の IAM ロールを付与する必要があります。このロールを使用すると、サービス アカウントの権限を借用して API とリソースにアクセスできます。IAM ロールはプロジェクトの IAM ポリシーで付与できるため、プロジェクト内のすべてのサービス アカウントで借用権限が付与されます。ただし、最小権限の原則を遵守する場合は、代わりにサービス アカウントの IAM ポリシーでロールを付与する必要があります。

サービス アカウントとサービス アカウント トークン作成者のロールを取得したら、環境変数にサービスアカウントのメールアドレスを設定するか、Terraformのコードにプロバイダブロックを追加するという 2 つの方法で Terraform のサービス アカウントの権限を借用できます。

前者の場合は、GOOGLE_IMPERSONATE_SERVICE_ACCOUNT 環境変数にサービス アカウントのメールを設定します。例:

読み込んでいます...

設定が完了すると、現在のターミナル セッションで実行される Terraform コードには、自分のアカウントではなくサービス アカウントの認証情報が使用されます。この方法により、Terraform をサービス アカウントとして素早く簡単に実行できます。ただし、当然のことながらターミナル セッションを再起動するたびに環境変数の設定が必要になります。また、Terraform コードで作成されるすべてのリソースに対して 1 つのサービス アカウントしか使用できないという制限もあります。  

後者の場合は、いくつかのブロックを Terraform コード(できれば provider.tf ファイル)に追加し、サービス アカウントの認証情報を取得する必要があります。まず、ローカル変数にサービス アカウントのメールを設定します。
読み込んでいます...

この変数は、変数ブロックを記述し、terraform.tfvars ファイルで値を指定して設定することもできます。どちらの方法でも適切に動作します。次に、サービス アカウントのアクセス トークンを取得するために使用するプロバイダを作成します。プロバイダは「google」ですが、それに割り当てられている「impersonation」エイリアスにご注意ください。

読み込んでいます...

次に、サービス アカウントとしての認証で使用するアクセス トークンを取得するためのデータブロックを追加します。データブロックが先に指定した impersonation プロバイダとサービス アカウントを参照している点に注意してください。

読み込んでいます...

最後に、サービス アカウントのアクセス トークンを使用するもう 1 つの「google」プロバイダを記述します。エイリアスがないため、これは Terraform コードの Google リソースに使用されるデフォルトのプロバイダになります。

読み込んでいます...

これで、環境変数を設定しなくても、Terraform コードで作成される Google Cloud リソースはユーザーの認証情報の代わりにサービス アカウントを使用するようになります。この方法では、一意のエイリアスを持つ追加のプロバイダ ブロックを指定して、複数のサービス アカウントを使用することもできます。

サービス アカウントでリモート状態ファイルを更新する

Terraform コードを実行すると、管理対象の Google Cloud リソースが状態ファイルで追跡されます。状態ファイルはデフォルトで作業ディレクトリに生成されますが、このファイルは GCS バケットに保持することをおすすめします。バックエンドを指定する際は、状態ファイルを保持する既存のバケットと、オプションのプレフィックス(ディレクトリ)を指定する必要があります。バケットがあっても自分のユーザー アカウントにアクセス権がない場合は、アクセス権を持つサービス アカウントを代わりに使用できます。  

繰り返しますが、サービス アカウント トークン作成者のロールがサービス アカウントのポリシーを通じて付与されている必要があります。このサービス アカウントは、Terraform コードの実行に使用するものとは別のアカウントでも構いません。このサービス アカウントは、バックエンド ブロックに impersonate_service_account 引数を追加するだけで簡単に指定できます。

読み込んでいます...

この引数をバックエンド ブロックに追加すると、インフラストラクチャに変更が加えられたときにサービス アカウントを使用して状態ファイルの読み取りと更新が行われるようになります。ユーザー アカウントにバケットへのアクセス権が付与されている必要はなく、必要なのはサービス アカウントへのアクセス権だけです。

権限借用のメリット

上記の方法では、サービス アカウント キーの生成や配布は不要です。Terraform はサービス アカウント キーの使用をサポートしていますが、サービス アカウント キーを生成して配布するとセキュリティ リスクが生じます。このリスクは権限借用によって最小限に抑えられます。管理者がキーを作成、追跡、ローテーションする必要はなく、サービス アカウントへのアクセスは対応する IAM ポリシーで一元的に管理できます。権限借用を使うことで、コードは移植可能になり、サービス アカウント トークン作成者のロールを持つプロジェクト関係者なら誰でも使用できるようになります。管理者はこのロールの付与や取り消しを簡単に行えます。

- Cloud デベロッパー アドボケイト Roger Martinez
投稿先