Bitbucket Cloud ホストに接続する

このページでは、Bitbucket Cloud ホストを Cloud Build に接続する方法について説明します。

始める前に

  • Cloud Build、Secret Manager、Compute Engine の各 API を有効にします。

    API を有効にするために必要なロール

    API を有効にするには、serviceusage.services.enable 権限が必要です。プロジェクトを作成した場合は、オーナーロール(roles/owner)によってこの権限が付与されている可能性があります。それ以外の場合は、Service Usage 管理者ロール(roles/serviceusage.serviceUsageAdmin)によってこの権限を取得できます。ロールを付与する方法をご覧ください

    API を有効にする

必要な IAM 権限

が接続に必要な権限を持っていることを確認するには、ユーザー アカウントに対する Cloud Build 接続管理者(cloudbuild.connectionAdmin)IAM ロールを付与するように管理者に依頼してください。ロールの付与については、プロジェクト、フォルダ、組織へのアクセスを管理するをご覧ください。

管理者は、カスタム ロールや他の事前定義 ロールを使用して、必要な権限を付与することもできます。

Bitbucket Cloud アクセス トークンを作成する

Bitbucket Cloud に次の 2 つのアクセス トークンを作成します。

  • 管理者アクセス トークン - リポジトリの接続と切断に使用します。
  • 読み取りアクセス トークン - Cloud Build にソースコードへのアクセスを許可します。

これらのトークンを作成する手順は次のとおりです。

  1. Bitbucket Cloud にログインします。

  2. Bitbucket Cloud の手順に従って、リポジトリプロジェクト またはワークスペースにリンクするアクセス トークンを作成します。

    次の権限を付与します。

    • 管理者アクセス トークン:

      • リポジトリ: 読み取り管理者
      • pull リクエスト: 読み取り
      • Webhook: 読み取り書き込み
    • 読み取りアクセス トークン:

      • リポジトリ: 読み取り
  3. 次の手順で使用するためにトークンをコピーします。

Bitbucket Cloud ホストに接続する

コンソール

次の手順で、Cloud Build を Bitbucket Cloud ホストに接続します。

  1. [リポジトリ] ページを Google Cloud コンソールで開きます。

    [リポジトリ] ページを開く

    [リポジトリ] ページが表示されます。

  2. プロジェクト セレクタで、 Google Cloud プロジェクトを選択します。

  3. ページ上部の [第 2 世代] タブを選択します。

  4. [ホスト接続の作成] をクリックして、新しいホストを Cloud Build に接続します。

  5. 左側のパネルで、ソース プロバイダとして Bitbucket を選択します。

  6. [接続の構成] セクションで、次の情報を入力します。

    • [リージョン]: 接続のリージョンを選択します。

    • [**名前**]: 接続の名前を入力します。

  7. [ホストの詳細] セクションに、次の情報を入力します。

    • ホストタイプとして [Bitbucket Cloud] を選択します。

    • ワークスペース: Bitbucket Cloud リポジトリのワークスペース ID を入力します。

  8. 省略可: Bitbucket Cloud リポジトリのアクセス トークンの暗号化に使用する暗号鍵を管理する場合は、[暗号化] セクションに移動して、Cloud Key Management Service 鍵を選択します。 詳細については、 Secret Manager の顧客管理の暗号鍵を有効にするをご覧ください。

  9. [アクセス トークン] セクションに、次の情報を入力します。

    • [**管理者アクセス トークン**]: 以前に 作成した管理者アクセス トークンを入力します。

    • [**読み取りアクセス トークン**]: 以前に作成した読み取りアクセス トークン を入力します

  10. [接続] をクリックします。

    新しい接続が [リポジトリ] ページに表示されます。

gcloud

  1. 認証情報を保存するには、次の手順を行います。

    1. 次のコマンドを実行して、 Google Cloud プロジェクトの Secret Manager にアクセス トークンを保存します。

      echo -n ADMIN_TOKEN | gcloud secrets create ADMIN_SECRET_NAME --data-file=-
      
      echo -n READ_TOKEN | gcloud secrets create READ_SECRET_NAME --data-file=-
      

      ここで

      • ADMIN_TOKEN は、管理者アクセス トークンです。
      • ADMIN_SECRET_NAME は、Secret Manager で管理者アクセス トークンのシークレットに付ける名前です。
      • READ_TOKEN は、読み取りアクセス トークンです。
      • READ_SECRET_NAME は、Secret Manager で読み取りアクセス トークンのシークレットに付ける名前です。
    2. 次のコマンドを実行して、Secret Manager で Webhook シークレットを作成します。ここで、WEBHOOK_SECRET_NAME は Webhook シークレットに付ける名前です。

      echo -n ${ex.(random-uuid)} | gcloud secrets create WEBHOOK_SECRET_NAME --data-file=-
      
    3. シークレットがすべて同じプロジェクト内にない場合は、次のコマンドを実行して Cloud Build サービス エージェントへのアクセス権を付与します。

      PN=$(gcloud projects describe PROJECT_ID --format="value(projectNumber)")
      CLOUD_BUILD_SERVICE_ACCOUNT="service-${PN}@gcp-sa-cloudbuild.iam.gserviceaccount.com"
      gcloud secrets add-iam-policy-binding ADMIN_SECRET_NAME \
          --member="serviceAccount:${CLOUD_BUILD_SERVICE_ACCOUNT}" \
          --role="roles/secretmanager.secretAccessor"
      
      gcloud secrets add-iam-policy-binding READ_SECRET_NAME \
          --member="serviceAccount:${CLOUD_BUILD_SERVICE_ACCOUNT}" \
          --role="roles/secretmanager.secretAccessor"
      
      gcloud secrets add-iam-policy-binding WEBHOOK_SECRET_NAME \
          --member="serviceAccount:${CLOUD_BUILD_SERVICE_ACCOUNT}" \
          --role="roles/secretmanager.secretAccessor"
      

      ここで

      • PROJECT_ID は Google Cloud プロジェクト ID です。
      • ADMIN_SECRET_NAME は、管理トークン シークレットの名前です。
      • READ_SECRET_NAME は、読み取りトークンのシークレットの名前です。
      • WEBHOOK_SECRET_NAME は、Webhook シークレットの名前です。
  2. 次のコマンドを使用して、Cloud Build を Bitbucket Cloud ホストに接続します。

    gcloud builds connections create bitbucket-cloud CONNECTION_NAME \
        --workspace=WORKSPACE_ID \
        --project=PROJECT_ID \
        --region=REGION \
        --authorizer-token-secret-version=projects/PROJECT_ID/secrets/ADMIN_SECRET_NAME/versions/latest \
        --read-authorizer-token-secret-version=projects/PROJECT_ID/secrets/READ_SECRET_NAME/versions/latest \
        --webhook-secret-secret-version=projects/PROJECT_ID/secrets/WEBHOOK_SECRET_NAME/versions/1
    

    ここで

    • CONNECTION_NAME は、Bitbucket Cloud ホストへの接続に付ける名前です。
    • WORKSPACE_ID は、Bitbucket Cloud リポジトリのワークスペース ID です。
    • PROJECT_ID は Google Cloud プロジェクト ID です。
    • REGION は、ホスト接続のリージョンです。
    • ADMIN_SECRET_NAME は、管理トークン シークレットの名前です。
    • READ_SECRET_NAME は、読み取りアクセス トークンのシークレットの名前です。
    • WEBHOOK_SECRET_NAME は、Webhook シークレットの名前です。

Terraform

Terraform を使用して Bitbucket Cloud ホストを Cloud Build に接続できます。

以下の例では、コード スニペットで次のことを行います。

  • Terraform Google プロバイダを構成します。
  • Bitbucket トークンを保存する Secret Manager のシークレットを作成します。
  • シークレットにアクセスするために必要な権限を Cloud Build サービス エージェントに付与します。
  • Bitbucket Cloud 接続を作成します。

    // Configure the Terraform Google provider
    terraform {
      required_providers {
        google = {}
      }
    }
    
    provider "google" {
      project = "PROJECT_ID"
      region = "REGION"
    }
    
    // Create secrets and grant permissions to the Cloud Build service agent
    resource "google_secret_manager_secret" "admin-token-secret" {
        project = "PROJECT_ID"
        secret_id = "ADMIN_TOKEN_NAME"
    
        replication {
            auto {}
        }
    }
    
    resource "google_secret_manager_secret_version" "admin-token-secret-version" {
        secret = google_secret_manager_secret.admin-token-secret.id
        secret_data = "ADMIN_TOKEN_VALUE"
    }
    
    resource "google_secret_manager_secret" "read-token-secret" {
        project = "PROJECT_ID"
        secret_id = "READ_TOKEN_NAME"
    
        replication {
            auto {}
        }
    }
    
    resource "google_secret_manager_secret_version" "read-token-secret-version" {
        secret = google_secret_manager_secret.read-token-secret.id
        secret_data = "READ_TOKEN_VALUE"
    }
    
    resource "google_secret_manager_secret" "webhook-secret-secret" {
        project = "PROJECT_ID"
        secret_id = "WEBHOOK_SECRET_NAME"
    
        replication {
            auto {}
        }
    }
    
    resource "google_secret_manager_secret_version" "webhook-secret-secret-version" {
        secret = google_secret_manager_secret.webhook-secret-secret.id
        secret_data = "WEBHOOK_SECRET_VALUE"
    }
    
    data "google_iam_policy" "p4sa-secretAccessor" {
        binding {
            role = "roles/secretmanager.secretAccessor"
            members = ["serviceAccount:service-PROJECT_NUMBER@gcp-sa-cloudbuild.iam.gserviceaccount.com"]
        }
    }
    
    resource "google_secret_manager_secret_iam_policy" "policy-pak" {
      project = google_secret_manager_secret.admin-token-secret.project
      secret_id = google_secret_manager_secret.admin-token-secret.secret_id
      policy_data = data.google_iam_policy.p4sa-secretAccessor.policy_data
    }
    
    resource "google_secret_manager_secret_iam_policy" "policy-rpak" {
      project = google_secret_manager_secret.read-token-secret.project
      secret_id = google_secret_manager_secret.read-token-secret.secret_id
      policy_data = data.google_iam_policy.p4sa-secretAccessor.policy_data
    }
    
    resource "google_secret_manager_secret_iam_policy" "policy-whs" {
      project = google_secret_manager_secret.webhook-secret-secret.project
      secret_id = google_secret_manager_secret.webhook-secret-secret.secret_id
      policy_data = data.google_iam_policy.p4sa-secretAccessor.policy_data
    }
    
    // Create the connection and add the repository resource
    resource "google_cloudbuildv2_connection" "my-connection" {
        project = "PROJECT_ID"
        location = "REGION"
        name = "CONNECTION_NAME"
    
        bitbucket_cloud_config {
            workspace = "WORKSPACE_ID"
            authorizer_credential {
                user_token_secret_version = google_secret_manager_secret_version.admin-token-secret-version.id
            }
            read_authorizer_credential {
                user_token_secret_version = google_secret_manager_secret_version.read-token-secret-version.id
            }
            webhook_secret_secret_version = google_secret_manager_secret_version.webhook-secret-secret-version.id
        }
    
        depends_on = [
            google_secret_manager_secret_iam_policy.policy-pak,
            google_secret_manager_secret_iam_policy.policy-rpak,
            google_secret_manager_secret_iam_policy.policy-whs
        ]
    }
    

ここで

  • PROJECT_ID は Google Cloud プロジェクト ID です。
  • PROJECT_NUMBER は Google Cloud プロジェクト番号です。
  • ADMIN_TOKEN_NAME は、webhookrepositoryrepository:adminpullrequest のアクセス範囲を持つトークンの名前です。
  • ADMIN_TOKEN_VALUEADMIN_TOKEN_NAME の値です。
  • READ_TOKEN_NAME は、スコープが repository:read のトークンの名前です。
  • READ_TOKEN_VALUEREAD_TOKEN_NAME の値です。
  • WEBHOOK_SECRET_NAME は、Webhook シークレットの名前です。
  • WEBHOOK_SECRET_VALUEWEBHOOK_SECRET_NAME の値です。
  • REGION は、接続のリージョンです。
  • CONNECTION_NAME は接続の名前です。
  • WORKSPACE_ID は、Bitbucket Cloud リポジトリのワークスペース ID です。

古い Bitbucket Cloud アクセス トークンまたは期限切れの Bitbucket Cloud アクセス トークンをローテーションする

Cloud Build ホスト接続が Bitbucket Cloud リポジトリへの接続を維持できるように、アクセス トークンをローテーションします。 Bitbucket Cloud アクセス トークンの有効期限が切れると、Cloud Build ホスト接続が Bitbucket Cloud リポジトリから切断されます。この場合、期限切れのトークンをローテーションするまで、接続を無効にしたり、リポジトリをリンクしたりすることはできません。また、次のような状況でエラーが発生します。

  • 接続の [接続の詳細] ページに、Connection is disconnected due to an invalid or expired access token というエラー メッセージが表示されます。

  • 期限切れのトークンを持つ接続にリポジトリをリンクしようとすると、[無効なアクセス トークン] メッセージが表示されます。[接続を表示] をクリックすると、期限切れのトークンを持つ接続の [接続の詳細] ページに移動します。

Cloud Build では、新しいトークン値を入力して、それらのトークンの最新のシークレット バージョンで Secret Manager に保存することで、アクセス トークンをローテーションできます。アクセス トークンをローテーションする手順は次のとおりです。

  1. Bitbucket Cloud で各アクセス トークンをローテーションします。

    1. Cloud Build ホスト接続に接続されている Bitbucket Cloud リポジトリに移動します。

    2. Bitbucket のドキュメントの手順に沿って、アクセス トークンを ローテーションします。 トークンをローテーションすると、Bitbucket Cloud は新しい認証情報で新しいトークンを作成し、そのトークンの以前のバージョンを無効にします。ローテーションされたトークンには、元のトークンと同じ権限とスコープが付与されます。

    3. ローテーションされたトークンの ID をコピーします。

  2. Cloud Build でアクセス トークンを更新します。

    1. 接続の [接続の詳細] ページに移動します。

    2. [アクセス トークンを更新] を選択します。

    3. [トークンのローテーション] メニューで、[API アクセス トークン] フィールドと [読み取りアクセス トークン] フィールドに新しいトークンを入力します。

    4. (省略可)接続でトークンの最新バージョンのシークレットを常に使用する場合は、[常に最新バージョンを使用するように接続を更新する] を選択します。接続で特定のシークレット バージョン番号を使用している場合は、このオプションを選択しない方がよい場合があります。

    5. [更新] を選択して、変更を保存します。

      Cloud Build は、新しいアクセス トークンを Secret Manager のシークレットの最新バージョンとして保存します。

詳細については、アクセス トークンBitbucket のセキュリティ強化: Bitbucket Cloud ドキュメントのアクセス トークンの有効期限の導入 をご覧ください。

次のステップ