Connect to a Bitbucket Cloud host

This page explains how to connect a Bitbucket Cloud host to Cloud Build.

Before you begin

  • Enable the Cloud Build, Secret Manager, and Compute Engine APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  • Ensure that the source code is in a Bitbucket Cloud repository.
  • Ensure that the Bitbucket Cloud source repository has either a Dockerfile or a Cloud Build config file.
  • Install the Google Cloud CLI to use gcloud commands.

Required IAM permissions

To ensure that has the necessary permissions to connect, ask your administrator to grant the Cloud Build Connection Admin (cloudbuild.connectionAdmin) IAM role on your user account. For more information about granting roles, see Manage access to projects, folders, and organizations.

Your administrator might also be able to give the required permissions through custom roles or other predefined roles.

Create Bitbucket Cloud access tokens

Create the following two access tokens in Bitbucket Cloud:

  • Admin access token - for connecting and disconnecting repositories.
  • Read access token - to allow Cloud Build to access your source code.

To create these tokens, follow these steps:

  1. Sign in to Bitbucket Cloud.

  2. Follow the Bitbucket Cloud instructions to create access tokens linked to your repository, project, or workspace.

    Grant the following permissions:

    • Admin access token:

      • Repositories: Read and Admin
      • Pull Requests: Read
      • Webhooks: Read and Write
    • Read access token:

      • Repositories: Read
  3. Copy your tokens for use in the following procedures.

Connect to a Bitbucket Cloud host

Console

Connect Cloud Build to your Bitbucket Cloud host by completing the following steps:

  1. Open the Repositories page in the Google Cloud console.

    Open the Repositories page

    You will see the Repositories page.

  2. In the project selector, select your Google Cloud project.

  3. At the top of the page, select the 2nd gen tab.

  4. Click Create host connection to connect a new host to Cloud Build.

  5. Select Bitbucket as your source provider.

  6. In the Configure Connection section, enter the following information:

    1. Region: Select a region for your connection.

    2. Name: Enter a name for your connection.

    3. In the Host details section, select Bitbucket Cloud as your host type.

    4. Workspace: Enter the workspace ID for your Bitbucket Cloud repository.

    5. Access token: Enter your admin access token created previously.

    6. Read access token: Enter your read access token created previously.

  7. Click Connect.

    The new connection appears in the Repositories page.

gcloud

  1. Complete the following steps to store your credentials:

    1. Store your access tokens in Secret Manager in your Google Cloud project by running the following commands:

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

      Where:

      • ADMIN_TOKEN is your admin access token.
      • ADMIN_SECRET_NAME is the name you want to give to your admin access token secret in Secret Manager.
      • READ_TOKEN is your read access token.
      • READ_SECRET_NAME is the name you want to give to your read access token secret in Secret Manager.
    2. Create a webhook secret in Secret Manager by running the following command, where WEBHOOK_SECRET_NAME is the name you want to give to your webhook secret:

      echo -n ${ex.(random-uuid)} | gcloud secrets create WEBHOOK_SECRET_NAME --data-file=-
      
    3. If your secrets aren't all in the same project, grant access to your Cloud Build service agent by running the following:

      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"
      

      Where:

      • PROJECT_ID is your Google Cloud project ID.
      • ADMIN_SECRET_NAME is the name of your admin token secret.
      • READ_SECRET_NAME is the name of your read token secret.
      • WEBHOOK_SECRET_NAME is the name of your webhook secret.
  2. Connect Cloud Build to your Bitbucket Cloud host by using the following command:

    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
    

    Where:

    • CONNECTION_NAME is the name you want to give to the connection to your Bitbucket Cloud host.
    • WORKSPACE_ID is the Workspace ID for your Bitbucket Cloud repository.
    • PROJECT_ID is your Google Cloud project ID.
    • REGION is the region for your host connection.
    • ADMIN_SECRET_NAME is the name of your admin token secret.
    • READ_SECRET_NAME is the name of your read access token secret.
    • WEBHOOK_SECRET_NAME is the name of your webhook secret.

Terraform

You can connect your Bitbucket Cloud host to Cloud Build using Terraform.

In the following example, the code snippet does the following:

  • Configures the Terraform Google provider.
  • Creates a Secret Manager secret to store the Bitbucket tokens.
  • Grants necessary permissions to the Cloud Build service agent to access secrets.
  • Creates a Bitbucket Cloud connection.

    // 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
        ]
    }
    

Where:

  • PROJECT_ID is your Google Cloud project ID.
  • PROJECT_NUMBER is your Google Cloud project number.
  • ADMIN_TOKEN_NAME is the name of your token with webhook, repository, repository:admin, and pullrequest scope access.
  • ADMIN_TOKEN_VALUE is the value of your ADMIN_TOKEN_NAME.
  • READ_TOKEN_NAME is the name of your token with repository:read scope.
  • READ_TOKEN_VALUE is the value of your READ_TOKEN_NAME.
  • WEBHOOK_SECRET_NAME is the name of your webhook secret.
  • WEBHOOK_SECRET_VALUE is the value of your WEBHOOK_SECRET_NAME.
  • REGION is the region for your connection.
  • CONNECTION_NAME is the name of your connection.
  • WORKSPACE_ID is the Workspace ID for your Bitbucket Cloud repository.

Rotate old or expired Bitbucket Cloud access tokens

If your Bitbucket Cloud access token expires, then your Cloud Build host connection is disconnected from its Bitbucket Cloud repository. As a result, you will see errors in the following circumstances:

  • When you try to link a Bitbucket Cloud repository Cloud Build connection, a Failed to fetch repositories to link. Check that Cloud Build is still authorized to access data from the selected connection message appears.

  • On the Triggers page, when you click Run, the Run trigger page opens and shows a Failed to list branches. You can still enter one manually message.

To rotate an old or expired token for your connection, do the following:

  1. Find the secrets associated with your host connection:

    1. Run the following command:

      gcloud builds connections describe CONNECTION_PATH --region=REGION
      

      Where:

      • CONNECTION_PATH is the path of your Bitbucket Cloud host connection in Cloud Build, in the format projects/PROJECT_ID/locations/REGION/connections/CONNECTION_NAME.
      • REGION is the region for your connection.
    2. In the output of the command, look for the values of your user token fields. readAuthorizerCredential.userTokenSecretVersion shows the Secret Manager name of the Read token, and authorizerCredential.userTokenSecretVersion shows the Secret Manager name of the Admin token. These names are stored as secrets in Secret Manager.

  2. Rotate each access token in Bitbucket Cloud:

    1. Go to the Bitbucket Cloud repository connected to your Cloud Build host connection.

    2. Follow the instructions in the Bitbucket documentation to rotate an access token. When you rotate a token, Bitbucket Cloud creates a new token with new credentials and invalidates the previous version of that token. Your rotated token has the same permissions and scope as the original token.

    3. Copy the ID of your rotated token.

  3. Create a new secret version for each token:

    1. Open the Secret Manager page in the Google Cloud console:

      Open the Secret Manager page

    2. For each token that you rotated, find the secret name that you identified in Step 1 and click Actions, and then click Add new version.

    3. In the Add new version window, enter the ID of your rotated token and then click Add new version.

For more information, see Access tokens and Enhancing security in Bitbucket: Introducing expiry for access tokens in the Bitbucket Cloud documentation.

What's next