このガイドでは、Workload Identity 連携を使用して、デプロイ パイプラインで Google Cloud に対する認証を行えるようにする方法について説明します。
使用している CI / CD システムによっては、デプロイ パイプラインからアンビエントな環境固有の認証情報にアクセスできる場合があります。次に例を示します。
- GitHub Actions ワークフローでは、GitHub OIDC トークンを取得して、ワークフローとそのリポジトリを一意に識別できます。
- Terraform Cloud では、ワークスペースと環境を一意に識別する OIDC トークンを Terraform 構成に指定できます。
Workload Identity 連携を使用することで、サービス アカウント キーを保存して管理する必要がなくなります。また、デプロイ パイプラインで環境固有の認証情報を使用して Google Cloud APIs にアクセスする必要がなくなります。
外部 IdP を準備する
GitHub Actions
GitHub アカウントで構成を変更する必要はありません。
GitHub リポジトリを信頼するように Workload Identity プールを構成すると、そのリポジトリのワークフローで GitHub OIDC トークンを使用して、有効期間の短い Google Cloud 認証情報を取得できます。
Terraform Cloud
Terraform Cloud アカウントで構成を変更する必要はありません。
Terraform Cloud を信頼するように Workload Identity プールを構成すると、個々のワークスペースで Workload Identity 連携を有効にできます。
Workload Identity 連携を構成する
この手順は、GitHub または Terraform Cloud 組織ごとに行う必要があります。
Workload Identity 連携の構成を開始するには、次の操作を行います。
-
Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。
Workload Identity プールとプロバイダの管理に専用のプロジェクトを使用することをおすすめします。
-
Cloud プロジェクトに対して課金が有効になっていることを確認します。詳しくは、プロジェクトで課金が有効になっているかどうかを確認する方法をご覧ください。
IAM, Resource Manager, Service Account Credentials, and Security Token Service API を有効にします。
属性のマッピングと条件を定義する
デプロイ パイプラインの環境固有の認証情報には複数の属性が含まれているため、Google Cloud でサブジェクト識別子(google.subject
)として使用する属性を決定する必要があります。
必要に応じて、追加の属性をマッピングできます。これにより、リソースへのアクセス権を付与する際にこれらの追加属性を参照できます。
GitHub Actions
属性マッピングでは、次のような OIDC トークンに埋め込まれたクレームをソース属性として使用できます。
sub
: リポジトリ名と Git リファレンスが含まれます(例:repo:username/reponame:ref:refs/heads/master
)。repository
: オーナーとリポジトリ名が含まれます(例:username/reponame
)。repository_owner
: オーナー(ユーザー名または GitHub 組織の名前)が含まれます。ref
: Git リファレンスが含まれます(refs/heads/main
など)。
次の属性マッピングでは、google.subject
を GitHub Actions OIDC トークンの sub
クレームに設定します。sub
クレームにはリポジトリ名と Git リファレンスの両方が含まれるため、このマッピングによりリポジトリとブランチによるアクセスを制御できます。
google.subject=assertion.sub
リポジトリとブランチによるアクセスの制御は、特定のブランチ(main
など)が他のブランチ(機能ブランチなど)以外のリソースに対する異なるアクセスが必要な場合に役立ちます。
ブランチごとにアクセスを区別しない場合は、次の属性マッピングを使用します。これにより、google.subject
が repository
クレームに設定されます。
google.subject=assertion.repository
Terraform Cloud
属性マッピングでは、次のような Terraform Cloud OIDC トークンに埋め込まれたクレームを使用できます。
terraform_organization_id
: 組織の一意の ID が含まれます(例:org-xxxxxxxxxxxxxxxx
)。terraform_workspace_id
: ワークスペースの一意の ID が含まれます(例:ws-xxxxxxxxxxxxxxxx
)。terraform_workspace_name
: ワークスペースの表示名が含まれます。sub
: 組織、ワークスペース、フェーズの表示名が含まれます(例:organization:example-org:workspace:example-workspace:run_phase:apply
)。
次の属性マッピングは、google.subject
を Terraform Cloud OIDC トークンの terraform_workspace_id
クレームに設定します。
google.subject=assertion.terraform_workspace_id
このマッピングにより、ワークスペースごとに Google Cloud リソースへのアクセスを制御できます。
属性条件は、アサーション属性とターゲット属性をチェックする CEL 式です。特定の認証情報の属性条件が true
と評価されると、認証情報が受け入れられます。それ以外の場合、認証情報は拒否されます。
GitHub Actions
GitHub 組織によって発行されたトークンへのアクセスを制限するには、次の条件を使用します。
assertion.repository_owner=='ORGANIZATION'
ORGANIZATION
は、GitHub 組織の名前に置き換えます。
必要に応じて属性条件を拡張して、ワークフローまたはブランチのサブセットへのアクセスを制限します。たとえば、次の条件は、Git ブランチ main
を使用するワークフローへのアクセスを制限します。
assertion.repository_owner=='ORGANIZATION' && assertion.ref=='refs/heads/main'
Terraform Cloud
Terraform Cloud 組織によって発行されたトークンへのアクセスを制限するには、次の条件を使用します。
assertion.terraform_organization_id=='ORGANIZATION_ID'
ORGANIZATION_ID
は、組織の一意の ID に置き換えます(例: org-xxxxxxxxxxxxxxxx
)。必要に応じて属性条件を拡張して、ワークフローまたはブランチのサブセットへのアクセスを制限します。たとえば、次の条件により、特定のワークスペースへのアクセスが制限されます。
assertion.terraform_organization_id=='ORGANIZATION_ID' && terraform_workspace_id=='WORKSPACE_ID'
Workload Identity のプールとプロバイダを作成する
必要なロール
Workload Identity 連携の構成に必要な権限を取得するには、プロジェクトに対して次の IAM ロールを付与するよう管理者に依頼してください。
- Workload Identity プール管理者(
roles/iam.workloadIdentityPoolAdmin
) - サービス アカウント管理者(
roles/iam.serviceAccountAdmin
)
ロールの付与の詳細については、アクセスの管理をご覧ください。
また、IAM オーナー(roles/owner
)の基本ロールには ID 連携を構成する権限も含まれています。本番環境では基本ロールを付与すべきではありません。基本ロールは、開発環境またはテスト環境で付与してください。これで、Workload Identity プールとプロバイダの作成に必要な情報がすべて収集されました。
コンソール
Google Cloud コンソールで、[新しいワークロード プロバイダとプール] ページに移動します。
[ID プールを作成] に、次のように入力します。
- 名前: プールの名前。この名前はプール ID としても使用されます。プール ID を後で変更することはできません。
- 説明: プールの目的を説明するテキスト。
[続行] をクリックします。
プロバイダを構成します。
GitHub Actions
- プロバイダを選択: OpenID Connect(OIDC)。
- プロバイダ名: プロバイダの名前。この名前はプロバイダ ID としても使用されます。プロバイダ ID は後から変更できません。
- 発行元 URL:
https://token.actions.githubusercontent.com/
- オーディエンス: デフォルトのオーディエンス
Terraform Cloud
- プロバイダを選択: OpenID Connect(OIDC)。
- プロバイダ名: プロバイダの名前。この名前はプロバイダ ID としても使用されます。プロバイダ ID は後から変更できません。
- 発行元 URL:
https://app.terraform.io
- オーディエンス: デフォルトのオーディエンス
[続行] をクリックします。
[プロバイダの属性を構成する] で、前に確認した属性マッピングを追加します。
[属性条件] で、前に確認した属性条件を入力します。属性条件がない場合は、空白のままにします。
[保存] をクリックして、Workload Identity のプールとプロバイダを作成します。
gcloud
新しい Workload Identity プールを作成します。
gcloud iam workload-identity-pools create POOL_ID \ --location="global" \ --description="DESCRIPTION" \ --display-name="DISPLAY_NAME"
次の値を置き換えます。
POOL_ID
: プールの一意の ID。DISPLAY_NAME
: プールの名前。DESCRIPTION
: プールの説明。この説明は、プール ID へのアクセス権を付与するときに表示されます。
Workload Identity プールのプロバイダを追加します。
GitHub Actions
gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \ --location="global" \ --workload-identity-pool="POOL_ID" \ --issuer-uri="https://token.actions.githubusercontent.com/" \ --attribute-mapping="MAPPINGS" \ --attribute-condition="CONDITIONS"
次の値を置き換えます。
PROVIDER_ID
: プロバイダの一意の ID。POOL_ID
: プールの ID。MAPPINGS
: 前に確認した属性マッピングのカンマ区切りリスト。CONDITIONS
: 前に確認した属性条件。属性条件がない場合は、パラメータを削除します。
Terraform Cloud
gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \ --location="global" \ --workload-identity-pool="POOL_ID" \ --issuer-uri="https://app.terraform.io" \ --attribute-mapping="MAPPINGS" \ --attribute-condition="CONDITIONS"
次の値を置き換えます。
PROVIDER_ID
: プロバイダの一意の ID。POOL_ID
: プールの ID。MAPPINGS
: 前に確認した属性マッピングのカンマ区切りリスト。CONDITIONS
: 前に確認した属性条件。属性条件がない場合は、パラメータを削除します。
デプロイ パイプラインを認証する
この手順は、GitHub Actions ワークフローまたは Terraform Cloud ワークスペースごとに行う必要があります。
デプロイ パイプライン用のサービス アカウントを作成する
IAM, Security Token Service, and Service Account Credentials API を有効にします。
ワークロードを表すサービス アカウントを作成します。デプロイ パイプラインごとに専用のサービス アカウントを使用することをおすすめします。
サービス アカウントは、Workload Identity プールと同じプロジェクトにある必要はありません。
外部 ID にアクセスを許可するリソースに対するアクセス権をサービス アカウントに付与します。
デプロイ パイプラインによるサービス アカウントの権限借用を許可する
外部 ID にサービス アカウントの権限借用を許可するには、サービス アカウントに Workload Identity ユーザーロール(roles/iam.workloadIdentityUser
)を付与します。このロールは、特定の外部 ID または複数の外部 ID に付与できます。
- 特定の外部 ID の場合は、
google.subject
属性をチェックする属性条件を記述します。 - 外部 ID のグループの場合は、
google.groups
属性またはカスタム属性attribute.NAME
をチェックする属性条件を記述します。 - Workload Identity プールの外部 ID には属性条件を使用しません。
コンソール
Google Cloud コンソールを使用して外部 ID にサービス アカウントの権限借用を許可するには、次の操作を行います。
Google Cloud コンソールで、[Workload Identity プール] ページに移動します。
更新する Workload Identity プールを見つけて選択します。
選択した Workload Identity プールへのアクセス権を付与するには、[
アクセスを許可] をクリックします。[サービス アカウント] リストで、権限を借用する外部 ID のサービス アカウントを選択します。
プール内のどの ID がサービス アカウントの権限を借用できるかを選択するには、次のいずれかを行います。
Workload Identity プールの特定の ID のみにサービス アカウントの権限借用を許可するには、[フィルタに一致する ID のみ] を選択します。
[属性名] リストで、フィルタリングする属性を選択します。
[属性値] フィールドに、属性の想定値を入力します。たとえば、属性マッピング
google.subject=assertion.sub
を使用する場合は、属性名をsubject
に設定します。属性値には、外部 ID プロバイダによって発行されたトークンのsub
クレームの値を設定します。Workload Identity プールのすべての外部 ID がサービス アカウントの権限借用を許可するには、[プール内のすべての ID] を選択します。
構成を保存するには、[保存]、[閉じる] の順にクリックします。
gcloud
gcloud CLI を使用して、外部 ID にサービス アカウントの権限借用を許可するには、次の操作を行います。
現在のプロジェクトのプロジェクト番号を取得するには、次のコマンドを実行します。
gcloud projects describe $(gcloud config get-value core/project) --format=value\(projectNumber\)
特定の条件を満たす外部 ID に Workload Identity ユーザー ロール(
roles/iam.workloadIdentityUser
)を付与するには:サブジェクト
gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \ --role=roles/iam.workloadIdentityUser \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT"
グループ
gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \ --role=roles/iam.workloadIdentityUser \ --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/group/GROUP"
属性
gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \ --role=roles/iam.workloadIdentityUser \ --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.ATTRIBUTE_NAME/ATTRIBUTE_VALUE"
すべての外部 ID
gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \ --role=roles/iam.workloadIdentityUser \ --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/*"
次のように置き換えます。
デプロイ パイプラインを構成する
この時点で、デプロイ パイプラインで Workload Identity 連携を使用する準備ができています。
GitHub Actions
google-github-actions/auth
アクションを使用すると、ワークフローの実行中に認証情報構成ファイルを自動的に生成できます。terraform
などのクライアント ライブラリとツールでは、この認証情報構成ファイルを使用して Google 認証情報を自動的に取得できます。
GitHub Actions YAML ファイルを編集して、次の内容を追加します。
ジョブが GitHub ID トークンを取得できるようにするには、次の構成を追加します。
permissions: id-token: write contents: read
認証情報構成ファイルを作成するステップを追加します。
- id: 'auth' name: 'Authenticate to Google Cloud' uses: 'google-github-actions/auth@v0' with: create_credentials_file: true workload_identity_provider: 'projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID' service_account: 'SERVICE_ACCOUNT_EMAIL'
次の値を置き換えます。
PROJECT_NUMBER
: Workload Identity プールを含むプロジェクトのプロジェクト番号POOL_ID
: Workload Identity プールの IDPROVIDER_ID
: Workload Identity プール プロバイダの IDSERVICE_ACCOUNT_EMAIL
: サービス アカウントのメールアドレス
例:
jobs: build: # Allow the job to fetch a GitHub ID token permissions: id-token: write contents: read runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - id: 'auth' name: 'Authenticate to Google Cloud' uses: 'google-github-actions/auth@v0' with: create_credentials_file: true workload_identity_provider: 'projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID' service_account: 'SERVICE_ACCOUNT_EMAIL'
google-github-actions/auth
アクションの使用方法については、Workload Identity 連携の設定をご覧ください。
Terraform Cloud
ワークスペースが Terraform Cloud OIDC トークンを取得できるようにワークスペースを構成します。
Terraform Cloud でワークスペースを開き、[Variables] に移動します。
[Add variable] をクリックし、次の変数を追加します。
- 変数カテゴリ: 環境変数
- キー:
TFC_WORKLOAD_IDENTITY_AUDIENCE
- 値:
https://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID
次の値を置き換えます。
PROJECT_NUMBER
: Workload Identity プールを含むプロジェクトのプロジェクト番号POOL_ID
: Workload Identity プールの IDPROVIDER_ID
: Workload Identity プール プロバイダの ID
[Save variable] をクリックします。
Terraform の構成を更新して、実行可能ファイル提供の認証情報とシェル スクリプトを使用して TFC_WORKLOAD_IDENTITY_AUDIENCE
環境変数から OIDC トークンを読み取り、Workload Identity 連携に使用します。
Terraform Cloud のワークスペース構成に、2 つの変数を追加します。
変数のカテゴリ キー 値 環境変数 GOOGLE_APPLICATION_CREDENTIALS
.google-cloud/workload-identity.json
環境変数 GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES
1
これらの変数は、実行可能ファイル提供の認証情報とファイル
.google-cloud/workload-identity.json
に保存された構成を使用するように、terraform
とクライアント ライブラリに指示します。ソースコード リポジトリで
.google-cloud/workload-identity.json
ファイルを作成し、次の構成をコピーします。{ "type": "external_account", "audience": "//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID", "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", "token_url": "https://sts.googleapis.com/v1/token", "credential_source": { "executable": { "command": "/bin/bash .google-cloud/workload-token.sh", "timeout_millis": 5000 } }, "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL:generateAccessToken" }
次の値を置き換えます。
PROJECT_NUMBER
: Workload Identity プールを含むプロジェクトのプロジェクト番号POOL_ID
: Workload Identity プールの IDPROVIDER_ID
: Workload Identity プール プロバイダの IDSERVICE_ACCOUNT_EMAIL
: サービス アカウントのメールアドレス
この構成では、スクリプト
.google-cloud/workload-token.sh
を実行して Terraform Cloud OIDC トークンを取得するようにクライアント ライブラリに指示します。ソースコード リポジトリで、別のファイル
.google-cloud/workload-token.sh
を作成し、次のスクリプトをコピーします。#!/bin/sh if [ -z $TFC_WORKLOAD_IDENTITY_TOKEN ] then echo '{"version": 1, "success": false, "code": "missing-variable", "message": "TFC_WORKLOAD_IDENTITY_TOKEN not defined in workspace."}' else echo '{"version": 1, "success": true, "token_type": "urn:ietf:params:oauth:token-type:id_token", "id_token": "'"$TFC_WORKLOAD_IDENTITY_TOKEN"'"}' fi
このスクリプトは、環境変数
TFC_WORKLOAD_IDENTITY_TOKEN
から Terraform Cloud OIDC トークンを読み取り、クライアント ライブラリで期待される形式でトークンを返します。Terraform 構成で、バージョン
4.48.0
以降の Google Cloud プロバイダが使用されていることを確認し、必要に応じて次のように更新します。terraform { required_providers { google = { source = "hashicorp/google" version = "~> 4.48.0" } } }
ソースコード リポジトリに変更を送信します。
次のステップ
- Workload Identity 連携について確認する。
- デプロイ パイプラインでの Workload Identity 連携の使用に関するベスト プラクティスを確認する。
- Workload Identity プールとプロバイダの管理方法を学習する。