Amazon S3 に接続する

BigQuery 管理者は、データ アナリストが Amazon Simple Storage Service(Amazon S3)バケットに保存されているデータにアクセスできるように接続を作成できます。

BigQuery Omni は、接続を介して Amazon S3 のデータにアクセスします。接続ごとに独自の Amazon Web Services(AWS)の Identity and Access Management ユーザーが設定されています。AWS IAM のロールを使用してユーザーに権限を付与します。AWS IAM ロールのポリシーにより、それぞれの接続で BigQuery がアクセスできるデータが決まります。

Amazon S3 データに対してクエリを行いBigQuery から Amazon S3 バケットにクエリ結果をエクスポートするには接続が必要です。

始める前に

次のリソースが作成されていることを確認します。

必要なロール

Amazon S3 のデータにアクセスするための接続の作成に必要な権限を取得するには、プロジェクトに対する BigQuery Connection 管理者roles/bigquery.connectionAdmin)IAM ロールを付与するよう管理者に依頼してください。ロールの付与については、プロジェクト、フォルダ、組織へのアクセスを管理するをご覧ください。

必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。

BigQuery の AWS IAM ポリシーを作成する

Amazon S3 のセキュリティに関するベスト プラクティスに従ってください。次の手順を行うことをおすすめします。

  • HTTP 経由での Amazon S3 バケットへのアクセスを防ぐ AWS ポリシーを設定します。
  • Amazon S3 バケットへの公開アクセスを防ぐ AWS ポリシーを設定します。
  • Amazon S3 サーバーサイド暗号化を使用します。
  • Google アカウントに付与する権限を必要最小限のものにします。
  • CloudTrails を設定し、Amazon S3 データイベントを有効にします。

AWS IAM ポリシーを作成するには、AWS コンソールまたは Terraform を使用します。

AWS コンソール

  1. AWS Identity and Access Management(IAM)コンソールに移動します。アクセスする Amazon S3 バケットを所有しているアカウントにログインしていることを確認します。
  2. [Policies] > [Create policy] を選択します(新しいタブが開きます)。
  3. [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. [Create policy] をクリックします。

ポリシーが次の形式の 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 ロールで別の接続を作成し、ロールに書き込み専用アクセス権を付与することをおすすめします。バケットの特定のパスに対するロールのアクセス権を制限すれば、よりきめ細かいアクセス制御を行うことができます。

BigQuery の AWS IAM ロールを作成する

次に、BigQuery 内から Amazon S3 バケットへのアクセスを許可するロールを作成します。このロールは、前のセクションで作成したポリシーを使用します。

AWS IAM ロールを作成するには、AWS コンソールまたは Terraform を使用します。

AWS コンソール

  1. AWS IAM コンソールに移動します。アクセスする Amazon S3 バケットを所有しているアカウントにログインしていることを確認します。
  2. [Roles] > [Create role] を選択します。
  3. [Select type of trusted entity] で、[Web Identity] を選択します。
  4. [Identity Provider] で [Google] を選択します。
  5. [Audience] に、プレースホルダ値として「00000」と入力します。値は後で置き換えます。
  6. [Next: Permissions] をクリックします。
  7. Amazon S3 データに対するアクセス権をロールに付与するには、IAM ポリシーをロールに接続します。前のセクションで作成したポリシーを検索し、切り替えボタンをクリックします。
  8. [Next: Tags] をクリックします。
  9. [Next: Review] をクリックします。ロールの名前を入力します(例: BQ_Read_Only)。
  10. [Create role] をクリックします。

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
  }

接続を作成する

Amazon S3 バケットに接続するには、Google Cloud コンソール、bq コマンドライン ツール、またはクライアント ライブラリを使用します。

コンソール

  1. BigQuery ページに移動します。

    BigQuery に移動

  2. [追加] メニューで [外部データソース] を選択します。

  3. [外部データソース] ペインで、次の情報を入力します。

    • [Connection type] で、[BigLake on AWS (via BigQuery Omni)] を選択します。
    • [接続 ID] に、接続リソースの識別子を入力します。文字、数字、ダッシュ、アンダースコアを使用できます。
    • 接続を作成するロケーションを選択します。
    • (省略可)[わかりやすい名前] に、わかりやすい接続名を入力します(例: My connection resource)。後で修正が必要になった場合、わかりやすい名前だと接続リソースを簡単に識別できます。
    • (省略可)[説明] に、この接続リソースの説明を入力します。
    • [AWS ロール ID] に、作成した IAM ロール ID を arn:aws:iam::AWS_ACCOUNT_ID:role/ROLE_NAME の形式で入力します。
  4. [接続を作成] をクリックします。

  5. [接続へ移動] をクリックします。

  6. [Connection info] ペインで、BigQuery Google ID をコピーします。これは、各接続に固有の Google プリンシパルです。例:

      BigQuery Google identity: 000000000000000000000
      

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_LOCATION: Google Cloud の Amazon S3 のロケーション
  • CONNECTION_ID: この接続リソースに付ける ID

コマンドラインで次の出力が表示されます。

  Identity: IDENTITY_ID

出力には次のものが含まれます。

  • IDENTITY_ID: Google Cloud が制御する、各接続に固有の Google プリンシパル。

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 からデータに安全にアクセスするための 2 つの方法が用意されています。Google Cloud サービス アカウントに AWS ロールへのアクセス権を付与するか、AWS アカウントが accounts.google.com 用のカスタム ID プロバイダを持っている場合は、Google Cloud サービス アカウントをオーディエンスとしてプロバイダに追加する必要があります。

信頼ポリシーを AWS ロールに追加する

信頼関係により、ロールポリシーで指定されているロールと Amazon S3 データへのアクセス権を接続で使用します。

信頼関係を追加するには、AWS コンソールまたは Terraform を使用します。

AWS コンソール

  1. AWS IAM コンソールに移動します。アクセスする Amazon S3 バケットを所有しているアカウントにログインしていることを確認します。
  2. [Roles] を選択します。
  3. 作成した ROLE_NAME を選択します。
  4. [Edit] をクリックして、次の操作を行います。

    1. [Maximum session duration] を [12 hours] に設定します。各クエリは最大 6 時間実行できるため、この期間で追加の再試行を 1 回行うことができます。セッション継続時間を 12 時間以上に増やしても、追加の再試行は行えません。詳細については、クエリ / 複数ステートメント クエリ実行時間の上限をご覧ください。

      AWS の [Edit] ボタンをクリックして、セッション継続時間を設定します。

    2. [変更を保存] をクリックします。

  5. [Trust Relationships] を選択し、[Edit trust relationship] をクリックします。ポリシーの内容を次のもので置き換えます。

    {
      "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 ID の値に置き換えます。この値は、作成した接続の AWS コンソール ページで確認できます。

  6. [Update Trust Policy] をクリックします。

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 ID プロバイダを構成する

AWS アカウントに accounts.google.com 用のカスタム ID プロバイダがある場合は、次のように IDENTITY_ID をプロバイダのオーディエンスとして追加する必要があります。方法は次のとおりです。

  1. AWS コンソールで [IAM] ページに移動します。

    AWS IAM に移動

  2. [IAM] > [Identity Providers] に移動します。

  3. accounts.google.com の ID プロバイダを選択します。

  4. [Add Audience] をクリックし、IDENTITY_ID をオーディエンスとして追加します。

これで接続が使用できるようになりました。

ユーザーと接続を共有する

次のロールを付与することで、ユーザーがデータをクエリして接続を管理できます。

  • roles/bigquery.connectionUser: ユーザーが接続を使用して外部データソースに接続し、それらに対してクエリを実行できるようにします。

  • roles/bigquery.connectionAdmin: ユーザーが接続を管理できるようにします。

BigQuery での IAM のロールと権限について詳しくは、事前定義ロールと権限をご覧ください。

次のオプションのいずれかを選択します。

コンソール

  1. BigQuery ページに移動します。

    BigQuery に移動

    接続は、プロジェクトの外部接続というグループに一覧表示されます。

  2. [エクスプローラ] ペインで、[プロジェクト名] > [外部接続] > [接続] の順にクリックします。

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

次のステップ