1. 簡介
在本實驗室中,我們將瞭解如何使用 VPC Service Controls 保護 BigQuery 資料移轉服務,同時將資料從 Cloud Storage 移轉至 BigQuery 資料集。接著保護 Cloud Storage,然後重複上述程序,將資料從 Cloud Storage 移轉至 BigQuery。Cloud Storage 的保護措施會導致 VPC Service Controls 違規,因此必須修正,才能順利移轉。最後,我們也會保護 BigQuery,然後嘗試在專案之間複製資料集,這也會導致違規,因此需要修正。
在本實驗室中,我們將分別使用輸入和輸出規則,瞭解如何修正輸入和輸出違規事項。我們也會使用存取層級修正 BigQuery 資料移轉的違規問題。本程式碼研究室的目標如下:
- 瞭解如何使用不同服務 (尤其是 Cloud Storage、BigQuery 和 BigQuery 資料移轉服務) 的輸入和輸出規則,修正輸入和輸出違規情形。
- 瞭解發生特定違規行為的原因。
2. 資源設定和需求
事前準備
在本程式碼研究室中,我們假設您已瞭解:
- 如何建立資料夾
- 如何在資料夾中建立專案,或將現有專案移入資料夾
- 如何建立範圍存取政策
- 如何透過 Google Cloud 控制台建立及設定服務周圍區域
- 如何從稽核記錄找出違規記錄
設定
我們的初始設定如下:
- Google Cloud 機構。
- 機構下的資料夾。在本程式碼研究室中,我們將其稱為
codelab-folder。 - 資料夾
codelab-folder中的兩個 Google Cloud 專案。在本程式碼研究室中,我們將專案稱為project-1和project-2。- 如果您尚未建立資料夾和專案,請在 Google Cloud 控制台中,於機構下建立資料夾,並建立兩個新專案。
- 必要權限:管理資料夾的 IAM 角色、管理專案的 IAM 角色、設定 VPC Service Controls 的必要 IAM 角色、管理 BigQuery 的 IAM 角色,以及管理 Cloud Storage 的 IAM 角色。
- 專案
project-1和project-2的帳單帳戶。
建立範圍政策和一般服務範圍
在本程式碼研究室中,我們會使用保護 project-2 的一般服務周邊。
- 建立範圍存取政策,範圍限定為資料夾
codelab-folder層級。在本程式碼研究室中,我們假設建立的存取權政策 ID 為987654321。 - 建立一般 perimeter (我們稱之為
perimeter-2),並新增專案project-2。
在範圍 perimeter-2 中,限制 BigQuery Data Transfer API。

建立 Cloud Storage bucket 和 BigQuery 資料集
在本程式碼研究室中,任何 CSV 檔案都適用,內容為何並不重要。主要限制與共置需求有關,強制規定如下:
- 如果 BigQuery 資料集位於多地區,則含有要轉移資料的 Cloud Storage bucket 必須位於相同多地區,或位於多地區內的位置
- 如果資料集位於某個區域,Cloud Storage 值區就必須位於相同區域。
因此,在本程式碼研究室中,我們會確保 Cloud Storage 值區和 BigQuery 資料集位於相同地區或多地區。
在專案 project-1 中建立新的 Cloud Storage bucket
如要建立新的 Cloud Storage bucket,請按照建立新 bucket 的步驟操作。
- 輸入符合值區命名規定的值區名稱。在本程式碼實驗室中,我們將 bucket 稱為
codelab-bqtransfer-bucket。 - 如要選擇資料的儲存位置和 bucket 位置,請選取「Location type」(位置類型) 和「Location」(位置),bucket 資料會永久儲存在這些位置。在本程式碼研究室中,我們將使用「us (multiple regions in United States)」(美國 (多個美國區域))。

建立 CSV 檔案
在您的本機或使用 Cloud Shell,我們可以透過 echo 指令,使用下列指令建立範例 CSV 檔案 codelab-test-file.csv:
echo "name,age" > codelab-test-file.csv; \
echo "Alice,10" >> codelab-test-file.csv; \
echo "Bob,20" >> codelab-test-file.csv; \
echo "Carol,30" >> codelab-test-file.csv; \
echo "Dan,40" >> codelab-test-file.csv; \
echo "Eve,50" >> codelab-test-file.csv; \
echo "Frank,60" >> codelab-test-file.csv; \
echo "Grace,70" >> codelab-test-file.csv; \
echo "Heidi,80" >> codelab-test-file.csv;
將 CSV 檔案上傳至 Cloud Storage bucket
建立 CSV 檔案後,請執行下列指令,將檔案物件上傳至建立的 bucket:
gcloud storage cp codelab-test-file.csv gs://codelab-bqtransfer-bucket

您可以列出 bucket 中的物件,或執行下列指令,確認檔案是否已上傳至建立的 bucket:
gcloud storage ls --recursive gs://codelab-bqtransfer-bucket/**
在 project-2 中建立 BigQuery 資料集和資料表
- 按照這些步驟,在專案
project-2中建立 BigQuery 資料集。 - 按照這些步驟,在建立的資料集
codelab_bqtransfer_dataset下方建立 BigQuery 資料表。- 在「來源」部分,從「建立資料表來源」清單中選取「空白資料表」。
- 在「Table」(資料表) 欄位中,輸入要建立的資料表名稱。在本程式碼研究室中,我們使用名稱:
codelab-bqtransfer-table。 - 確認「資料表類型」欄位已設為「原生資料表」
- 在「Schema」(結構定義) 區段中,輸入結構定義。按一下「以文字形式編輯」,然後輸入下列結構定義,即可輸入結構定義資訊,這項結構定義符合所建立 CSV 檔案的格式。
[{ "name": "name", "type": "STRING", "mode": "NULLABLE", "description": "The name" }, { "name": "age", "type": "INTEGER", "mode": "NULLABLE", "description": "The age" }]
費用
您需要在專案 project-2 和 project-1 中啟用帳單,才能使用 Cloud 資源/API。建議您關閉使用的資源,以免產生本程式碼研究室以外的帳單費用。
產生費用的資源是 BigQuery 和 Cloud Storage。您可以在 BigQuery 定價計算機和 Cloud Storage 計算機中查看預估費用。
3. 設定從 Cloud Storage 物件到 BigQuery 資料表的資料移轉作業
我們現在要嘗試建立資料移轉服務 (位於 project-2),從 Cloud Storage (位於 project-1) 移轉至 BigQuery (位於 project-2),同時讓 VPC Service Controls 保護 project-2 中的 BigQuery 資料移轉服務。如果只保護 BigQuery 資料移轉服務 (不保護 BigQuery 和 Cloud Storage),主體就只能建立及管理資料移轉作業 (例如手動啟動資料移轉作業)。
設定從 Cloud Storage 移轉資料
如要建立資料移轉作業,請按照下列步驟操作:
- 前往
project-2的 Google Cloud 控制台 BigQuery 頁面。 - 按一下「資料移轉」。

存取「資料移轉」頁面時調查違規事項
在 Google Cloud 控制台中,我們可以查看 VPC Service Controls 專屬 ID。使用相同 ID 篩選記錄,並找出違規詳細資料 (將 OBSERVED_VPCSC_DENIAL_UNIQUE_ID 替換為觀察到的拒絕 ID):
protoPayload.metadata.@type="type.googleapis.com/google.cloud.audit.VpcServiceControlAuditMetadata"
protoPayload.metadata.vpcServiceControlsUniqueId="OBSERVED_VPCSC_DENIAL_UNIQUE_ID"
觀察到的違規事項是 NO_MATCHING_ACCESS_LEVEL,也就是輸入違規事項,詳細資料如下:
ingressViolations: [
0: {
servicePerimeter: "accessPolicies/987654321/servicePerimeters/perimeter-2"
targetResource: "projects/[PROJECT2_NUMBER]"
}]
violationReason: "NO_MATCHING_ACCESS_LEVEL"
callerIp: "USER_PUBLIC_IP_ADDRESS"
resource: {
labels: {
method: "google.cloud.bigquery.datatransfer.v1.DataTransferService.ListTransferConfigs"
project_id: "project-2"
service: "bigquerydatatransfer.googleapis.com"
}
type: "audited_resource"
}
存取「資料移轉」頁面時,系統會嘗試列出所有已設定的資料移轉,因此會違反 ListTransferConfigs 方法。
修正 bigquerydatatransfer.googleapis.com 服務的違規事項
您可以透過存取層級或輸入規則修正輸入違規事項。在本程式碼研究室中,我們將使用設定為拒絕使用者身分的輸入規則,允許存取 bigquerydatatransfer.googleapis.com 服務和所有方法。

設定輸入規則後,應該就能順利存取「資料移轉」頁面。
繼續設定從 Cloud Storage 移轉資料
在先前的步驟中,點選「資料轉移」後,您會進入「資料轉移」頁面,請繼續執行下列步驟:
- 按一下「+ 建立移轉作業」。
- 在「Source type」(來源類型) 部分,「Source」(來源) 請選取「Google Cloud Storage」。
- 在「Transfer config name」(轉移設定名稱) 部分,「Display name」(顯示名稱) 請輸入移轉作業的名稱,例如
Codelab Transfer。 - 在「Schedule options」(排程選項) 專區:
- 選取重複頻率,例如 15 分鐘。
- 請務必選取「立即開始」,否則資料移轉作業只會在設定的「重複頻率」後開始
- 在「Destination settings」(目的地設定) 部分,針對「Destination dataset」(目的地資料集),選擇您建立來儲存資料的資料集:
codelab_bqtransfer_dataset - 在「Data source details」(資料來源詳細資料) 區段
- 在「Destination table」(目的地資料表) 中輸入目的地資料表的名稱。目的地資料表的名稱必須符合資料表命名規則,在本程式碼研究室中,我們會使用先前建立的資料表:
codelab-bqtransfer-table - 在「Cloud Storage URI」輸入 Cloud Storage URI,在本程式碼研究室中,我們會使用建立的 bucket 和檔案:
codelab-bqtransfer-bucket/codelab-test-file.csv - 針對「Write preference」(寫入偏好設定),請保留
APPEND(或選擇MIRROR)。 - 請勿選取在轉移後刪除檔案 (因為我們會重複使用相同檔案多次,不過,你可以使用多個檔案,並在轉移後刪除來源檔案)
- 「檔案格式」請選取「CSV」
- 在「Transfer Options」(移轉選項) 的「CSV」下方,輸入半形逗號 (「,」) 做為「Field delimiter」(欄位分隔符號)。
- 在「Destination table」(目的地資料表) 中輸入目的地資料表的名稱。目的地資料表的名稱必須符合資料表命名規則,在本程式碼研究室中,我們會使用先前建立的資料表:
- 在「Service Account」(服務帳戶) 選單,選取與 Google Cloud 雲端專案相關聯的服務帳戶
- 所選服務帳戶必須具備儲存空間 bucket 所在專案的 Cloud Storage 必要權限;在本程式碼研究室中,該專案為
project-1。 - 在本程式碼研究室中,我們將使用在
project-2中建立的服務帳戶做為codelab-sa@project-2.iam.gserviceaccount.com。
- 所選服務帳戶必須具備儲存空間 bucket 所在專案的 Cloud Storage 必要權限;在本程式碼研究室中,該專案為
- 按一下 [儲存]。
由於我們選取「立即開始」做為排程選項,因此選取「儲存」後,系統就會立即開始第一次轉移。
確認資料轉移服務狀態
如要驗證已設定的資料移轉狀態,請按照下列步驟操作:
- 前往 Google Cloud 控制台的 BigQuery 頁面
- 按一下「資料移轉」。
- 畫面會顯示已設定的轉移作業清單

按一下「顯示名稱」下方的 Codelab Transfer,系統就會顯示目前為止執行的所有執行清單。

手動觸發和排定的資料移轉作業都應順利完成,且不會違反 VPC Service Controls 規定。請注意,只有手動觸發的轉移作業,才需要輸入規則,允許存取發起轉移作業的主體。
4. 手動觸發資料轉移的 IP 位址限制
目前設定的輸入規則允許設定的身分從任何 IP 位址手動觸發資料移轉。
使用存取層級時,VPC Service Controls 可根據特定 API 要求屬性限制允許的存取權,包括:
- IP 子網路:檢查要求是否來自特定 IP 位址。
- 區域:檢查要求是否來自特定區域,這取決於 IP 位址的地理位置。
- 主體:檢查要求是否來自特定帳戶。
- 裝置政策:檢查要求是否來自符合特定需求的裝置。
如要連同已設定的輸入規則一併強制驗證這些屬性,我們必須建立允許所需屬性的存取層級,然後將建立的存取層級新增為輸入規則中的來源。
這張圖說明兩個主體 (
user@example.com 和 user2@example.com) 在三種情境下發起的存取要求,並展示 VPC Service Controls 如何將來源 (輸入存取層級) 和身分屬性評估為 AND 條件,也就是兩者都必須相符。
- 使用者 user@example.com 嘗試從存取層級允許的 IP 位址存取時,系統會允許存取,因為他們的 IP 位址和使用者帳戶符合輸入規則中的設定。
- 即使帳戶已在連入規則中設定,如果 IP 位址不符合允許的 IP 位址,使用者 user@example.com 仍會遭到封鎖。
- 使用者 user2@example.com 嘗試從允許的 IP 位址存取,但由於其帳戶不符合連入規則,因此遭到封鎖。
建立存取層級
如要建立根據 IP 位址限制存取權的存取層級,請按照下列步驟操作:
- 在 Google Cloud 控制台中開啟「Access Context Manager」頁面。
- 如果系統顯示提示,請選取「
codelab-folder」資料夾。
- 如果系統顯示提示,請選取「
- 按一下「Access Context Manager」頁面最上方的「建立存取層級」。
- 在「New Access Level」(建立新的存取層級) 窗格中,為新的存取層級命名標題。在本程式碼研究室中,我們將其稱為
project_2_al。 - 在「條件」部分,按一下「IP 子網路」前面的「+」。
- 在「IP Subnetworks」(IP 子網路) 方塊中,選取「Public IP」(公開 IP)
- 您也可以選取使用私人 IP,在存取層級中使用內部 IP 位址。不過,在本程式碼研究室中,我們使用的是公開 IP。
- 輸入一或多個 IPv4 或 IPv6 範圍 (CIDR 區塊格式)。
在輸入規則中新增存取層級
在輸入規則中,存取層級會參照 sources 欄位,這是輸入規則參考資料中記載的必填欄位。如要允許資源輸入流量,VPC Service Controls 會將 sources 和 identityType 屬性評估為 AND 條件。這項輸入規則會使用手動觸發資料移轉作業的主體身分,而非資料移轉設定中指定的服務帳戶。

重新執行轉移作業,並設定 IP 位址限制存取權
如要評估套用設定的成效,請使用下列情境再次觸發轉移:
- 使用輸入規則參照的存取層級中允許的 IP 位址範圍。
- 使用設定不允許的 IP 位址
從允許的 IP 位址存取時應會成功,從不允許的 IP 位址存取時則會失敗,並導致 VPC Service Controls 違規。
如要使用其他 IP 位址進行測試,簡單的方法是允許使用 Google Cloud 控制台時指派的 IP 位址,然後使用 Cloud Shell 進行測試。
在 Cloud Shell 中執行下列指令,手動觸發轉移作業,並取代 RUN_TIME 和 RESOURCE_NAME:
bq mk \
--transfer_run \
--run_time='RUN_TIME' \
RESOURCE_NAME
舉例來說,下列指令範例會立即為專案 1234567890 中的移轉作業 12345678-90ab-cdef-ghij-klmnopqrstuv 設定執行作業。
NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ");
bq mk \
--transfer_run \
--run_time=$NOW \
projects/1234567890/locations/us/transferConfigs/12345678-90ab-cdef-ghij-klmnopqrstuv
如預期,觀察到的輸出內容顯示 VPC Service Controls 違規事項,因為系統不允許使用該 IP 位址。

觀察到的違規事項與 DataTransferService.StartManualTransferRuns 方法有關。
ingressViolations: [
0: {
servicePerimeter: "accessPolicies/987654321/servicePerimeters/perimeter-2"
targetResource: "projects/[PROJECT2_NUMBER]"
targetResourcePermissions: [0: "vpcsc.permissions.unavailable"]
}]
violationReason: "RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER"
resource: {
labels: {
method: "google.cloud.bigquery.datatransfer.v1.DataTransferService.StartManualTransferRuns"
project_id: "project-2"
service: "bigquerydatatransfer.googleapis.com"
}
type: "audited_resource"
}
severity: "ERROR"
5. 開始資料移轉,同時保護 Cloud Storage 服務
由於我們要從 Cloud Storage 移轉至 BigQuery,請在受 VPC Service Controls 保護的服務中新增 Cloud Storage,並確認移轉作業是否仍能順利完成。
在 perimeter-2 設定中,將 Cloud Storage API 和 BigQuery Data Transfer API 新增為受限服務。

保護 Cloud Storage API 後,請等待下一次排定的資料移轉作業,或按照下列步驟手動觸發移轉作業:
- 前往 Google Cloud 控制台的 BigQuery 頁面。
- 按一下「資料移轉」。
- 從清單中選取轉移作業:在本程式碼研究室中,我們使用「Codelab Transfer」轉移作業
- 按一下「立即執行移轉作業」
- 按一下「確定」。
系統會啟動另一項轉移作業。你可能需要重新整理頁面才能看到。這次移轉作業會因 VPC Service Controls 違規而失敗。

調查 Cloud Storage VPC Service Controls 違規事項
使用 vpcServiceControlsUniqueIdentifier 篩選稽核記錄,如轉移作業「摘要」所示。
觀察到的違規事項是RESOURCES_NOT_IN_SAME_SERVICE_PERIMETER輸出違規,詳細資料如下:
- 主體是資料移轉服務中設定的服務帳戶 (無論是手動觸發或執行排定的資料移轉作業,遭拒的主體都會相同)。
- 受影響的服務為 Cloud Storage
- 要求的來源是設定資料移轉服務的專案:
project-2 - 目標專案是 Cloud Storage 物件所在的專案:
project-1
principalEmail: "codelab-sa@project-2.iam.gserviceaccount.com"
egressViolations: [
0: {
servicePerimeter: "accessPolicies/987654321/servicePerimeters/perimeter-2"
source: "projects/[PROJECT2_NUMBER]"
sourceType: "Resource"
targetResource: "projects/[PROJECT1_NUMBER]"
targetResourcePermissions: [0: "storage.objects.get"]
}]
labels: {
method: "google.storage.objects.get"
project_id: "project-2"
service: "storage.googleapis.com"
}
修正 Cloud Storage 輸出違規問題
如要修正輸出違規問題,我們必須使用輸出規則,允許來自遭拒服務帳戶的流量前往含有 Cloud Storage 物件的專案。

修改服務安全防護範圍 perimeter-2 後,請重複上述程序,再次觸發轉移作業。轉移作業不會顯示錯誤。

6. 將 BigQuery 資料集從 project-2 複製到 project-1
確認我們可以將資料從 project-1 中的 Cloud Storage 值區移轉至 project-2 中的 BigQuery 資料集後,請將 BigQuery 資料集從 project-2 複製到 project-1;此時 BigQuery API 會受到 VPC Service Controls 保護。
如要建立及複製資料集,我們將使用 bq mk 指令,該指令會使用 bq 工具。
在 project-1 中建立目的地資料集
複製資料集前,請先建立目的地資料集。如要建立目的地資料集,我們可以執行下列指令,在專案 project-1 中建立名為 copied_dataset 的資料集,並將 us 設為位置。
bq mk \
--dataset \
--location=us \
project-1:copied_dataset
使用 VPC Service Controls 保護 project-2 中的 BigQuery 服務
修改邊界的設定 perimeter-2,並將 BigQuery API 新增為受保護的服務,以及 BigQuery 資料移轉和 Cloud Storage 服務。

啟動資料集副本
如要複製資料集,請執行下列 bq mk 指令,將專案 project-2 中的資料集 codelab_bqtransfer_dataset 複製到 project-1 中的資料集 copied_dataset,並覆寫資料集內容 (如有)。
bq mk \
--transfer_config \
--project_id=project-1 \
--target_dataset=copied_dataset \
--data_source=cross_region_copy \
--display_name='Dataset from project-2 to project-1' \
--params='{
"source_dataset_id":"codelab_bqtransfer_dataset",
"source_project_id":"project-2",
"overwrite_destination_table":"true"
}'
指令會順利執行,同時系統會成功建立轉移設定,開始複製資料集。複製資料集本身會失敗,並出現 VPC Service Controls 違規事項。
如要查看對應的 VPC Service Controls 違規事項詳細資料,請使用下列記錄查詢,檢查 project-2 (來源資料集專案) 中的記錄。記錄查詢會根據 BigQuery 服務和要複製的資料集資源名稱 (codelab_bqtransfer_dataset) 篩選記錄。
resource.labels.service="bigquery.googleapis.com"
protoPayload.metadata.resourceNames:"datasets/codelab_bqtransfer_dataset"
觀察到的 VPC Service Controls 違規行為是從 project-2 到 project-1 的輸出違規行為。
egressViolations: [
0: {
servicePerimeter: "accessPolicies/987654321/servicePerimeters/perimeter-2"
source: "projects/[PROJECT-2-NUMBER]"
sourceType: "Resource"
targetResource: "projects/[PROJECT-1-NUMBER]"
targetResourcePermissions: [
0: "bigquery.transfers.update"
1: "bigquery.transfers.get"
2: "bigquery.jobs.create"
]
}
]
method: "bigquery.tables.getData"
service: "bigquery.googleapis.com"
修正所有 BigQuery 違規事項,然後再次開始複製資料集
如要修正輸出違規事項,請建立允許遭拒主體的輸出規則。遭拒主體是執行 mk 指令的主體。

設定輸出規則後,在服務範圍 perimeter-2 中執行相同指令,即可複製資料集。這次應該就能成功複製資料集,不會違反 VPC Service Controls。
7. 清除
雖然服務未使用時,使用 VPC Service Controls 無須另外付費,但建議您清理本實驗室中使用的設定。您也可以刪除 VM 執行個體和/或 Cloud 專案,以免產生費用。刪除雲端專案後,系統就會停止對該專案使用的所有資源收取費用。
- 如要刪除 Cloud Storage bucket,請完成下列步驟:
- 如要刪除 BigQuery 資料集,請完成下列步驟:
- 前往 Google Cloud 控制台的「BigQuery」頁面。
- 在「Explorer」窗格中展開專案,然後選取資料集。
- 展開三點選單,然後點按「刪除」。
- 在「Delete dataset」(刪除資料集) 對話方塊中,在欄位輸入
delete,然後按一下「Delete」(刪除)。
- 如要刪除服務範圍,請完成下列步驟:
- 在 Google Cloud 控制台中,依序選取 Security,然後選取 VPC Service Controls,存取權政策的範圍層級為資料夾層級。
- 在「VPC Service Controls」頁面中,找出要刪除的範圍,然後在對應的資料表列中選取
Delete Icon。
- 如要刪除存取層級,請完成下列步驟:
- 如要關閉專案,請完成下列步驟:
8. 恭喜!
在本程式碼研究室中,您建立了 VPC Service Controls perimeter、強制執行 perimeter,並排解 perimeter 問題。
瞭解詳情
您也可以探索下列情境:
- 在另一個也保護 BigQuery、BigQuery 資料移轉服務和 Cloud Storage 的安全防護範圍中新增
project-1。 - 從其他支援的來源執行 BigQuery 資料移轉作業。
- 根據其他屬性 (例如位置或裝置政策) 限制使用者存取權。
授權
這項內容採用的授權為 創用 CC 姓名標示 2.0 通用授權。

