Conéctate a Amazon S3

Como administrador de BigQuery, puedes crear una conexión para permitir que los analistas de datos accedan a los datos almacenados en los buckets de Amazon Simple Storage Service (Amazon S3).

BigQuery Omni accede a los datos de Amazon S3 a través de conexiones. Cada conexión tiene su propio usuario único de Identity and Access Management (IAM) de Amazon Web Services (AWS). Debes otorgar permisos a los usuarios a través de las funciones de IAM de AWS. Las políticas dentro de las funciones de IAM de AWS determinan a qué datos puede acceder BigQuery en cada conexión.

Se requieren conexiones para consultar los datos de Amazon S3 y exportar los resultados de las consultas de BigQuery al bucket de Amazon S3.

Antes de comenzar

Asegúrate de que creaste los siguientes recursos:

Roles obligatorios

Para obtener los permisos que necesitas para crear una conexión que te permita acceder a los datos de Amazon S3, pídele a tu administrador que te otorgue el rol de IAM de Administrador de conexión de BigQuery (roles/bigquery.connectionAdmin) en el proyecto. Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso.

También puedes obtener los permisos necesarios mediante roles personalizados o cualquier otro rol predefinido.

Crea una política de IAM de AWS para BigQuery

Asegúrate de seguir las prácticas recomendadas de seguridad para Amazon S3. Te recomendamos que hagas lo siguiente:

  • Configura una política de AWS que evite el acceso a tu bucket de Amazon S3 a través de HTTP.
  • Configura una política de AWS que evite el acceso público a tu bucket de Amazon S3.
  • Usa la encriptación del servidor de Amazon S3.
  • Limita los permisos otorgados a la Cuenta de Google al mínimo requerido.
  • Configura CloudTrails y habilita los eventos de datos de Amazon S3.

Para crear una política de IAM de AWS, usa AWS Console o Terraform:

AWS Console

  1. Ve a la consola de Identity and Access Management (IAM) de AWS. Asegúrate de estar en la cuenta que es propietaria del bucket de Amazon S3 al que deseas acceder.
  2. Selecciona Policies > Create policy (se abrirá en una pestaña nueva).
  3. Haz clic en JSON y pega lo siguiente en el editor:

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

    Reemplaza lo siguiente:

    • BUCKET_NAME: el bucket de Amazon S3 al que deseas que BigQuery acceda.
  4. En el campo Nombre, ingresa un nombre de política, como bq_omni_read_only.

  5. Haga clic en Crear política.

La política se creó con un nombre de recursos de Amazon (ARN) en el siguiente formato:

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

Reemplaza los siguientes elementos:

  • AWS_ACCOUNT_ID: Es el número de ID del usuario de IAM de AWS de la conexión.
  • POLICY_NAME: Es el nombre de la política que elegiste.

Terraform

Agrega lo siguiente a tu configuración de Terraform para adjuntar una política a un recurso de bucket de 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"],
                      "Resource": [
                          "arn:aws:s3:::BUCKET_NAME",
                          "arn:aws:s3:::BUCKET_NAME/*"
                          ]
                  }
              ]
            }
            EOF
  }

Reemplaza BUCKET_NAME por el bucket de Amazon S3 al que deseas que BigQuery acceda.

Si necesitas exportar datos a un bucket de Amazon S3, también necesitas el permiso s3:PutObject. Para separar el control de acceso, te recomendamos que crees otra conexión con una función separada de IAM de AWS y otorgues a la función acceso de solo escritura. Para obtener un control de acceso más detallado, también puedes limitar el acceso de una función a una ruta de acceso específica del bucket.

Crea un rol de IAM de AWS para BigQuery

A continuación, crea un rol que permita el acceso al bucket de Amazon S3 desde BigQuery. Este rol usa la política que creaste en la sección anterior.

Para crear un rol de IAM de AWS, usa la consola de AWS o Terraform:

AWS Console

  1. Ve a la consola de IAM de AWS. Asegúrate de estar en la cuenta que es propietaria del bucket de Amazon S3 al que deseas acceder.
  2. Selecciona Roles > Create role.
  3. En Seleccionar tipo de entidad de confianza, selecciona Entidad web.
  4. En Proveedor de identidad, selecciona Google.
  5. En Público, ingresa 00000 como valor de marcador de posición. Reemplazarás el valor más adelante.
  6. Haz clic en Next: Permissions.
  7. Para otorgar al rol acceso a tus datos de Amazon S3, adjunta una política de IAM al rol. Busca la política que creaste en la sección anterior y haz clic en el botón de activar o desactivar.
  8. Haz clic en Siguiente: Etiquetas.
  9. Haz clic en Siguiente: Revisar. Ingresa un nombre para la función, como BQ_Read_Only.
  10. Haz clic en Crear rol.

Terraform

Agrega lo siguiente a tu configuración de Terraform para crear un rol de IAM y asígnale la política al rol creado:

  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
  }

Crear conexiones

Para conectarte a tu bucket de Amazon S3, usa la consola de Google Cloud, la herramienta de línea de comandos de bq o la biblioteca cliente:

Console

  1. Ve a la página de BigQuery.

    Ir a BigQuery

  2. En el menú Agregar datos , selecciona Fuente de datos externa.

  3. En el panel Fuente de datos externa, ingresa la siguiente información:

    • En Tipo de conexión, selecciona BigLake on AWS (mediante BigQuery Omni).
    • En ID de conexión, ingresa un identificador para el recurso de conexión. Puedes usar letras, números, guiones y guiones bajos.
    • Selecciona la ubicación en la que deseas crear la conexión.
    • En Nombre descriptivo, ingresa un nombre fácil de usar para la conexión, como My connection resource (opcional). El nombre descriptivo puede ser cualquier valor que te ayude a identificar el recurso de conexión si necesitas modificarlo más adelante.
    • En Descripción, ingresa una descripción para este recurso de conexión (opcional).
    • En ID del rol de AWS, ingresa el ID del rol de IAM completo que creaste en este formato: arn:aws:iam::AWS_ACCOUNT_ID:role/ROLE_NAME.
  4. Haga clic en Crear conexión.

  5. Haz clic en Ir a la conexión.

  6. En el panel Información de la conexión, copia la identidad de BigQuery en Google. Este es un principio de Google específico para cada conexión. Ejemplo:

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

Reemplaza lo siguiente:

bq

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

Reemplaza lo siguiente:

  • AWS_ACCOUNT_ID: Es el número de ID del usuario de IAM de AWS de la conexión.
  • ROLE_NAME: Es el nombre de la política del rol que elegiste.
  • AWS_LOCATION: una ubicación de Amazon S3 en Google Cloud
  • CONNECTION_ID: el ID que le otorgas a este recurso de conexión.

La línea de comandos muestra el siguiente resultado:

  Identity: IDENTITY_ID

El resultado contiene lo siguiente:

  • IDENTITY_ID: Una principal de Google que Google Cloud controla y que es específica para cada conexión.

Toma nota del valor de IDENTITY_ID.

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración para Java incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Java.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

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

Agrega una relación de confianza al rol de AWS

BigQuery Omni proporciona dos métodos para acceder de forma segura a los datos desde Amazon S3. Puedes otorgar a la cuenta de servicio de Google Cloud acceso a tu rol de AWS o si tu cuenta de AWS tiene un proveedor de identidad personalizado para accounts.google.com, debes agregar la cuenta de servicio de Google Cloud como público al proveedor:

Agrega una política de confianza al rol de AWS

La relación de confianza permite que la conexión asuma el rol y acceda a los datos de Amazon S3 como se especifica en la política de roles.

Para agregar una relación de confianza, usa la consola de AWS o Terraform:

AWS Console

  1. Ve a la consola de IAM de AWS. Asegúrate de estar en la cuenta que es propietaria del bucket de Amazon S3 al que deseas acceder.
  2. Selecciona Roles.
  3. Selecciona el ROLE_NAME que creaste.
  4. Haz clic en Editar y, luego, haz lo siguiente:

    1. Establece la Duración máxima de la sesión en 12 horas. Como cada consulta puede ejecutarse durante un máximo de seis horas, esta duración permite un reintento adicional. Si se aumenta la duración de la sesión por más de 12 horas, no se podrán realizar reintentos adicionales. Para obtener más información, consulta el límite de tiempo de ejecución de la consulta de varias declaraciones/consulta.

      Botón Editar en AWS para establecer la duración de la sesión.

    2. Haga clic en Guardar cambios.

  5. Selecciona Trust Relationships y haz clic en Edit trust relationship. Reemplaza el contenido de la política por lo siguiente:

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

    Reemplaza IDENTITY_ID por el valor de identidad de Google de BigQuery, que puedes encontrar en la página de la consola de AWS para la conexión que creaste.

  6. Haz clic en Update Trust Policy.

Terraform

Actualiza el recurso aws_iam_role en la configuración de Terraform para agregar una relación de confianza:

    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
    }

La conexión ya está lista para usar.

Configura un proveedor de identidad de AWS personalizado

Si tu cuenta de AWS tiene un proveedor de identidad personalizado para accounts.google.com, deberás agregar IDENTITY_ID de la siguiente manera como un público al proveedor. Para ello, tienes las siguientes opciones:

  1. En la consola de AWS, ve a la página IAM.

    Ir a IAM de AWS

  2. Navega a IAM > IAM.

  3. Selecciona el proveedor de identidad para accounts.google.com.

  4. Haz clic en Agregar público y agrega IDENTITY_ID como el público.

La conexión ya está lista para usar.

Comparte conexiones con usuarios

Puedes otorgar los siguientes roles para permitir que los usuarios consulten datos y administren conexiones:

  • roles/bigquery.connectionUser: Permite que los usuarios usen conexiones para conectarse con fuentes de datos externas y ejecutar consultas en ellas.

  • roles/bigquery.connectionAdmin: Permite que los usuarios administren conexiones.

Para obtener más información sobre los roles y los permisos de IAM en BigQuery, consulta Roles y permisos predefinidos.

Selecciona una de las opciones siguientes:

Console

  1. Ve a la página de BigQuery.

    Ir a BigQuery

    Las conexiones se enumeran en tu proyecto, en un grupo llamado Conexiones externas.

  2. En el panel Explorer, haz clic en el nombre de tu proyecto > Explorer > conexión.

  3. En el panel Detalles, haz clic en Compartir para compartir una conexión. A continuación, sigue estos pasos:

    1. En el cuadro de diálogo Permisos de conexión, agrega o edita las principales para compartir la conexión con otros principales.

    2. Haz clic en Guardar.

bq

No puedes compartir una conexión con la herramienta de línea de comandos de bq. Para compartir una conexión, usa la consola de Google Cloud o el método de la API de conexiones de BigQuery.

API

Consulta el método projects.locations.connections.setIAM en la sección de referencia de la API de REST de las conexiones de BigQuery y proporciona una instancia del recurso policy.

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración para Java incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Java.

Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

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

¿Qué sigue?