Zenn
🐕

Bitbucket Pipeline × Google Cloud Workload Identity連携

2025/01/17に公開

概要

BitBcuket PilpelineとGoogle CloudのWorkload Identity連携でサービスアカウントの発行無しで、Pipelineの連携を行う手順を備忘録として記載します。

操作は、Console画面から実施します。

手順

1. OIDC(OpenID Connect)でIdentityプロバイダを確認

bitbucketの「Pipeline > OpenID Connect」のURLAudienceの情報を確認し、メモしておきます。

2. Workload Identityプールでプロバイダの設定

Google Cloudの「IAM > Workload Identity 連携」でプロバイダとプールを作成します。

項目 設定値
プール名 test-bitbucket
プロバイダの選択 OpenID Cpnnect
プロバイダ名 test-bitbucket
プロバイダID test-bitbucket
URL <1.で確認したURL> (https://api.bitbucket.org...)
オーディエンス ✅許可するオーディエンス <1.で確認したAudience> (ari:cloud:bitbucket...)
プロバイダの属性1 : google.subject assertion.sub
プロバイダの属性2(追加) : attribute.workspace_uuid assertion.workspaceUuid

今回、属性条件(IDのサブセットのみ認証を制限する)は指定しません。

作成が完了すると以下のような「IAMプリンシパル」が生成されます。

principal://iam.googleapis.com/projects/<project_id>/locations/global/workloadIdentityPools/test-bitbucket/subject/SUBJECT_ATTRIBUTE_VALUE

サービスアカウントへのアクセスを許可するには、SUBJECT_ATTRIBUTE_VALUE を Workload Identity プール内の特定のサブジェクトに置き換え、そのプリンシパルにサービスアカウントに対する Workload Identity ユーザーロールを付与します。

また、プリンシパルのIDは任意の属性に一致するIDを指定することが可能なので、今回はATTRIBUTE_VALUEでBitBuket Pipeline上のWorkspace UUIDと一致するプリンシパルを用意します。

  • principalSetの指定:principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/attribute.ATTRIBUTE_NAME/ATTRIBUTE_VALUE
  • Sample:principalSet://iam.googleapis.com/projects/<project_id>/locations/global/workloadIdentityPools/<pool_id>/attribute.workspace_uuid/<Workspace UUID:{3fa48120-66b0...>

https://cloud.google.com/iam/docs/principal-identifiers

3. IAM権限の設定と構成ファイルの取得

上記のプリンシパルをIAMで登録します。今回は、Pipelineの動作確認のため cloud storageのバケット一覧を確認するため、roles/storage.adminを上記プリンシパルに付与します。

設定の順序は特に関係ありませんが、ファイルパスに /tmp/oidc-token.txt を指定し構成をダウンロードします。

4. Pipelineの設定

ダウンロードした構成ファイルをBitbucketのDeploymentの任意の環境でBITBUCKET_STEP_OIDC_TOKENの環境変数を上記の構成ファイルのJSON文字列をコピー&ペーストして設定します。

Pipeline上で環境変数で指定したJSONを

echo -n "${BITBUCKET_STEP_OIDC_TOKEN}" > /tmp/oidc-token.txt

で出力し、対象のOIDCの構成ファイルを元に

gcloud iam workload-identity-pools create-cred-config <対象のプリンシパル> <構成ファイル> <出力ファイル>

として認証情報を発行し、GOOGLE_APPLICATION_CREDENTIALS(GAC)に指定する事でデフォルトの認証情報として以降の処理を実行するようにします。

pipelines:
  default:
    - step:
        name: test
        oidc: true
        image: google/cloud-sdk:alpine
        script:
        - export GCP_PROJECT_NUMBER=<project_id>
        - export PROJECT_NAME=<project_name>

        - export workload_identity_pool_id='test-bitbucket'

        - export workload_identity_pool_provider_id='test-bitbucket'
        
        - echo -n "${BITBUCKET_STEP_OIDC_TOKEN}" > /tmp/oidc-token.out

        - gcloud iam workload-identity-pools create-cred-config "projects/${GCP_PROJECT_NUMBER}/locations/global/workloadIdentityPools/${workload_identity_pool_id}/providers/${workload_identity_pool_provider_id}" --credential-source-file=/tmp/oidc-token.out --output-file=creds.json

        - export GOOGLE_APPLICATION_CREDENTIALS=`pwd`/creds.json

        - gcloud auth login --cred-file=`pwd`/creds.json

        - CLOUDSDK_CORE_DISABLE_PROMPTS=1 gcloud components install alpha

        - gcloud --project "${PROJECT_NAME}" storage ls 

4. 結果

上記のPipelineを実行することによって、サービスアカウントは発行せずに、バケットの一覧が取得でき、アクセストークンの交換の結果が指標として表示されました。

gs://gcf-.../
gs://...

備考

principalSubjectとWorkspace UUIDが一致しない場合

IAMで管理しているプリンシパルのUUIDを変更してPipelineを実行してみます

principalSet://iam.googleapis.com/projects/<project_id>/locations/global/workloadIdentityPools/test-bitbucket/attribute.workspace_uuid/{3fa_test}

Unique identifiersと一致しないため、権限が無く失敗しました。

参考

Discussion

ログインするとコメントできます