デプロイメント パイプラインとの Workload Identity 連携を構成する

このガイドでは、Workload Identity 連携を使用して、デプロイ パイプラインで Google Cloud に対する認証を行えるようにする方法について説明します。

使用している CI / CD システムによっては、デプロイ パイプラインからアンビエントな環境固有の認証情報にアクセスできる場合があります。例:

  • Azure DevOps パイプラインは、Microsoft Entra Workload Identity 連携サービス接続を使用して、Azure DevOps プロジェクトを一意に識別する ID トークンを取得できます。
  • GitHub Actions ワークフローでは、GitHub OIDC トークンを取得して、ワークフローとそのリポジトリを一意に識別できます。
  • GitLab SaaS を使用すると、CI / CD ジョブは、ジョブとそのプロジェクト、環境、リポジトリを一意に識別する ID トークンにアクセスできます。
  • Terraform Cloud では、ワークスペースと環境を一意に識別する OIDC トークンを Terraform 構成に指定できます。

Workload Identity 連携を使用すると、これらの認証情報を使用して Google Cloud に対する認証を行うようにデプロイ パイプラインを構成できます。これにより、サービス アカウント キーに関連するメンテナンスとセキュリティの負担がなくなります。

始める前に

認証を設定する

このページのサンプルをどのように使うかに応じて、タブを選択してください。

コンソール

Google Cloud コンソールを使用して Google Cloud サービスと API にアクセスする場合、認証を設定する必要はありません。

gcloud

このページの gcloud CLI のサンプルは、次のいずれかの開発環境から使用できます。

  • Cloud Shell: gcloud CLI がすでに設定されているオンライン ターミナルを使用するには、Cloud Shell をアクティブにします。

    このページの下部で Cloud Shell セッションが開始し、コマンドライン プロンプトが表示されます。セッションが初期化されるまで数秒かかることがあります。

  • ローカルシェル: ローカル開発環境で gcloud CLI を使用するには、gcloud CLI をインストールして初期化してください。

Python

このページの Python サンプルをローカル開発環境から使用するには、gcloud CLI をインストールして初期化し、自身のユーザー認証情報を使用してアプリケーションのデフォルト認証情報を設定してください。

  1. Google Cloud CLI をインストールします。
  2. gcloud CLI を初期化するには:

    gcloud init
  3. Google アカウントのローカル認証情報を作成します。

    gcloud auth application-default login

詳細については、Google Cloud の認証に関するドキュメントのローカル開発環境の認証の設定をご覧ください。

必要なロール

Workload Identity 連携の構成に必要な権限を取得するには、プロジェクトに対する Workload Identity プール管理者roles/iam.workloadIdentityPoolAdmin)IAM ロールを付与するよう管理者に依頼してください。ロールの付与の詳細については、アクセス権の管理に関する記事をご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

また、IAM オーナー(roles/owner)の基本ロールには ID 連携を構成する権限も含まれています。本番環境では基本ロールを付与すべきではありません。基本ロールは、開発環境またはテスト環境で付与してください。

外部 IdP を準備する

Azure DevOps

Azure DevOps パイプラインで Google Cloud に対する認証を行うには、まず Azure Resource Manager にサービス接続を構成します。この接続により、パイプラインで ID トークンを取得し、Google Cloud の認証情報と交換できるようになります。

Azure Resource Manager にサービス接続を作成するには、次の操作を行います。

  1. Azure DevOps でプロジェクトを開き、[Project Settings] に移動します。
  2. [Pipelines] > [Service connections] に移動します。
  3. [Create service connection] をクリックします。
  4. [Azure Resource Manager] を選択します。
  5. [Next] をクリックします。
  6. [Workload Identity federation (automatic)] を選択します。
  7. [Next] をクリックします。
  8. 以下の設定を構成します。

    • Scope level: サブスクリプションを選択します。

      サービス接続を使用して Azure リソースにアクセスする予定がない場合でも、サブスクリプションを選択する必要があります。

    • Service connection name: google-cloud などの名前を入力します。

  9. [Save] をクリックします。

後のステップでは、サービス接続の発行者とサブジェクトの識別子が必要になります。これらの情報を確認するには、次の操作を行います。

  1. 作成したサービス接続をクリックします。
  2. [Manage Service Principal] をクリックします。
  3. [Certificate & secrets] > [Federated credentials] に移動します。
  4. フェデレーション資格情報をクリックします。
  5. [Edit a credential] ページで、次の識別子を見つけます。

    • Issuer: Azure DevOps 組織を一意に識別する ID
    • Subject identifier: サービス接続を一意に識別する ID

Azure DevOps は、新しいサービス接続に関連付けられたサービス プリンシパルに、スコープとして選択したサブスクリプションへのアクセス権を自動的に付与します。サービス接続を使用して Azure リソースにアクセスする予定がないため、このアクセス権は次のステップで取り消すことができます。

  1. Azure Portal で、スコープとして選択したサブスクリプションを開きます。
  2. [Access control (IAM)] > [Role assignments] に移動します。
  3. サービス接続のロール割り当てを見つけて削除します。

GitHub Actions

GitHub アカウントで構成を変更する必要はありません。

GitHub リポジトリを信頼するように Workload Identity プールを構成すると、そのリポジトリのワークフローで GitHub OIDC トークンを使用して、有効期間の短い Google Cloud 認証情報を取得できます。

GitLab SaaS

GitLab アカウントで構成を変更する必要はありません。

GitLab グループを信頼するように Workload Identity プールを構成すると、個々の CI / CD ジョブで Workload Identity 連携を有効にできます。

Terraform Cloud

Terraform Cloud アカウントで構成を変更する必要はありません。

Terraform Cloud を信頼するように Workload Identity プールを構成すると、個々のワークスペースで Workload Identity 連携を有効にできます。

Workload Identity 連携を構成する

この手順は、GitHub 組織、GitLab グループ、Terraform Cloud 組織ごとに行う必要があります。

Workload Identity 連携の構成を開始するには、次の操作を行います。

  1. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  2. Workload Identity プールとプロバイダの管理に専用のプロジェクトを使用することをおすすめします。
  3. Google Cloud プロジェクトで課金が有効になっていることを確認します

  4. IAM, Resource Manager, Service Account Credentials, and Security Token Service API を有効にします。

    API を有効にする

属性マッピングを定義する

デプロイ パイプラインの環境固有の認証情報には複数の属性を含めることができます。このため、Google Cloud でサブジェクト識別子(google.subject)として使用する属性を決定する必要があります。

必要に応じて、追加の属性をマッピングできます。これにより、リソースへのアクセス権を付与する際にこれらの追加属性を参照できます。

Azure DevOps

Azure DevOps ID トークンには、サービス接続のサブジェクト識別子を含む sub クレームが含まれています。サブジェクト識別子の形式は次のとおりです。

sc://ORGANIZATION/PROJECT/CONNECTION

この識別子を google.subject にマッピングするには、次の属性マッピングを使用します。

google.subject=assertion.sub

GitHub Actions

属性マッピングでは、GitHub Actions OIDC トークン内のすべてのクレームを使用できます。これらのトークン クレームキーとその値は GitHub によって制御されます。少なくとも、GitHub Actions OIDC トークンのサブジェクトに対応する google.subjectassertion.sub にマッピングする必要があります。

google.subject=assertion.sub

GitHub Actions の OIDC トークンのサブジェクトの値は、ソースイベントによって異なる場合があります。その他のクレーム属性には次のようなものがあります。

  • repository: オーナーとリポジトリ名が含まれます(例: "google/guava")。

  • repository_id: 一意のリポジトリ ID が含まれています(例: "20300177")。

  • repository_owner: オーナー(ユーザー名または GitHub 組織の名前)が含まれています(例: "google")。

  • repository_owner_id: 一意のオーナー ID が含まれています(例: "1342004")。

このリストは、可能性のあるクレームの一部です。完全なリストについては、クレームの例に関する GitHub ドキュメントをご覧ください。属性条件として使用するクレーム、または今後 principalSet 条件の一部として使用する予定のクレームを必ずマッピングします。

GitLab SaaS

属性マッピングでは、次のような GitLab ID トークンに埋め込まれたクレームをソース属性として使用できます。

  • sub: プロジェクト名と Git リファレンス(例: project_path:groupname/projectname:ref_type:branch:ref:main)。
  • namespace_id: 一意のグループ ID。
  • project_id: 一意のプロジェクト ID。
  • user_id: 一意のユーザー ID。
  • environment: ジョブが適用される環境。
  • ref_path: Git リファレンス(例: refs/heads/main)。

次の属性マッピングでは、google.subject を GitLab ID トークンの sub クレームに設定します。sub クレームにはリポジトリ名と Git リファレンスの両方が含まれるため、このマッピングによりプロジェクトとブランチによるアクセスを制御できます。

google.subject=assertion.sub

リポジトリとブランチによるアクセスの制御は、特定のブランチ(main など)が他のブランチ(機能ブランチなど)以外のリソースに対する異なるアクセスが必要な場合に役立ちます。

場合によっては、プロジェクトまたはグループでアクセスを区別するだけで十分です。次のマッピングには、GitLab の project_idnamespace_id を含む 2 つの追加属性が含まれています。

google.subject=assertion.sub
attribute.project_id=assertion.project_id
attribute.namespace_id=assertion.namespace_id

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 と評価されると、認証情報が受け入れられます。それ以外の場合、認証情報は拒否されます。すべての属性条件フィールドに属性マッピングが必要です。

Azure DevOps

必要に応じて、属性条件を使用して、特定のサービス接続へのアクセスを制限します。たとえば、次の条件は、特定の Azure DevOps プロジェクトの接続へのアクセスを制限しています。

assertion.sub.startsWith('sc://ORGANIZATION/PROJECT/')

次のように置き換えます。

  • ORGANIZATION: Azure DevOps 組織の名前。
  • PROJECT: Azure DevOps プロジェクトの名前。

GitHub Actions

GitHub 組織によって発行されたトークンへのアクセスを制限するには、次の属性条件を使用します。

assertion.repository_owner=='ORGANIZATION'

ORGANIZATION は、GitHub 組織の名前に置き換えます。

必要に応じて属性条件を拡張して、ワークフローまたはブランチのサブセットへのアクセスを制限します。たとえば、次の条件は、Git ブランチ main を使用するワークフローへのアクセスを制限します。

assertion.repository_owner=='ORGANIZATION' && assertion.ref=='refs/heads/main'

GitLab SaaS

次の属性条件を使用して、GitLab グループによって発行されるトークンへのアクセスを制限します。

assertion.namespace_id=='GROUP_ID'

GROUP_ID は、GitLab グループのホームページに表示されるグループ ID に置き換えます。

必要に応じて、属性条件を拡張して、プロジェクト、ブランチ、環境のサブセットへのアクセスを制限します。たとえば、次の条件は、環境 production を使用するジョブへのアクセスを制限します。

assertion.namespace_id=='GROUP_ID' && assertion.environment=='production'

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 プールとプロバイダの作成に必要な情報がすべて収集されました。

コンソール

  1. Google Cloud コンソールで、[新しいワークロード プロバイダとプール] ページに移動します。

    [新しいワークロード プロバイダとプール] に移動

  2. [ID プールを作成] に、次のように入力します。

    • 名前: プールの名前。この名前はプール ID としても使用されます。プール ID を後で変更することはできません。
    • 説明: プールの目的を説明するテキスト。
  3. [続行] をクリックします。

  4. プロバイダを構成します。

    Azure DevOps

    • Select a provider: OpenID Connect(OIDC)
    • Provider name: Azure DevOps プロジェクトの名前またはカスタム名。
    • Provider ID: Azure DevOps プロジェクトの名前またはカスタム ID。プロバイダ ID は後から変更できません。
    • Issuer URL: 以前に検索したサービス接続の発行元。
    • Audiences: [Allowed audiences] を選択して、次の値を貼り付けます。

      api://AzureADTokenExchange
      

    GitHub Actions

    • Select a provider: OpenID Connect(OIDC)
    • Provider name: プロバイダの名前。
    • Provider ID: プロバイダの ID。プロバイダ ID は後から変更できません。
    • 発行元 URL: https://token.actions.githubusercontent.com/
    • オーディエンス: デフォルトのオーディエンス

    GitLab SaaS

    • Select a provider: OpenID Connect(OIDC)
    • Provider name: プロバイダの名前。
    • Provider ID: プロバイダの ID。プロバイダ ID は後から変更できません。
    • 発行元 URL: https://gitlab.com
    • オーディエンス: デフォルトのオーディエンス

    Terraform Cloud

    • Select a provider: OpenID Connect(OIDC)
    • Provider name: プロバイダの名前。
    • Provider ID: プロバイダの ID。プロバイダ ID は後から変更できません。
    • 発行元 URL: https://app.terraform.io
    • オーディエンス: デフォルトのオーディエンス
  5. [続行] をクリックします。

  6. [プロバイダの属性を構成する] で、前に確認した属性マッピングを追加します。

  7. [属性条件] で、前に確認した属性条件を入力します。

  8. [保存] をクリックして、Workload Identity のプールとプロバイダを作成します。

gcloud

  1. 新しい 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 へのアクセス権を付与するときに表示されます。
  2. Workload Identity プールのプロバイダを追加します。

    Azure DevOps

    gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS"
    

    次の値を置き換えます。

    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/" \
        --allowed-audiences="api://AzureADTokenExchange" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS"
    

    次の値を置き換えます。

    GitLab SaaS

    gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="https://gitlab.com" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="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"
    

    次の値を置き換えます。

Workload Identity プロバイダの属性条件を更新する

このセクションでは、既存の Workload Identity プール プロバイダの属性条件を更新して、GitHub 組織、GitLab グループ、Terraform Cloud 組織によって発行されたトークンへのアクセスを制限する方法について説明します。

パイプラインに推奨される属性条件を確認するには、属性条件を定義するをご覧ください。

コンソール

  1. Google Cloud コンソールで、[Workload Identity プール] ページに移動します。

    [Workload Identity プール] に移動

  2. プロバイダを含む Workload Identity プールを見つけて、そのプールの「ノードを開く」アイコン()をクリックします。

  3. 編集する Workload Identity プール プロバイダを見つけて、[編集] をクリックします。

  4. [属性条件] で、前に確認した属性条件を入力します。

  5. Workload Identity のプールとプロバイダを更新するには、[保存] をクリックします。

gcloud

Workload Identity プールのプロバイダを更新するには、次のコマンドを実行します。

gcloud iam workload-identity-pools providers update-oidc PROVIDER_ID \
    --location="global" \
    --workload-identity-pool="POOL_ID" \
    --attribute-condition="CONDITIONS"

次の値を置き換えます。

デプロイ パイプラインを認証する

この手順は、GitHub Actions ワークフローまたは Terraform Cloud ワークスペースごとに行う必要があります。

デプロイ パイプライン用のサービス アカウントを作成する

  1. IAM, Security Token Service, and Service Account Credentials API を有効にします。

    API を有効にする

  2. ワークロードを表すサービス アカウントを作成します。デプロイ パイプラインごとに専用のサービス アカウントを使用することをおすすめします。

    サービス アカウントは、Workload Identity プールと同じプロジェクトにある必要はありません。

  3. 外部 ID にアクセスを許可するリソースに対するアクセス権をサービス アカウントに付与します。

デプロイ パイプラインによるサービス アカウントの権限借用を許可する

外部 ID にサービス アカウントの権限借用を許可するには、サービス アカウントに Workload Identity ユーザーロール(roles/iam.workloadIdentityUser)を付与します。このロールは、特定の外部 ID または複数の外部 ID に付与できます。

  • 特定の外部 ID の場合は、google.subject 属性をチェックする属性条件を記述します。
  • 外部 ID のグループの場合は、google.groups 属性またはカスタム属性 attribute.NAME をチェックする属性条件を記述します。

コンソール

Google Cloud コンソールを使用して外部 ID にサービス アカウントの権限借用を許可するには、次の操作を行います。

  1. Google Cloud コンソールで、[Workload Identity プール] ページに移動します。

    [Workload Identity プール] に移動

  2. 更新する Workload Identity プールを見つけて選択します。

  3. 選択した Workload Identity プールへのアクセス権を付与するには、[ アクセスを許可] をクリックします。

  4. [サービス アカウント] リストで、権限を借用する外部 ID のサービス アカウントを選択します。

  5. プール内のどの ID がサービス アカウントの権限を借用できるかを選択するには、次のいずれかを行います。

    • Workload Identity プールの特定の ID のみにサービス アカウントの権限借用を許可するには、[フィルタに一致する ID のみ] を選択します。

      [属性名] リストで、フィルタリングする属性を選択します。

      [属性値] フィールドに、属性の想定値を入力します。たとえば、属性マッピング google.subject=assertion.sub を使用する場合は、属性名を subject に設定します。属性値には、外部 ID プロバイダによって発行されたトークンの sub クレームの値を設定します。

  6. 構成を保存するには、[保存]、[閉じる] の順にクリックします。

gcloud

gcloud CLI を使用して、外部 ID にサービス アカウントの権限借用を許可するには、次の操作を行います。

  1. 現在のプロジェクトのプロジェクト番号を取得するには、次のコマンドを実行します。

    gcloud projects describe $(gcloud config get-value core/project) --format=value\(projectNumber\)
    
  2. 特定の条件を満たす外部 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"
    

    次のように置き換えます。

    • SERVICE_ACCOUNT_EMAIL: サービス アカウントのメールアドレス
    • PROJECT_NUMBER: Workload Identity プールを含むプロジェクトのプロジェクト番号
    • POOL_ID: Workload Identity プールのプール ID
    • SUBJECT: google.subjectマッピングされている属性の想定値
    • GROUP: google.groupsマッピングされている属性の想定値
    • ATTRIBUTE_NAME: 属性マッピングのカスタム属性の名前

デプロイ パイプラインを構成する

この時点で、デプロイ パイプラインで Workload Identity 連携を使用する準備ができています。

Azure DevOps

azure-pipelines.yml ファイルを編集して、ジョブ構成に以下を追加します。

variables:
- name: Azure.WorkloadIdentity.Connection
  value: CONNECTION
- name: GoogleCloud.WorkloadIdentity.ProjectNumber
  value: PROJECT_NUMBER
- name: GoogleCloud.WorkloadIdentity.Pool
  value: POOL_ID
- name: GoogleCloud.WorkloadIdentity.Provider
  value: PROVIDER_ID
- name: GoogleCloud.WorkloadIdentity.ServiceAccount
  value: SERVICE_ACCOUNT_EMAIL
- name: GOOGLE_APPLICATION_CREDENTIALS
  value: $(Pipeline.Workspace)/.workload_identity.wlconfig

steps:
  - task: AzureCLI@2
    inputs:
      connectedServiceNameARM: $(Azure.WorkloadIdentity.Connection)
      addSpnToEnvironment: true
      scriptType: 'bash'
      scriptLocation: 'inlineScript'
      inlineScript: |
        echo $idToken > $(Pipeline.Workspace)/.workload_identity.jwt
        cat << EOF > $GOOGLE_APPLICATION_CREDENTIALS
        {
          "type": "external_account",
          "audience": "//iam.googleapis.com/projects/$(GoogleCloud.WorkloadIdentity.ProjectNumber)/locations/global/workloadIdentityPools/$(GoogleCloud.WorkloadIdentity.Pool)/providers/$(GoogleCloud.WorkloadIdentity.Provider)",
          "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
          "token_url": "https://sts.googleapis.com/v1/token",
          "credential_source": {
            "file": "$(Pipeline.Workspace)/.workload_identity.jwt"
          },
          "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$(GoogleCloud.WorkloadIdentity.ServiceAccount):generateAccessToken"
        }
        EOF

次の値を置き換えます。

  • CONNECTION: サービス接続の名前
  • PROJECT_NUMBER: Workload Identity プールを含むプロジェクトのプロジェクト番号
  • POOL_ID: Workload Identity プールの ID
  • PROVIDER_ID: Workload Identity プール プロバイダの ID
  • SERVICE_ACCOUNT_EMAIL: サービス アカウントのメールアドレス

この構成では、次の処理が行われます。

  1. AzureCLI タスクを使用して、サービス接続の ID トークンを取得し、idToken 変数で使用できるようにします。
  2. ID トークンを .workload_identity.jwt という一時ファイルに保存します。
  3. .workload_identity.jwt から ID トークンを読み取り、それを使用してサービス アカウントの権限を借用するようにクライアント ライブラリに指示する認証情報構成ファイルを作成します。
  4. 認証情報構成ファイルを参照するように環境変数 GOOGLE_APPLICATION_CREDENTIALS を設定します。

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@v1'
      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 プールの ID
  • PROVIDER_ID: Workload Identity プール プロバイダの ID
  • SERVICE_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@v3

      - id: 'auth'
        name: 'Authenticate to Google Cloud'
        uses: 'google-github-actions/auth@v1'
        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 連携の設定をご覧ください。

GitLab SaaS

.gitlab-ci.yml ファイルを編集して、ジョブ構成に以下を追加します。

job:
  variables:
    WORKLOAD_IDENTITY_PROJECT_NUMBER: PROJECT_NUMBER
    WORKLOAD_IDENTITY_POOL: POOL_ID
    WORKLOAD_IDENTITY_PROVIDER: PROVIDER_ID
    SERVICE_ACCOUNT: SERVICE_ACCOUNT_EMAIL
    GOOGLE_APPLICATION_CREDENTIALS: $CI_BUILDS_DIR/.workload_identity.wlconfig

  id_tokens:
    WORKLOAD_IDENTITY_TOKEN:
      aud: https://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID

  script:
    - |-
      echo $WORKLOAD_IDENTITY_TOKEN > $CI_BUILDS_DIR/.workload_identity.jwt
      cat << EOF > $GOOGLE_APPLICATION_CREDENTIALS
      {
        "type": "external_account",
        "audience": "//iam.googleapis.com/projects/$WORKLOAD_IDENTITY_PROJECT_NUMBER/locations/global/workloadIdentityPools/$WORKLOAD_IDENTITY_POOL/providers/$WORKLOAD_IDENTITY_PROVIDER",
        "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
        "token_url": "https://sts.googleapis.com/v1/token",
        "credential_source": {
          "file": "$CI_BUILDS_DIR/.workload_identity.jwt"
        },
        "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$SERVICE_ACCOUNT:generateAccessToken"
      }
      EOF

次の値を置き換えます。

  • PROJECT_NUMBER: Workload Identity プールを含むプロジェクトのプロジェクト番号
  • POOL_ID: Workload Identity プールの ID
  • PROVIDER_ID: Workload Identity プール プロバイダの ID
  • SERVICE_ACCOUNT_EMAIL: サービス アカウントのメールアドレス

この構成では、次の処理が行われます。

  1. ID トークンを発行し、WORKLOAD_IDENTITY_TOKEN という名前の環境変数で使用できるように GitLab に指示します。ID トークンは、Workload Identity プールのプロバイダをオーディエンスとして使用します。
  2. ID トークンを .workload_identity.jwt という名前の一時ファイルに保存します。
  3. .workload_identity.jwt から ID トークンを読み取り、それを使用してサービス アカウントの権限を借用するようにクライアント ライブラリに指示する認証情報構成ファイルを作成します。
  4. 認証情報の構成ファイルを参照するように環境変数 GOOGLE_APPLICATION_CREDENTIALS を設定します。

Terraform Cloud

Terraform Cloud ワークスペースで Workload Identity 連携を使用して Google Cloud への認証を行えるように構成します。

  1. Terraform Cloud でワークスペースを開き、[Variables] に移動します。

  2. 次の変数を追加します。

    変数のカテゴリ キー
    環境変数 TFC_GCP_PROVIDER_AUTH true
    環境変数 TFC_GCP_RUN_SERVICE_ACCOUNT_EMAIL サービス アカウントのメールアドレス(例: terraform@my-project-123.iam.gserviceaccount.com
    環境変数 TFC_GCP_PROJECT_NUMBER Workload Identity プールを含むプロジェクトのプロジェクト番号
    環境変数 TFC_GCP_WORKLOAD_POOL_ID Workload Identity プールの ID
    環境変数 TFC_GCP_WORKLOAD_PROVIDER_ID Workload Identity プール プロバイダの ID

    必要に応じて環境変数を追加し、Terrform Cloud で plan フェーズと apply フェーズに異なるサービス アカウントを使用できるようにします。詳細については、オプションの環境変数をご覧ください。

  3. 変数のリストで、前の手順で追加した 5 つの変数のカテゴリenv に設定されていることを確認します。

  4. Terraform 構成で、バージョン 4.48.0 以降の Google Cloud プロバイダが使用されていることを確認し、必要に応じて次のように更新します。

    terraform {
      required_providers {
        google = {
          source  = "hashicorp/google"
          version = "~> 4.48.0"
        }
      }
    }
    
  5. ソースコード リポジトリに変更を送信します。

次のステップ