連線至 Blob 儲存體

身為 BigQuery 管理員,您可以建立連線,讓資料分析師存取儲存在 Azure Blob 儲存體中的資料。

BigQuery Omni 會透過連線存取 Blob 儲存體資料。BigQuery Omni 支援 Azure 工作負載身分識別資訊聯合。BigQuery Omni 支援 Azure 工作負載身分聯盟,可讓您將 Azure 應用程式在租用戶中的存取權授予 Google 服務帳戶。您或 Google 都不需要管理應用程式用戶端密鑰。

建立 BigQuery Azure 連線後,您可以查詢 Blob 儲存體資料,或將查詢結果匯出至 Blob 儲存體

事前準備

必要的角色

配額

如要進一步瞭解配額,請參閱 BigQuery Connection API

建立 Azure 連線

如要建立 Azure 連線,請按照下列步驟操作:

  1. 在 Azure 用戶群中建立應用程式
  2. 建立 BigQuery Azure 連線
  3. 新增聯盟憑證
  4. 為 BigQuery Azure AD 應用程式指派角色

如要進一步瞭解如何使用聯盟身分憑證存取 Azure 中的資料,請參閱「Workload Identity 聯盟」。

在 Azure 用戶群中建立應用程式

如要在 Azure 用戶群中建立應用程式,請按照下列步驟操作:

Azure 入口網站

  1. 在 Azure 入口網站中前往「App registrations」,然後按一下「New registration」

  2. 在「名稱」中,輸入應用程式名稱。

  3. 針對「支援的帳戶類型」,選取「僅限這個機構組織目錄中的帳戶」

  4. 如要註冊新應用程式,請按一下「Register」

  5. 記下應用程式 (用戶端) ID,您需要在建立連線時提供這個 ID。

    用於建立應用程式的 Azure 入口網站

Terraform

在 Terraform 設定檔中新增下列內容:

  data "azuread_client_config" "current" {}

  resource "azuread_application" "example" {
    display_name = "bigquery-omni-connector"
    owners       = [data.azuread_client_config.current.object_id]
  }

  resource "azuread_service_principal" "example" {
    client_id                    = azuread_application.example.client_id
    app_role_assignment_required = false
    owners                       = [data.azuread_client_config.current.object_id]
  }

詳情請參閱如何在 Azure 中註冊應用程式

建立連線

主控台

  1. 前往 Google Cloud 控制台的「BigQuery」頁面。

    前往 BigQuery

  2. 在「Explorer」窗格中,按一下 「Add data」

    「Add data」對話方塊隨即開啟。

  3. 在「Filter By」窗格中的「Data Source Type」部分,選取「Databases」

    或者,您也可以在「Search for data sources」欄位中輸入 Azure

  4. 在「精選資料來源」部分,按一下「Azure Blob 儲存體」

  5. 按一下「Azure Blob Storage Omni: BigQuery Federation」解決方案資訊卡。

  6. 在「建立表格」對話方塊的「連線 ID」欄位中,選取「建立新的 ABS 連線」

  7. 在「外部資料來源」窗格中,輸入以下資訊:

    • 在「連線類型」中,選取「Azure 中的 BigLake (透過 BigQuery Omni)」
    • 在「Connection ID」(連線 ID) 專區中輸入連線資源的 ID。您可以使用英文字母、數字、破折號和底線。
    • 選取要建立連線的位置。
    • 選用:在「Friendly name」(好記名稱) 中輸入使用者容易記得的連線名稱,例如 My connection resource。好記名稱可以是任何值,只要您日後需要修改時可以輕鬆識別連線資源即可。
    • 選用:在「Description」(說明) 中輸入連線資源的說明。
    • 針對「Azure 租用戶 ID」,請輸入 Azure 租用戶 ID,也稱為目錄 (租用戶) ID。
    • 啟用「使用聯合身分」核取方塊,然後輸入 Azure 聯盟應用程式 (用戶端) ID。

      如要瞭解如何取得 Azure ID,請參閱「在 Azure 用戶群中建立應用程式」。

  8. 點選「建立連線」

  9. 按一下「前往連線」

  10. 在「連線資訊」部分,記下「BigQuery Google 身分」的值,也就是服務帳戶 ID。這個 ID 適用於您授權存取應用程式的Google Cloud 服務帳戶

Terraform

  resource "google_bigquery_connection" "connection" {
    connection_id = "omni-azure-connection"
    location      = "azure-eastus2"
    description   = "created by terraform"

    azure {
      customer_tenant_id              = "TENANT_ID"
      federated_application_client_id = azuread_application.example.client_id
    }
  }

TENANT_ID 替換為包含 Blob 儲存體帳戶的 Azure 目錄的租用戶 ID。

bq

使用 bq mk 指令。如要以 JSON 格式取得輸出內容,請使用 --format=json 參數。

bq mk --connection --connection_type='Azure' \
  --tenant_id=TENANT_ID \
  --location=AZURE_LOCATION \
  --federated_azure=true \
  --federated_app_client_id=APP_ID \
  CONNECTION_ID

更改下列內容:

  • TENANT_ID:包含 Azure 儲存體帳戶的 Azure 目錄租用戶 ID。
  • AZURE_LOCATION:Azure 儲存體資料所在的 Azure 區域。BigQuery Omni 支援 azure-eastus2 區域。
  • APP_ID:Azure 應用程式 (用戶端) ID。如要瞭解如何取得這個 ID,請參閱「在 Azure 用戶群中建立應用程式」。
  • CONNECTION_ID:連線名稱。

輸出結果會與下列內容相似:

Connection CONNECTION_ID successfully created
Please add the following identity to your Azure application APP_ID
Identity: SUBJECT_ID

輸出內容包含下列值:

  • APP_ID:您建立的應用程式 ID。

  • SUBJECT_ID:使用者授權存取其應用程式的 Google Cloud服務帳戶 ID。在 Azure 中建立聯盟憑證時,必須使用這個值。

請記下 APP_IDSUBJECT_ID 值,以便在後續步驟中使用。

接著,為應用程式新增聯盟憑證。

新增聯盟憑證

如要建立聯合身分驗證,請按照下列步驟操作:

Azure 入口網站

  1. 在 Azure 入口網站中前往「App registrations」,然後按一下您的應用程式。

  2. 依序選取「憑證與密鑰」>「聯合式憑證」>「新增憑證」。接著,請按照下列步驟操作:

    1. 在「聯合身分驗證情境」清單中,選取「其他發證機構」

    2. 在「Issuer」中輸入 https://accounts.google.com

    3. 在「主體 ID」中,輸入您建立連線時取得的 Google Cloud 服務帳戶的 BigQuery Google 身分

    4. 在「Name」 中輸入憑證名稱。

    5. 按一下「新增」。

Terraform

在 Terraform 設定檔中新增下列內容:

  resource "azuread_application_federated_identity_credential" "example" {
    application_id = azuread_application.example.id
    display_name   = "omni-federated-credential"
    description    = "BigQuery Omni federated credential"
    audiences      = ["api://AzureADTokenExchange"]
    issuer         = "https://accounts.google.com"
    subject        = google_bigquery_connection.connection.azure[0].identity
  }

詳情請參閱「設定應用程式以信任外部身分識別資訊提供者」。

將角色指派給 BigQuery 的 Azure 應用程式

如要將角色指派給 BigQuery 的 Azure 應用程式,請使用 Azure 入口網站、Azure PowerShell 或 Microsoft Management REST API:

Azure 入口網站

您可以以具有 Microsoft.Authorization/roleAssignments/write 權限的使用者身分登入 Azure 入口網站,在該網站中執行角色指派作業。角色指派可讓 BigQuery Azure 連線依角色政策指定的內容存取 Azure Storage 資料。

如要使用 Azure 入口新增角色指派,請按照下列步驟操作:

  1. 在 Azure 儲存體帳戶中,在搜尋列中輸入 IAM

  2. 按一下「存取權控管 (IAM)」

  3. 按一下「新增」,然後選取「新增角色指派」

  4. 如要提供唯讀存取權,請選取「Storage Blob Data Reader」角色。如要提供讀寫存取權,請選取「儲存體 Blob 資料貢獻者」角色。

  5. 將「指派存取權給」設為「使用者、群組或服務主體」

  6. 按一下「選取成員」

  7. 在「選取」欄位中,輸入您在建立 Azure 用戶群中的應用程式時所提供的 Azure 應用程式名稱。

  8. 按一下 [儲存]

詳情請參閱「使用 Azure 入口網站指派 Azure 角色」一文。

Terraform

在 Terraform 設定檔中新增下列內容:

  resource "azurerm_role_assignment" "data_role" {
    scope                = data.azurerm_storage_account.example.id
    # Read permission for Omni on the storage account
    role_definition_name = "Storage Blob Data Reader"
    principal_id         = azuread_service_principal.example.id
  }

Azure PowerShell

如要在資源範圍中為服務主體新增角色指派,您可以使用 New-AzRoleAssignment 指令

  New-AzRoleAssignment`
   -SignInName APP_NAME`
   -RoleDefinitionName ROLE_NAME`
   -ResourceName RESOURCE_NAME`
   -ResourceType RESOURCE_TYPE`
   -ParentResource PARENT_RESOURCE`
   -ResourceGroupName RESOURCE_GROUP_NAME

更改下列內容:

  • APP_NAME:應用程式名稱。
  • ROLE_NAME:您要指派的角色名稱。
  • RESOURCE_NAME:資源名稱。
  • RESOURCE_TYPE:資源類型。
  • PARENT_RESOURCE:父項資源。
  • RESOURCE_GROUP_NAME:資源群組名稱。

如要進一步瞭解如何使用 Azure PowerShell 新增服務主體,請參閱「使用 Azure PowerShell 指派 Azure 角色」一文。

Azure CLI

如要在資源範圍中為服務主體新增角色指派,您可以使用 Azure 指令列工具。您必須具備儲存空間帳戶的 Microsoft.Authorization/roleAssignments/write 權限,才能授予角色。

如要將角色 (例如 儲存體 Blob 資料讀取者 角色) 指派給服務主體,請執行 az role assignment create 指令

  az role assignment create --role "Storage Blob Data Reader" \
    --assignee-object-id ${SP_ID} \
    --assignee-principal-type ServicePrincipal \
    --scope   subscriptions/SUBSCRIPTION_ID/resourcegroups/RESOURCE_GROUP_NAME/providers/Microsoft.Storage/storageAccounts/STORAGE_ACCOUNT_NAME

更改下列內容:

  • SP_ID:服務主體 ID。這個服務管理員是用於您建立的應用程式。如要取得聯合連線的服務主體,請參閱「服務主體物件」。
  • STORAGE_ACCOUNT_NAME:儲存空間帳戶名稱。
  • RESOURCE_GROUP_NAME:資源群組名稱。
  • SUBSCRIPTION_ID:訂閱項目 ID。

詳情請參閱「使用 Azure CLI 指派 Azure 角色」。

Microsoft REST API

如要為服務主體新增角色指派,您可以向 Microsoft Management 傳送 HTTP 要求。

如要呼叫 Microsoft Graph REST API,請擷取應用程式的 OAuth 權杖。詳情請參閱「在沒有使用者的情況下取得存取權」。呼叫 Microsoft Graph REST API 的應用程式必須具備 Application.ReadWrite.All 應用程式權限。

如要產生 OAuth 權杖,請執行下列指令:

  export TOKEN=$(curl -X POST \
    https://login.microsoftonline.com/TENANT_ID/oauth2/token \
    -H 'cache-control: no-cache' \
    -H 'content-type: application/x-www-form-urlencoded' \
    --data-urlencode "grant_type=client_credentials" \
    --data-urlencode "resource=https://graph.microsoft.com/" \
    --data-urlencode "client_id=CLIENT_ID" \
    --data-urlencode "client_secret=CLIENT_SECRET" \
  | jq --raw-output '.access_token')

更改下列內容:

  • TENANT_ID:與包含 Azure 儲存體帳戶的 Azure 目錄 ID 相符的租用戶 ID。
  • CLIENT_ID:Azure 用戶端 ID。
  • CLIENT_SECRET:Azure 用戶端密碼。

取得要指派給服務主體的 Azure 內建角色 ID。

以下是一些常見的角色:

如要為服務主體指派角色,請對 Azure Resource Management REST API 呼叫 Microsoft Graph REST API:

  export ROLE_ASSIGNMENT_ID=$(uuidgen)
  curl -X PUT \
'https://management.azure.com/subscriptions/SUBSCRIPTION_ID/resourcegroups/RESOURCE_GROUP_NAME/providers/Microsoft.Storage/storageAccounts/STORAGE_ACCOUNT_NAME/providers/Microsoft.Authorization/roleAssignments/ROLE_ASSIGNMENT_ID?api-version=2018-01-01-preview' \
    -H "authorization: Bearer ${TOKEN?}" \
    -H 'cache-control: no-cache' \
    -H 'content-type: application/json' \
    -d '{
        "properties": {
            "roleDefinitionId": "subscriptions/SUBSCRIPTION_ID/resourcegroups/RESOURCE_GROUP_NAME/providers/Microsoft.Storage/storageAccounts/STORAGE_ACCOUNT_NAME/providers/Microsoft.Authorization/roleDefinitions/ROLE_ID",
            "principalId": "SP_ID"
        }
    }'

更改下列內容:

  • ROLE_ASSIGNMENT_ID:角色 ID。
  • SP_ID:服務主體 ID。這個服務管理員是用於您建立的應用程式。如要取得聯合連線的服務主體,請參閱「服務主體物件」。
  • SUBSCRIPTION_ID:訂閱項目 ID。
  • RESOURCE_GROUP_NAME:資源群組名稱。
  • STORAGE_ACCOUNT_NAME:儲存空間帳戶名稱。
  • SUBSCRIPTION_ID:訂閱項目 ID。

連線現在已可使用。不過,Azure 中的角色指派可能會延遲傳播。如果您因為權限問題無法使用連線,請過一段時間後再試一次。

與使用者分享連線

您可以授予下列角色,讓使用者查詢資料及管理連線:

  • roles/bigquery.connectionUser:可讓使用者使用連線連結外部資料來源,並對這些資料來源執行查詢。

  • roles/bigquery.connectionAdmin:讓使用者管理連線。

如要進一步瞭解 BigQuery 中的 IAM 角色和權限,請參閱「預先定義的角色與權限」一文。

選取下列選項之一:

主控台

  1. 前往「BigQuery」頁面

    前往 BigQuery

    連線會列在專案中,位於名為「External connections」的群組中。

  2. 在「Explorer」窗格中,依序點選「專案名稱」>「外部連線」>「連線」

  3. 在「Details」窗格中,按一下「Share」,即可分享連線。接著,按照下列步驟操作:

    1. 在「Connection permissions」對話方塊中,新增或編輯主體,與其他主體共用連線。

    2. 按一下 [儲存]

bq

您無法透過 bq 指令列工具共用連線。如要分享連線,請使用 Google Cloud 主控台或 BigQuery Connections API 方法。

API

請使用 BigQuery Connections REST API 參考資料部分的 projects.locations.connections.setIAM 方法,並提供 policy 資源的例項。

Java

在嘗試這個範例之前,請先按照 BigQuery 快速入門:使用用戶端程式庫中的 Java 設定說明進行操作。詳情請參閱 BigQuery Java API 參考說明文件

如要向 BigQuery 進行驗證,請設定應用程式預設憑證。詳情請參閱「設定用戶端程式庫的驗證機制」。

import com.google.api.resourcenames.ResourceName;
import com.google.cloud.bigquery.connection.v1.ConnectionName;
import com.google.cloud.bigqueryconnection.v1.ConnectionServiceClient;
import com.google.iam.v1.Binding;
import com.google.iam.v1.Policy;
import com.google.iam.v1.SetIamPolicyRequest;
import java.io.IOException;

// Sample to share connections
public class ShareConnection {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "MY_PROJECT_ID";
    String location = "MY_LOCATION";
    String connectionId = "MY_CONNECTION_ID";
    shareConnection(projectId, location, connectionId);
  }

  static void shareConnection(String projectId, String location, String connectionId)
      throws IOException {
    try (ConnectionServiceClient client = ConnectionServiceClient.create()) {
      ResourceName resource = ConnectionName.of(projectId, location, connectionId);
      Binding binding =
          Binding.newBuilder()
              .addMembers("group:example-analyst-group@google.com")
              .setRole("roles/bigquery.connectionUser")
              .build();
      Policy policy = Policy.newBuilder().addBindings(binding).build();
      SetIamPolicyRequest request =
          SetIamPolicyRequest.newBuilder()
              .setResource(resource.toString())
              .setPolicy(policy)
              .build();
      client.setIamPolicy(request);
      System.out.println("Connection shared successfully");
    }
  }
}

後續步驟