Migración simple de Amazon S3 a Cloud Storage

En esta página, se describe cómo completar una migración simple de Amazon Simple Storage Service (Amazon S3) a Cloud Storage. En una migración simple, debes usar tus herramientas y bibliotecas existentes a fin de generar solicitudes REST autenticadas a Amazon S3 para enviar solicitudes autenticadas a Cloud Storage en su lugar.

Si eres nuevo en Cloud Storage y no vas a usar la API directamente, considera usar la consola de Google Cloud para configurar y administrar las transferencias. La consola de Google Cloud proporciona una interfaz gráfica para Cloud Storage que te permite realizar muchas de tus tareas de almacenamiento con solo un navegador, incluida la migración de tus datos de Amazon S3 a Cloud Storage.

Si deseas que Cloud Storage almacene una copia de seguridad de tus datos de Amazon S3, considera usar transferencias controladas por eventos, que usan las notificaciones de eventos de Amazon S3 para mantener de forma automática un bucket de Cloud Storage sincronizado. con tu fuente de Amazon S3.

Migra de Amazon S3 a Cloud Storage en una situación de migración simple

Para realizar solicitudes a Cloud Storage, debes completar los siguientes pasos:

  • Configura un proyecto predeterminado de Google Cloud.
  • Obtén una clave HMAC (código de autenticación de mensajes basado en hash).
  • En las herramientas o bibliotecas existentes, realiza los siguientes cambios:

    • Cambia el extremo de la solicitud para que use el extremo de solicitud a la API de XML de Cloud Storage.
    • Reemplaza el acceso y la clave secreta de Amazon Web Services (AWS) por el ID de acceso y la clave secreta de Cloud Storage correspondientes (en conjunto, se denominan clave HMAC de Cloud Storage).
    • Asegúrate de que tus encabezados x-amz- usen valores admitidos por Cloud Storage. Por ejemplo, x-amz-storage-class debería usar una de las clases de almacenamiento de Cloud Storage disponibles.

      Cuando usas la API de XML de Cloud Storage en una situación de migración simple, especificar el identificador de firma AWS en el encabezado Authorization le permite a Cloud Storage esperar encabezados x-amz-* y LCA con sintaxis XML de Amazon S3 en tu solicitud. Cloud Storage procesa los encabezados x-amz-* que tienen un x-goog-* equivalente, como los que se enumeran en la tabla de encabezados.

Después de realizar estos cambios, puedes empezar a usar las herramientas y bibliotecas existentes para enviar solicitudes HMAC a Cloud Storage.

En los siguientes ejemplos, se muestra cómo mostrar una lista de los buckets de Cloud Storage mediante el SDK de Amazon S3:

Go

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage Go.

Para autenticarte en Cloud Storage, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

import (
	"context"
	"fmt"
	"io"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
)

func listGCSBuckets(w io.Writer, googleAccessKeyID string, googleAccessKeySecret string) error {
	// googleAccessKeyID := "Your Google Access Key ID"
	// googleAccessKeySecret := "Your Google Access Key Secret"

	// Create a new client and do the following:
	// 1. Change the endpoint URL to use the Google Cloud Storage XML API endpoint.
	// 2. Use Cloud Storage HMAC Credentials.
	sess := session.Must(session.NewSession(&aws.Config{
		Region:      aws.String("auto"),
		Endpoint:    aws.String("https://storage.googleapis.com"),
		Credentials: credentials.NewStaticCredentials(googleAccessKeyID, googleAccessKeySecret, ""),
	}))

	client := s3.New(sess)
	ctx := context.Background()

	ctx, cancel := context.WithTimeout(ctx, time.Second*10)
	defer cancel()
	result, err := client.ListBucketsWithContext(ctx, &s3.ListBucketsInput{})
	if err != nil {
		return fmt.Errorf("ListBucketsWithContext: %w", err)
	}

	fmt.Fprintf(w, "Buckets:")
	for _, b := range result.Buckets {
		fmt.Fprintf(w, "%s\n", aws.StringValue(b.Name))
	}

	return nil
}

Java

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage Java.

Para autenticarte en Cloud Storage, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;
import java.util.List;

public class ListGcsBuckets {
  public static void listGcsBuckets(String googleAccessKeyId, String googleAccessKeySecret) {

    // String googleAccessKeyId = "your-google-access-key-id";
    // String googleAccessKeySecret = "your-google-access-key-secret";

    // Create a BasicAWSCredentials using Cloud Storage HMAC credentials.
    BasicAWSCredentials googleCreds =
        new BasicAWSCredentials(googleAccessKeyId, googleAccessKeySecret);

    // Create a new client and do the following:
    // 1. Change the endpoint URL to use the Google Cloud Storage XML API endpoint.
    // 2. Use Cloud Storage HMAC Credentials.
    AmazonS3 interopClient =
        AmazonS3ClientBuilder.standard()
            .withEndpointConfiguration(
                new AwsClientBuilder.EndpointConfiguration(
                    "https://storage.googleapis.com", "auto"))
            .withCredentials(new AWSStaticCredentialsProvider(googleCreds))
            .build();

    // Call GCS to list current buckets
    List<Bucket> buckets = interopClient.listBuckets();

    // Print bucket names
    System.out.println("Buckets:");
    for (Bucket bucket : buckets) {
      System.out.println(bucket.getName());
    }

    // Explicitly clean up client resources.
    interopClient.shutdown();
  }

Python

Si deseas obtener más información, consulta la documentación de referencia de la API de Cloud Storage Python.

Para autenticarte en Cloud Storage, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

import boto3  # type: ignore


def list_gcs_buckets(
    google_access_key_id: str, google_access_key_secret: str
) -> List[str]:
    """Lists all Cloud Storage buckets using AWS SDK for Python (boto3)
    Positional arguments:
        google_access_key_id: hash-based message authentication code (HMAC) access ID
        google_access_key_secret: HMAC access secret

    Returned value is a list of strings, one for each bucket name.

    To use this sample:
    1. Create a Cloud Storage HMAC key: https://cloud.google.com/storage/docs/authentication/managing-hmackeys#create
    2. Change endpoint_url to a Google Cloud Storage XML API endpoint.

    To learn more about HMAC: https://cloud.google.com/storage/docs/authentication/hmackeys#overview
    """
    client = boto3.client(
        "s3",
        region_name="auto",
        endpoint_url="https://storage.googleapis.com",
        aws_access_key_id=google_access_key_id,
        aws_secret_access_key=google_access_key_secret,
    )

    # Call GCS to list current buckets
    response = client.list_buckets()

    # Return list of bucket names
    results = []
    for bucket in response["Buckets"]:
        results.append(bucket["Name"])
        print(bucket["Name"])  # Can remove if not needed after development
    return results

Configura un proyecto predeterminado

Para usar Cloud Storage en una situación de migración simple, te recomendamos que configures un proyecto predeterminado, que Cloud Storage usa para realizar ciertas operaciones, como GET Service o PUT bucket. Si no configuraste un proyecto predeterminado, debes especificar un encabezado de proyecto en ciertas solicitudes.

Sigue estos pasos para establecer un proyecto predeterminado:

  1. Abre la página Configuración de Cloud Storage en la consola de Google Cloud.
  2. Selecciona la pestaña Interoperabilidad.
  3. Haz clic en Configurar PROJECT-ID como el proyecto predeterminado, ubicado en la sección Proyecto predeterminado para el acceso interoperable.

    Si ya está configurado como predeterminado, verás que PROJECT-ID es tu proyecto predeterminado para el acceso de interoperabilidad.

Este proyecto es ahora el predeterminado. Puedes cambiar el proyecto predeterminado en cualquier momento si eliges otro proyecto y sigues estos pasos.

También puedes especificar un encabezado de proyecto

En lugar de configurar un proyecto predeterminado (o además de hacerlo), puedes usar el encabezado x-amz-project-id en solicitudes individuales que requieran que especifiques un proyecto.

  • Una solicitud que usa x-amz-project-id usa el proyecto especificado en el encabezado, aunque haya un proyecto predeterminado existente.

El encabezado x-amz-project-id es útil en los siguientes casos:

  • Si estás trabajando con varios proyectos.
  • Si tus solicitudes se realizan mediante una cuenta de servicio asociada con un proyecto diferente, ya que las cuentas de servicio usan su proyecto superior como proyecto predeterminado.

Ten en cuenta que Amazon S3 no tiene proyectos, por lo que, según las herramientas o las bibliotecas cliente que uses, es posible que no se pueda especificar un encabezado x-amz-project-id. En este caso, debes configurar un proyecto predeterminado.

Usa claves HMAC

Para usar la API de XML de Cloud Storage en una situación de migración simple, usa las claves de código de autenticación de mensajes basado en hash (HMAC) de Cloud Storage para las credenciales. Por lo general, debes crear una clave HMAC asociada con una cuenta de servicio. Sin embargo, puedes usar una asociada con una cuenta de usuario.

Autentica en una situación de migración simple

Usa el encabezado Autorización

Para las operaciones en una situación de migración simple que requieren autenticación, incluye un encabezado de la solicitud Authorization, como haces con las solicitudes a Amazon S3. La sintaxis del encabezado Authorization para una solicitud de Amazon S3 es la siguiente:

Authorization: AWS4-HMAC-SHA256 Credential=AWS-ACCESS-KEY/CREDENTIAL_SCOPE, SignedHeaders=SIGNED_HEADERS, Signature=SIGNATURE

En una situación de migración simple, solo cambia el encabezado para usar el ID de acceso HMAC de Cloud Storage y asegúrate de que la Signature que adjuntas se calcule con la clave secreta HMAC de Cloud Storage:

Authorization: ALGORITHM Credential=GOOG-ACCESS-ID/CREDENTIAL_SCOPE, SignedHeaders=SIGNED_HEADERS, Signature=SIGNATURE

Las partes del encabezado Authorization son:

  • ALGORITHM: El algoritmo de firma y la versión que usas. El uso de AWS4-HMAC-SHA256 indica que usas una firma HMAC V4 y tienes la intención de enviar encabezados x-amz-*. También puedes usar GOOG4-HMAC-SHA256, que indica que usas una firma HMAC V4 y deseas enviar encabezados x-goog-*, o GOOG4-RSA-SHA256, que indica que estás usando una firma RSA V4 y que deseas enviar encabezados x-goog-*.

  • GOOG-ACCESS-ID: El ID de acceso identifica la entidad que realiza y firma la solicitud. En una migración simple, reemplaza el ID de la clave de acceso de Amazon Web Service (AWS) que usas para acceder a Amazon S3 por el ID de acceso HMAC de Cloud Storage. El ID de acceso HMAC de Cloud Storage comienza con GOOG.

  • CREDENTIAL_SCOPE: El permiso de la credencial, como se define en la firma. En una migración simple, no necesitas cambiar el permiso de la credencial si usas AWS4-HMAC-SHA256 para tu valor ALGORITHM.

  • SIGNED_HEADERS: Una lista de encabezados separados por punto y coma que se debe incluir para firmar esta solicitud. Todos los encabezados deben estar en minúscula y ordenados por código de caracteres.

    Un ejemplo de una string de encabezado firmado de estilo Amazon S3 se ve como se muestra a continuación:

    content-type;host;x-amz-date

    En una migración simple, no es necesario realizar ningún cambio en la string de encabezado firmado.

  • SIGNATURE: La firma que permite autenticar la solicitud. En una migración simple, reemplaza la información de la clave de acceso de AWS por la información de la clave HMAC de Cloud Storage equivalente.

Solicitud de autenticación de muestra

En los siguientes ejemplos, se sube un objeto llamado /europe/france/paris.jpg a un bucket llamado my-travel-maps, se aplica la LCA predefinida public-read y se define un encabezado de metadatos personalizado para los revisores. A continuación, se muestra la solicitud a un bucket en Amazon S3:

PUT europe/france/paris.jpg HTTP/1.1
Host: my-travel-maps.s3.amazonaws.com
Date: Mon, 11 Mar 2019 23:46:19 GMT
Content-Length: 888814
Content-Type: image/jpg
x-amz-acl: public-read
x-amz-date:20190311T192918Z
x-amz-meta-reviewer: joe,jane
Authorization: AWS4-HMAC-SHA256 Credential=AWS-ACCESS-KEY/20190311/us-east-1/s3/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-acl;x-amz-date;x-amz-meta-reviewer, Signature=SIGNATURE

A continuación, se muestra la solicitud de un bucket en Cloud Storage:

PUT europe/france/paris.jpg HTTP/1.1
Host: my-travel-maps.storage.googleapis.com
Date: Mon, 11 Mar 2019 23:46:19 GMT
Content-Length: 888814
Content-Type: image/jpg
x-amz-acl: public-read
x-amz-date:20190311T192918Z
x-amz-meta-reviewer: joe,jane
Authorization: AWS4-HMAC-SHA256 Credential=GOOG-ACCESS-ID/20190311/us-east-1/s3/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-acl;x-amz-date;x-amz-meta-reviewer, Signature=SIGNATURE

A continuación, se muestra la solicitud canónica que se creó para esta solicitud:

PUT
/europe/france/paris.jpg

content-length:888814
content-type:image/jpg
host:my-travel-maps.storage.googleapis.com
x-amz-acl:public-read
x-amz-date:20190311T192918Z
x-amz-meta-reviewer:joe,jane

content-length,content-type,host,x-amz-acl,x-amz-date,x-amz-meta-reviewer
82e3da8b3f35989512e8d428add7eca73ab0e5f36586e66fbad8e1051343cbd2

A continuación, se muestra la string para firmar que se creó en esta solicitud:

AWS4-HMAC-SHA256
20190311T192918Z
20190311/us-east-1/s3/aws4_request
73918a5ff373d7a03e406fbf9ea35675396b06fca2af76c27a5c451fa783ef65

Esta solicitud no proporcionó un encabezado Content-MD5, por lo que se muestra una string vacía en la segunda línea del mensaje.

Control de acceso en una situación de migración simple

Para admitir migraciones simples, Cloud Storage acepta las LCA producidas por Amazon S3. En una situación de migración simple, debes usar AWS como identificador de firma, lo que le indica a Cloud Storage que espere la sintaxis de LCA con el uso de la sintaxis XML de Amazon S3 LCA. Debes asegurarte de que las LCA de Amazon S3 que usas se asignen al modelo LCA de Cloud Storage. Por ejemplo, si tus herramientas y bibliotecas usan la sintaxis de la LCA de Amazon S3 para otorgar permiso de WRITE a un bucket, entonces también deben otorgar permiso de READ al bucket, porque los permisos de Cloud Storage son concéntricos. No es necesario que especifiques ambos permisos de WRITE y READ cuando otorgas el permiso de WRITE mediante la sintaxis de Cloud Storage.

Cloud Storage admite la sintaxis de la LCA de Amazon S3 en las siguientes situaciones:

  • En una solicitud a Cloud Storage para recuperar las LCA (por ejemplo, una solicitud de objeto GET o bucket GET), Cloud Storage muestra la sintaxis de LCA de Amazon S3.
  • En una solicitud a Cloud Storage para aplicar LCA (por ejemplo, una solicitud de objeto PUT o bucket PUT), Cloud Storage espera recibir la sintaxis de LCA de Amazon S3.

En una situación de migración simple, el encabezado Authorization usa AWS para el identificador de firma, pero con el ID de acceso de Google.

Authorization: AWS4-HMAC-SHA256 Credential=GOOG-ACCESS-ID/CREDENTIAL_SCOPE, SignedHeaders=SIGNED_HEADERS, Signature=SIGNATURE

En el siguiente ejemplo, se muestra una solicitud GET a Cloud Storage para devolver las LCA de un objeto.

GET europe/france/paris.jpg?acl HTTP/1.1
Host: my-travel-maps.storage.googleapis.com
Date: Thu, 21 Feb 2019 23:50:10 GMT
Content-Type: application/xml
X-Amz-Date: 20190221T235010Z
Authorization: AWS4-HMAC-SHA256 Credential=GOOGMC5PDPA5JLZYQMHQHRAX/20190221/region/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature=29088b1d6dfeb2549f6ff67bc3744abb7e45475f0ad60400485805415bbfc534

La respuesta a la solicitud incluye la LCA con la sintaxis de la LCA de Amazon S3.

<?xml version='1.0' encoding='UTF-8'?>
<AccessControlPolicy>
    <Owner>
        <ID>00b4903a972faa8bcce9382686e9129676f1cd6e5def1f5663affc2ba4652490
        </ID>
        <DisplayName>OwnerName</DisplayName>
    </Owner>
    <AccessControlList>
        <Grant>
            <Grantee xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
                xsi:type='CanonicalUser'>
                <ID>00b4903a972faa8bcce9382686e9129676f1cd6e5def1f5663affc2ba4652490</ID>
                <DisplayName>UserName</DisplayName>
            </Grantee>
            <Permission>FULL_CONTROL</Permission>
        </Grant>
    </AccessControlList>
</AccessControlPolicy>

En el siguiente ejemplo, se muestra una solicitud PUT a Cloud Storage para establecer las LCA de un objeto. En el ejemplo, se muestra un cuerpo de solicitud con la sintaxis de la LCA de Amazon S3.

PUT europe/france/paris.jpg?acl HTTP/1.1
Host: my-travel-maps.storage.googleapis.com
Date: Thu, 21 Feb 2019 23:50:10 GMT
Content-Type: application/xml
Content-Length: 337
X-Amz-Date: 20190221T235010Z
Authorization: AWS4-HMAC-SHA256 Credential=GOOGMC5PDPA5JLZYQMHQHRAX/20190221/region/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature=29088b1d6dfeb2549f6ff67bc3744abb7e45475f0ad60400485805415bbfc534

<?xml version='1.0' encoding='utf-8'?>
<AccessControlPolicy>
  <AccessControlList>
    <Grant>
      <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="AmazonCustomerByEmail">
        <EmailAddress>jane@gmail.com</EmailAddress>
      </Grantee>
      <Permission>FULL_CONTROL</Permission>
    </Grant>
  </AccessControlList>
</AccessControlPolicy>

Por último, en una situación de migración simple, también puedes usar el identificador de firma GOOG1 en el encabezado Authorization. En este caso, debes usar la sintaxis de LCA de Cloud Storage y asegurarte de que todos los encabezados x-amz-* se cambien a x-goog-*. Si bien esto es posible, te recomendamos que elijas una migración completa para usar todos los beneficios de Cloud Storage.

Asistencia para la compatibilidad de la API de XML con Amazon S3

Para discusiones sobre la interoperabilidad de la API de XML, consulta Stack Overflow con la etiqueta google-cloud-storage.

¿Qué sigue?