Infrastructure-as-Code を最小権限で実行する
Google Cloud Japan Team
Google Cloud サービス アカウントの権限を借用して Terraform コードを実行する
※この投稿は米国時間 2023 年 4 月 21 日に、Google Cloud blog に投稿されたものの抄訳です。
Terraform はオープンソースの Infrastructure as Code(IAC)ツールであり、Google Cloud のリソース管理に広く利用されています。このツールを使用すると、リソースを人が判読できる構成ファイルとして定義し、バージョンの付与や、再利用、共有ができるようになるため、柔軟な IAC 管理や、移植、デベロッパー間の連携に役立ちます。Terraform でオーナーなどのロールを使ってリソースを管理すると、編集者ロールを割り当てられたデベロッパーは、Terraform 構成ファイルの構文や構造の管理に集中できるようになります。権限を拡大するほど、IAM 権限の問題を回避できます。
このブログ投稿では、Terraform で Google Cloud サービス アカウントの権限借用を行う方法をいくつか紹介します。サービス アカウントの権限を借用すれば、管理者はサービス アカウント キーを生成せずに、サービス アカウント トークン作成者のロールを使って、IAM で権限を管理できるため、サービス アカウント キーの管理プロセスや、キーのローテーション、作成、削除を実装する手間が省けます。この方法だと、最小権限の原則に沿って、特定のサービス アカウントに限定した権限をユーザー アカウントに与えられるため、リソースのセキュリティが向上します。また、Google Cloud サービスへの承認を与えるためにユーザーの認証情報を使用せずに済むため、アクセスの管理およびセキュリティが向上します。
IAM 使用時のセキュリティを徹底するために、Terraform のコードは最小権限の原則に沿って実行する必要があります。ユーザーのアクセス権限を Terraform コードで制限する代わりに、サービス アカウントを使用して Terraform コードを実行することができます。サービス アカウントとは、仮想マシンなどの各種リソースが API やサービスにアクセスするために使用する特種な Google アカウントです。アプリケーションは、このような実際の人ではないサービス アカウントを使用して認証を受け、Google API のデータへのアクセスを承認してもらうことができます。
サービス アカウントの認証は、サービス アカウント キーを生成することで行えます。ただし、この方法のデメリットとして、キーを持つユーザーなら誰でもサービス アカウントを使って認証を受けれるという点があります。それを回避するために、定期的ローテーションでキーを管理し、API キーの制限を追加する必要があります。
別の方法として、サービス アカウントの権限借用があります。この方法の場合、サービス アカウント キーへのアクセスは不要で、代わりに IAM 権限を使用して、サービス アカウントの使用を承認します。この方法だと、ユーザー アカウントに与える権限を減らすことができます。ユーザーがサービス アカウントにアクセスする必要がなくなったら、Google Cloud IAM で、そのサービス アカウントのリソースからユーザー ID を削除するだけで済みます。
サービス アカウントの権限借用に必要な権限
サービス アカウントの権限を借用するためには、ユーザー アカウントに以下の権限が必要です。
サービス アカウント ユーザー(roles/iam.serviceAccountUser): このロールは、サービス アカウントがアクセス可能なリソースへのアクセスを、プリンシパルに許可します。ただし、プリンシパルがサービス アカウントの有効期間が短い認証情報を作成することや、Google Cloud CLI の –impersonate-service-account フラグを使用することは許可しません。
サービス アカウント トークン作成者(roles/iam.serviceAccountTokenCreato): このロールは、認証情報を作成するサービス アカウントの権限借用をプリンシパルに許可します(OAuth 2.0 アクセス トークン、OpenID Connect(OIDC)ID トークン、JSON Web Token(JWT)とバイナリ blob への署名)。
サービス アカウントの権限を借用して Terraform コードを実行する方法
サービス アカウントの権限を借用する 1 つ目の方法は、環境変数 GOOGLE_IMPERSONATE_SERVICE_ACCOUNT をサービス アカウントのメールアドレスに設定することです。
例:
export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=SERVICE_ACCOUNT@PROJECT@iam.gserviceaccount.com
これにより、サービス アカウントの権限を借用し、そのサービス アカウントの認証情報を使用してそれ以降の Terraform コードを実行することができます。この方法の制約としては、ターミナルを再起動するたびに環境変数を設定する必要があるということと、Terraform コード全体に対して 1 つのアカウントを使用することになるという点が挙げられます。
2 つ目の方法は、access_token を持つプロバイダ エイリアスを追加して、サービス アカウントの権限を借用することです。この方法の場合、Terraform コードに以下のステップを追加する必要があります。
Terraform 構成ファイルを通じてサービス アカウントを作成するか、または、terraform.tfvars で、変数を使用するサービス アカウントのメールアドレスに設定する。
サービス アカウントのアクセス トークンを取得するためのプロバイダ ブロック。
- サービス アカウントのアクセス トークンを取得するためのデータブロックを追加する。
- 指定のサービス アカウントのアクセス トークンを使用するプロバイダ ブロックを含める。
これで、Terraform コードの実行によって作成されたリソースはすべて、上記の方法で権限を借用したサービス アカウントを使用することになります。この方法だと、最小権限の原則にのっとりながら、実行する Terraform モジュールごとに異なるサービス アカウントを使用できます。
3 つ目の方法は、プロバイダ ブロックの属性 impersonate_service_account を使用して、サービス アカウントの権限を借用することです。この方法は 2 つ目の方法と似ており、プロバイダのエイリアスを用いて、そのプロバイダのサービス アカウントの権限を借用します。実装するためのステップを以下に示します。
サービス アカウントの権限を借用するために、以下のようなプロバイダ ブロックを追加します。
- 上記のステップによって、デフォルトのプロバイダ ブロックに権限借用が設定されます。権限借用が少数のタスクの実行にのみ必要な場合は、エイリアスの属性を使って、権限借用が必要なリソースのエイリアスをプロバイダに定義できます。以下のようにして作成した Billing Budget Terraform リソースは、示されているサービス アカウントの権限を借用します。
次のステップ
Google Cloud のサービス アカウントの権限借用について詳しくは、以下をご覧ください。
- Google、インフラストラクチャ担当クラウド エンジニア Vipul Sharma