Bitbucket Cloud 호스트에 연결

이 페이지에서는 Bitbucket Cloud 호스트를 Cloud Build와 연결하는 방법을 설명합니다.

시작하기 전에

  • Cloud Build, Secret Manager, Compute Engine API를 사용 설정합니다.

    API 사용 설정에 필요한 역할

    API를 사용 설정하려면 serviceusage.services.enable 권한이 포함된 서비스 사용량 관리자 IAM 역할(roles/serviceusage.serviceUsageAdmin)이 필요합니다. 역할 부여 방법 알아보기.

    API 사용 설정

  • 소스 코드가 Bitbucket Cloud 저장소에 있는지 확인합니다.
  • Bitbucket Cloud 소스 저장소에 Dockerfile 또는 Cloud Build 구성 파일이 있는지 확인합니다.
  • gcloud 명령어를 사용하도록 Google Cloud CLI를 설치합니다.

필수 IAM 권한

연결에 필요한 권한이 있는지 확인하려면 관리자에게 사용자 계정에 대해 Cloud Build 연결 관리자 (cloudbuild.connectionAdmin) IAM 역할을 부여해 달라고 요청하세요. 역할 부여에 대한 상세 설명은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.

관리자는 필요한 권한을 커스텀 역할이나 다른 사전 정의된 역할을 통해 부여할 수도 있습니다.

Bitbucket Cloud 액세스 토큰 만들기

Bitbucket Cloud에서 다음 2개의 액세스 토큰을 만듭니다.

  • 관리자 액세스 토큰 - 저장소 연결 및 연결 해제에 사용됩니다.
  • 읽기 액세스 토큰 - Cloud Build가 소스 코드에 액세스하도록 허용합니다.

이러한 토큰을 만들려면 다음 단계를 수행합니다.

  1. Bitbucket Cloud에 로그인합니다.

  2. Bitbucket Cloud 안내에 따라 저장소, 프로젝트, 작업공간에 연결된 액세스 토큰을 만듭니다.

    다음 권한을 부여합니다.

    • 관리자 액세스 토큰:

      • 저장소: 읽기관리자
      • pull 요청: 읽기
      • 웹훅: 읽기쓰기
    • 읽기 액세스 토큰:

      • 저장소: 읽기
  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_SECRET_NAME은 웹훅 보안 비밀에 지정하려는 이름입니다.

      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: 웹훅 보안 비밀의 이름입니다.
  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: 웹훅 보안 비밀의 이름입니다.

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_NAMEwebhook, repository, repository:admin, pullrequest 범위의 액세스 권한이 있는 토큰 이름입니다.
  • ADMIN_TOKEN_VALUE: ADMIN_TOKEN_NAME의 값입니다.
  • READ_TOKEN_NAME: repository:read 범위의 토큰 이름입니다.
  • READ_TOKEN_VALUE: READ_TOKEN_NAME의 값입니다.
  • WEBHOOK_SECRET_NAME: 웹훅 보안 비밀의 이름입니다.
  • WEBHOOK_SECRET_VALUE: WEBHOOK_SECRET_NAME의 값입니다.
  • REGION: 연결의 리전입니다.
  • CONNECTION_NAME: 연결의 이름입니다.
  • WORKSPACE_ID은(는) Bitbucket Cloud 저장소의 작업공간 ID입니다.

오래되었거나 만료된 Bitbucket Cloud 액세스 토큰 순환

Bitbucket Cloud 액세스 토큰이 만료되면 Cloud Build 호스트 연결이 Bitbucket Cloud 저장소에서 연결 해제됩니다. 따라서 다음과 같은 상황에서 오류가 표시됩니다.

  • Bitbucket Cloud 저장소 Cloud Build 연결을 연결하려고 하면 Failed to fetch repositories to link. Check that Cloud Build is still authorized to access data from the selected connection 메시지가 표시됩니다.

  • 트리거 페이지에서 실행을 클릭하면 트리거 실행 페이지가 열리고 Failed to list branches. You can still enter one manually 메시지가 표시됩니다.

연결의 오래되었거나 만료된 토큰을 순환하려면 다음을 수행합니다.

  1. 호스트 연결과 연결된 보안 비밀을 찾습니다.

    1. 다음 명령어를 실행합니다.

      gcloud builds connections describe CONNECTION_PATH --region=REGION
      

      각 항목의 의미는 다음과 같습니다.

      • CONNECTION_PATH는 Cloud Build의 Bitbucket Cloud 호스트 연결 경로이며 projects/PROJECT_ID/locations/REGION/connections/CONNECTION_NAME 형식입니다.
      • REGION은 연결의 리전입니다.
    2. 명령어의 출력에서 사용자 토큰 필드의 값을 찾습니다. readAuthorizerCredential.userTokenSecretVersionRead 토큰의 Secret Manager 이름을 표시하고 authorizerCredential.userTokenSecretVersionAdmin 토큰의 Secret Manager 이름을 표시합니다. 이러한 이름은 Secret Manager에 보안 비밀로 저장됩니다.

  2. Bitbucket Cloud에서 각 액세스 토큰을 순환합니다.

    1. Cloud Build 호스트 연결에 연결된 Bitbucket Cloud 저장소로 이동합니다.

    2. Bitbucket 문서의 안내에 따라 액세스 토큰을 순환합니다. 토큰을 순환하면 Bitbucket Cloud에서 새 사용자 인증 정보로 새 토큰을 만들고 이전 버전의 토큰을 무효화합니다. 순환된 토큰은 원래 토큰과 동일한 권한 및 범위를 갖습니다.

    3. 순환된 토큰의 ID를 복사합니다.

  3. 각 토큰의 새 보안 비밀 버전을 만듭니다.

    1. 콘솔에서 Secret Manager 페이지를 엽니다. Google Cloud

      Secret Manager 페이지 열기

    2. 순환한 각 토큰에 대해 1단계에서 식별한 보안 비밀 이름을 찾고 작업을 클릭한 후 새 버전 추가를 클릭합니다.

    3. 새 버전 추가 창에서 순환된 토큰의 ID를 입력한 후 새 버전 추가 를 클릭합니다.

자세한 내용은 Bitbucket Cloud 문서의 액세스 토큰Bitbucket의 보안 강화: 액세스 토큰의 만료 도입 을 참조하세요.

다음 단계