連結至 Amazon S3

BigQuery 管理員可以建立連線,讓資料分析師存取儲存在 Amazon Simple Storage Service (Amazon S3) 值區中的資料。

BigQuery Omni 會透過連線存取 Amazon S3 資料。每個連線都有專屬的 Amazon Web Services (AWS) 身分與存取權管理 (IAM) 使用者。您可以透過 AWS IAM 角色授予使用者權限。AWS IAM 角色中的政策會決定 BigQuery 可存取哪些資料 (以每個連線為單位)。

您必須建立連線,才能查詢 Amazon S3 資料,以及將查詢結果從 BigQuery 匯出至 Amazon S3 值區

事前準備

請確認您已建立下列資源:

必要的角色

如要取得建立連結以存取 Amazon S3 資料所需的權限,請要求管理員授予您專案的「BigQuery 連線管理員」 (roles/bigquery.connectionAdmin) IAM 角色。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。

您或許還可透過自訂角色或其他預先定義的角色取得必要權限。

為 BigQuery 建立 AWS IAM 政策

請務必遵循 Amazon S3 的安全性最佳做法。建議您採取下列做法:

  • 設定 AWS 政策,禁止透過 HTTP 存取 Amazon S3 值區。
  • 設定 AWS 政策,禁止公開存取 Amazon S3 儲存空間。
  • 使用 Amazon S3 伺服器端加密。
  • 將授予 Google 帳戶的權限限制在最低必要權限。
  • 設定 CloudTrails 並啟用 Amazon S3 資料事件。

如要建立 AWS IAM 政策,請使用 AWS 主控台或 Terraform:

AWS 管理主控台

  1. 前往 AWS IAM 主控台。 確認您目前使用的帳戶擁有要存取的 Amazon S3 值區。

    前往 AWS IAM 主控台

  2. 選取「政策」>「建立政策」 (在新分頁中開啟)。

  3. 按一下「JSON」JSON,然後將下列內容貼到編輯器中:

    {
     "Version": "2012-10-17",
     "Statement": [
        {
         "Effect": "Allow",
         "Action": [
           "s3:ListBucket"
         ],
         "Resource": [
           "arn:aws:s3:::BUCKET_NAME"
          ]
        },
       {
         "Effect": "Allow",
         "Action": [
           "s3:GetObject",
           EXPORT_PERM
         ],
         "Resource": [
           "arn:aws:s3:::BUCKET_NAME",
            "arn:aws:s3:::BUCKET_NAME/*"
          ]
        }
     ]
    }

    更改下列內容:

    • BUCKET_NAME:您希望 BigQuery 存取的 Amazon S3 儲存空間。
    • EXPORT_PERM (選用):額外權限,如果您想將資料匯出至 Amazon S3 值區。以「"s3:PutObject"」取代
      • 如要分開控管匯出存取權,建議您使用另一個 AWS IAM 角色建立其他連線,並授予該角色僅限寫入的存取權。如要更精細地控管存取權,您也可以限制角色只能存取值區的特定路徑。
  4. 在「Name」(名稱) 欄位中輸入政策名稱,例如 bq_omni_read_only

  5. 按一下「建立政策」

系統會建立政策,並以以下格式提供 Amazon Resource Name (ARN):

arn:aws:iam::AWS_ACCOUNT_ID:policy/POLICY_NAME

更改下列內容:

  • AWS_ACCOUNT_ID:連線的 AWS IAM 使用者 ID 號碼。
  • POLICY_NAME:您選擇的政策名稱。

AWS CLI

如要建立 AWS IAM 政策,請使用 aws iam create-policy 指令

  aws iam create-policy \
   --policy-name POLICY_NAME \
   --policy-document '{
     "Version": "2012-10-17",
     "Statement": [
        {
         "Effect": "Allow",
         "Action": [
           "s3:ListBucket"
         ],
         "Resource": [
           "arn:aws:s3:::BUCKET_NAME"
          ]
        },
       {
         "Effect": "Allow",
         "Action": [
           "s3:GetObject",
           EXPORT_PERM
         ],
         "Resource": [
           "arn:aws:s3:::BUCKET_NAME",
            "arn:aws:s3:::BUCKET_NAME/*"
          ]
        }
     ]
    }'

更改下列內容:

  • POLICY_NAME:您要建立的政策名稱。
  • BUCKET_NAME:您希望 BigQuery 存取的 Amazon S3 儲存空間。
  • EXPORT_PERM (選用):如果您想將資料匯出至 Amazon S3 值區,請授予額外權限。以「"s3:PutObject"」取代
    • 如要分開控管匯出存取權,建議您使用另一個 AWS IAM 角色建立其他連線,並授予該角色僅限寫入的存取權。如要更精細地控管存取權,您也可以限制角色只能存取值區的特定路徑。

系統會建立政策,並以以下格式提供 Amazon Resource Name (ARN):

arn:aws:iam::AWS_ACCOUNT_ID:policy/POLICY_NAME

更改下列內容:

  • AWS_ACCOUNT_ID:連線的 AWS IAM 使用者 ID 號碼。
  • POLICY_NAME:您選擇的政策名稱。

Terraform

在 Terraform 設定中新增下列內容,將政策附加至 Amazon S3 值區資源:

  resource "aws_iam_policy" "bigquery-omni-connection-policy" {
    name = "bigquery-omni-connection-policy"

    policy = <<-EOF
            {
              "Version": "2012-10-17",
              "Statement": [
                  {
                      "Sid": "BucketLevelAccess",
                      "Effect": "Allow",
                      "Action": ["s3:ListBucket"],
                      "Resource": ["arn:aws:s3:::BUCKET_NAME"]
                  },
                  {
                      "Sid": "ObjectLevelAccess",
                      "Effect": "Allow",
                      "Action": ["s3:GetObject",EXPORT_PERM],
                      "Resource": [
                          "arn:aws:s3:::BUCKET_NAME",
                          "arn:aws:s3:::BUCKET_NAME/*"
                          ]
                  }
              ]
            }
            EOF
  }

更改下列內容:

  • BUCKET_NAME:您希望 BigQuery 存取的 Amazon S3 儲存空間。
  • EXPORT_PERM (選用):額外權限,如果您想將資料匯出至 Amazon S3 值區。以「"s3:PutObject"」取代
    • 如要分開控管匯出存取權,建議您使用不同的 AWS IAM 角色建立另一個連線,並授予該角色僅限寫入的存取權。如要更精細地控管存取權,您也可以限制角色只能存取 bucket 的特定路徑。

為 BigQuery 建立 AWS IAM 角色

接著,建立可從 BigQuery 存取 Amazon S3 值區的角色。這個角色會使用您在前一節建立的政策。

如要建立 AWS IAM 角色,請使用 AWS 控制台或 Terraform:

AWS 管理主控台

  1. 前往 AWS IAM 主控台。 確認您目前使用的帳戶擁有要存取的 Amazon S3 值區。

    前往 AWS IAM 主控台

  2. 選取「角色」> 建立角色

  3. 在「Select type of trusted entity」部分,選取「Web Identity」

  4. 在「識別資訊提供者」部分,選取「Google」

  5. 在「目標對象」中,輸入 00000 做為預留位置值。 您稍後會替換這個值。

  6. 點選 [Next: Permissions] (下一步:權限)。

  7. 如要授予角色 Amazon S3 資料的存取權,請將 IAM 政策附加至該角色。搜尋您在前一節中建立的政策,然後點選切換按鈕。

  8. 按一下「下一步:代碼」

  9. 按一下「下一步:檢閱」。輸入角色名稱,例如 BQ_Read_Only

  10. 按一下「建立角色」

AWS CLI

使用下列指令建立 IAM 角色,並將政策指派給建立的角色:

  aws iam create-role \
   --role-name bigquery-omni-connection \
   --max-session-duration 43200 \
   --assume-role-policy-document '{
     "Version": "2012-10-17",
     "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "accounts.google.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "accounts.google.com:sub": "00000"
                }
            }
        }
    ]
}'

Terraform

在 Terraform 設定中新增下列項目,建立 IAM 角色並將政策指派給建立的角色:

  resource "aws_iam_role" "bigquery-omni-connection-role" {
    name                 = "bigquery-omni-connection"
    max_session_duration = 43200

    assume_role_policy = <<-EOF
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "accounts.google.com"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "accounts.google.com:sub": "00000"
            }
          }
        }
      ]
    }
    EOF
  }

  resource "aws_iam_role_policy_attachment" "bigquery-omni-connection-role-attach" {
    role       = aws_iam_role.bigquery-omni-connection-role.name
    policy_arn = aws_iam_policy.bigquery-omni-connection-policy.arn
  }

  output "bigquery_omni_role" {
    value = aws_iam_role.bigquery-omni-connection-role.arn
  }

然後將政策附加至角色:

  aws iam attach-role-policy \
    --role-name bigquery-omni-connection \
    --policy-arn arn:aws:iam::AWS_ACCOUNT_ID:policy/POLICY_NAME

更改下列內容:

  • AWS_ACCOUNT_ID:連線的 AWS IAM 使用者 ID 號碼。
  • POLICY_NAME:您選擇的政策名稱。

建立連結

如要連線至 Amazon S3 儲存空間,請使用Google Cloud 主控台、bq 指令列工具或用戶端程式庫:

主控台

  1. 前往「BigQuery」頁面

    前往 BigQuery

  2. 在「Explorer」窗格中,按一下 「新增資料」

    「新增資料」對話方塊隨即開啟。

  3. 在「Filter By」(依條件篩選) 窗格的「Data Source Type」(資料來源類型) 區段中,選取「Storage/Data Lakes」(儲存空間/資料湖泊)

    或者,您也可以在「Search for data sources」(搜尋資料來源) 欄位中輸入 awsAmazon S3

  4. 在「精選資料來源」部分,按一下「Amazon S3」

  5. 按一下「Amazon S3 Omni:BigQuery 聯盟」解決方案資訊卡。

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

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

    • 在「連線類型」中,選取「AWS 中的 BigLake (透過 BigQuery Omni)」
    • 在「Connection ID」(連線 ID) 專區中輸入連線資源的 ID。可以使用英文字母、數字、破折號和底線。
    • 在「Region」(區域) 部分,選取要建立連線的位置。
    • 選用:在「Friendly name」(好記名稱) 中輸入使用者容易記得的連線名稱,例如 My connection resource。好記名稱可以是任何資料值,只要您日後需要修改時可以輕鬆識別連線資源即可。
    • 選用:在「Description」(說明) 中輸入這項連線資源的說明。
    • 在「AWS 角色 ID」欄位中,輸入您建立的完整 IAM 角色 ID,格式如下:
      arn:aws:iam::AWS_ACCOUNT_ID:role/ROLE_NAME
  8. 點選「建立連線」

  9. 按一下「前往連線」

  10. 在「連線資訊」窗格中,複製「BigQuery Google 身分」。 這是 Google 主體,每個連線都有專屬主體。範例:

      BigQuery Google identity: IDENTITY_ID
      

Terraform

  resource "google_bigquery_connection" "connection" {
    connection_id = "bigquery-omni-aws-connection"
    friendly_name = "bigquery-omni-aws-connection"
    description   = "Created by Terraform"

    location      = "AWS_LOCATION"
    aws {
      access_role {
        # This must be constructed as a string instead of referencing the
        # AWS resources directly to avoid a resource dependency cycle
        # in Terraform.
        iam_role_id = "arn:aws:iam::AWS_ACCOUNT:role/IAM_ROLE_NAME"
      }
    }
  }

更改下列內容:

bq

bq mk --connection --connection_type='AWS' \
--iam_role_id=arn:aws:iam::AWS_ACCOUNT_ID:role/ROLE_NAME \
--location=AWS_LOCATION \
CONNECTION_ID

更改下列內容:

  • AWS_ACCOUNT_ID:連線的 AWS IAM 使用者 ID 號碼
  • ROLE_NAME:您選擇的角色政策名稱
  • AWS_LOCATIONAmazon S3 位置 (位於 Google Cloud)
  • CONNECTION_ID:您為這個連線資源指定的 ID。

指令列會顯示下列輸出內容:

  Identity: IDENTITY_ID

輸出內容包含下列項目:

  • IDENTITY_ID:Google 主體, Google Cloud 可控制各個連線專屬的控制項。

請記下 IDENTITY_ID 的值。

Java

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

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

import com.google.cloud.bigquery.connection.v1.AwsAccessRole;
import com.google.cloud.bigquery.connection.v1.AwsProperties;
import com.google.cloud.bigquery.connection.v1.Connection;
import com.google.cloud.bigquery.connection.v1.CreateConnectionRequest;
import com.google.cloud.bigquery.connection.v1.LocationName;
import com.google.cloud.bigqueryconnection.v1.ConnectionServiceClient;
import java.io.IOException;

// Sample to create aws connection
public class CreateAwsConnection {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "MY_PROJECT_ID";
    // Example of location: aws-us-east-1
    String location = "MY_LOCATION";
    String connectionId = "MY_CONNECTION_ID";
    // Example of role id: arn:aws:iam::accountId:role/myrole
    String iamRoleId = "MY_AWS_ROLE_ID";
    AwsAccessRole role = AwsAccessRole.newBuilder().setIamRoleId(iamRoleId).build();
    AwsProperties awsProperties = AwsProperties.newBuilder().setAccessRole(role).build();
    Connection connection = Connection.newBuilder().setAws(awsProperties).build();
    createAwsConnection(projectId, location, connectionId, connection);
  }

  static void createAwsConnection(
      String projectId, String location, String connectionId, Connection connection)
      throws IOException {
    try (ConnectionServiceClient client = ConnectionServiceClient.create()) {
      LocationName parent = LocationName.of(projectId, location);
      CreateConnectionRequest request =
          CreateConnectionRequest.newBuilder()
              .setParent(parent.toString())
              .setConnection(connection)
              .setConnectionId(connectionId)
              .build();
      Connection response = client.createConnection(request);
      AwsAccessRole role = response.getAws().getAccessRole();
      System.out.println(
          "Aws connection created successfully : Aws userId :"
              + role.getIamRoleId()
              + " Aws externalId :"
              + role.getIdentity());
    }
  }
}

為 AWS 角色新增信任關係

BigQuery Omni 提供兩種方法,可安全地存取 Amazon S3 中的資料。您可以授予 Google Cloud 服務帳戶 AWS 角色存取權,或者,如果 AWS 帳戶有 accounts.google.com 的自訂身分識別提供者,則必須將 Google Cloud 服務帳戶新增為提供者的對象:

為 AWS 角色新增信任政策

信任關係可讓連線擔任角色,並根據角色政策存取 Amazon S3 資料。

如要新增信任關係,請使用 AWS 控制台或 Terraform:

AWS 管理主控台

  1. 前往 AWS IAM 主控台。 確認您目前使用的帳戶擁有要存取的 Amazon S3 值區。

    前往 AWS IAM 主控台

  2. 選取「角色」

  3. 選取您建立的 ROLE_NAME

  4. 按一下「編輯」,然後執行下列操作:

    1. 將「工作階段持續時間上限」設為「12 小時」。由於每項查詢最多可執行六小時,因此這段時間允許一次額外的重試。將工作階段時間延長至 12 小時以上,不會增加重試次數。詳情請參閱「查詢/多重陳述式查詢執行時間限制」。

      在 AWS 中點選「編輯」按鈕,設定工作階段時間長度。

    2. 按一下 [儲存變更]。

  5. 選取「信任關係」,然後按一下「編輯信任關係」。 將政策內容換成下列內容:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "accounts.google.com"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "accounts.google.com:sub": "IDENTITY_ID"
            }
          }
        }
      ]
    }

    IDENTITY_ID 替換為 BigQuery Google 身分識別值,您可以在 Google Cloud 控制台中找到您建立的連線

  6. 按一下「更新信任政策」

AWS CLI

如要建立與 BigQuery 連線的信任關係,請使用 aws iam update-assume-role-policy 指令

  aws iam update-assume-role-policy \
    --role-name bigquery-omni-connection \
    --policy-document '{
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "accounts.google.com"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "accounts.google.com:sub": "IDENTITY_ID"
            }
          }
        }
      ]
    }'
  aws iam update-assume-role-policy \
    --role-name bigquery-omni-connection \
    --policy-document '{
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "accounts.google.com"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "accounts.google.com:sub": "IDENTITY_ID"
            }
          }
        }
      ]
    }'

更改下列內容:

  • IDENTITY_IDBigQuery Google 身分值,您可以在 Google Cloud 建立的連線的控制台中找到這個值。

Terraform

更新 Terraform 設定中的 aws_iam_role 資源,新增信任關係:

    resource "aws_iam_role" "bigquery-omni-connection-role" {
      name                 = "bigquery-omni-connection"
      max_session_duration = 43200

      assume_role_policy = <<-EOF
          {
            "Version": "2012-10-17",
            "Statement": [
              {
                "Effect": "Allow",
                "Principal": {
                  "Federated": "accounts.google.com"
                },
                "Action": "sts:AssumeRoleWithWebIdentity",
                "Condition": {
                  "StringEquals": {
                    "accounts.google.com:sub": "${google_bigquery_connection.connection.aws[0].access_role[0].identity}"
                  }
                }
              }
            ]
          }
          EOF
    }

現在可以使用連線了。

設定自訂 AWS 識別資訊提供者

如果 AWS 帳戶有 accounts.google.comIDENTITY_ID自訂身分識別提供者,您需要將 IDENTITY_ID 新增為提供者的目標對象。方法如下:

  1. 前往 AWS IAM 主控台。 確認您目前使用的帳戶擁有要存取的 Amazon S3 值區。

    前往 AWS IAM 主控台

  2. 依序前往「IAM」>「身分識別提供者」

  3. 選取 accounts.google.com 的識別資訊提供者。

  4. 按一下「新增目標對象」,然後新增 IDENTITY_ID 做為目標對象。

現在可以使用連線了。

與使用者共用連線

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

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

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

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

選取下列選項之一:

主控台

  1. 前往「BigQuery」頁面

    前往 BigQuery

    連線會列在專案的「External connections」(外部連線) 群組中。

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

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

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

    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");
    }
  }
}

後續步驟