Migración sencilla de Amazon S3 a Cloud Storage

En esta página se describe cómo completar una migración sencilla de Amazon Simple Storage Service (Amazon S3) a Cloud Storage. En una migración sencilla, usas tus herramientas y bibliotecas para generar solicitudes REST autenticadas a Amazon S3 y, en su lugar, envías solicitudes autenticadas a Cloud Storage.

Si no tienes experiencia con Cloud Storage y no vas a usar la API directamente, te recomendamos que utilices la consola para configurar y gestionar las transferencias Google Cloud . La consola deGoogle Cloud proporciona una interfaz gráfica a Cloud Storage que te permite llevar a cabo muchas de tus tareas de almacenamiento con solo un navegador, incluida la migración de tus datos de Amazon S3 a Cloud Storage.

Si quieres que Cloud Storage almacene una copia de seguridad de tus datos de Amazon S3, te recomendamos que uses las transferencias basadas en eventos, que usan las notificaciones de eventos de Amazon S3 para mantener automáticamente sincronizado un segmento de Cloud Storage con tu fuente de Amazon S3.

Migrar de Amazon S3 a Cloud Storage en un escenario de migración sencillo

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

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

    • Cambia el endpoint de la solicitud para usar el endpoint de la solicitud de la API XML de Cloud Storage.
    • Sustituye la clave de acceso y la clave secreta de Amazon Web Services (AWS) por el ID de acceso y el secreto de Cloud Storage correspondientes (en conjunto, se denominan "clave HMAC de Cloud Storage").
    • Asegúrate de que los encabezados x-amz- usen valores de Cloud Storage compatibles. Por ejemplo, x-amz-storage-class debe usar una de las clases de almacenamiento de Cloud Storage disponibles.

      Cuando usas la API XML de Cloud Storage en un escenario de migración sencillo, especificar el identificador de firma AWS en el encabezado Authorization indica a Cloud Storage que debe esperar encabezados x-amz-* y sintaxis XML de ACL de Amazon S3 en tu solicitud. Cloud Storage procesa los encabezados x-amz-* que tienen un equivalente x-goog-*, como los que se indican en la tabla de encabezados, y procesa el encabezado x-amz-decoded-content-length.

Una vez que hayas hecho estos cambios, podrás empezar a usar tus herramientas y bibliotecas para enviar solicitudes HMAC a Cloud Storage.

Por ejemplo, en los siguientes ejemplos se muestra cómo enumerar segmentos de Cloud Storage con el SDK de Amazon S3:

Go

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

Para autenticarte en Cloud Storage, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación para bibliotecas de cliente.

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

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

Para autenticarte en Cloud Storage, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación para bibliotecas de cliente.

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

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

Para autenticarte en Cloud Storage, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación para bibliotecas de cliente.

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

Definir un proyecto predeterminado

Para usar Cloud Storage en un escenario de migración sencillo, te recomendamos que definas un proyecto predeterminado, que Cloud Storage usará para llevar a cabo determinadas operaciones, como el GET servicio o el PUT segmento. Si no defines un proyecto predeterminado, debes especificar un encabezado de proyecto en determinadas solicitudes.

Para definir un proyecto predeterminado, sigue estos pasos:

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

    Si el proyecto ya es el predeterminado, verás el mensaje PROJECT-ID es el proyecto predeterminado del acceso interoperable.

Este proyecto ya es tu proyecto predeterminado. Puedes cambiar el proyecto predeterminado en cualquier momento. Para ello, elige otro proyecto y sigue estos pasos.

También puedes especificar un encabezado de proyecto

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

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

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

  • Estás trabajando con varios proyectos.
  • Tus solicitudes se realizan mediante una cuenta de servicio asociada a otro proyecto, ya que las cuentas de servicio usan su proyecto principal como proyecto predeterminado.

Ten en cuenta que Amazon S3 no tiene proyectos, por lo que, en función de las herramientas o las bibliotecas de cliente que utilices, puede que no sea posible especificar un encabezado x-amz-project-id. En ese caso, debes definir un proyecto predeterminado.

Usar claves HMAC

Para usar la API XML de Cloud Storage en un escenario de migración sencillo, utiliza 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 a una cuenta de servicio. Sin embargo, también puedes usar una asociada a una cuenta de usuario.

Autenticar en un escenario de migración sencillo

Usar el encabezado Authorization

En las operaciones de un escenario de migración simple que requieren autenticación, se incluye un encabezado de solicitud Authorization, al igual que en las solicitudes a Amazon S3. La sintaxis del encabezado Authorization de una solicitud de Amazon S3 es la siguiente:

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

En un escenario de migración sencillo, solo tienes que cambiar el encabezado para usar tu ID de acceso HMAC de Cloud Storage y asegurarte de que el Signature que adjuntes se calcule con tu 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 las siguientes:

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

  • GOOG-ACCESS-ID: el ID de acceso identifica la entidad que hace y firma la solicitud. En una migración sencilla, sustituye el ID de clave de acceso de Amazon Web Service (AWS) que usas para acceder a Amazon S3 por tu ID de acceso HMAC de Cloud Storage. Tu ID de acceso HMAC de Cloud Storage empieza por GOOG.

  • CREDENTIAL_SCOPE: el ámbito de las credenciales, tal como se define en la firma. En una migración sencilla, no es necesario que cambies el ámbito de las credenciales si usas AWS4-HMAC-SHA256 para el valor de ALGORITHM.

  • SIGNED_HEADERS: lista de nombres de encabezados separados por punto y coma que deben incluirse para firmar esta solicitud. Todos los encabezados deben estar en minúsculas y ordenados por código de carácter.

    Un ejemplo de cadena de encabezado firmada al estilo de Amazon S3 es el siguiente:

    content-type;host;x-amz-date

    En una migración sencilla, no es necesario que hagas ningún cambio en la cadena de encabezado firmado.

  • SIGNATURE: la firma que permite autenticar la solicitud. En una migración sencilla, sustituye 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 ejemplo

En los siguientes ejemplos se sube un objeto llamado /europe/france/paris.jpg a un segmento llamado my-travel-maps, se aplica la LCA predefinida public-read y se define un encabezado de metadatos personalizado para los revisores. Esta es la solicitud a un segmento de 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

Esta es la solicitud de un segmento de 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

Esta es la solicitud canónica correspondiente que se ha creado 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

Esta es la cadena que se ha creado para esta solicitud:

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

En esta solicitud no se ha proporcionado una cabecera Content-MD5, por lo que se muestra una cadena vacía en la segunda línea del mensaje.

Control de acceso en un escenario de migración sencillo

Para facilitar las migraciones, Cloud Storage acepta las listas de control de acceso creadas por Amazon S3. En un escenario de migración sencillo, se usa AWS como identificador de firma, lo que indica a Cloud Storage que debe esperar la sintaxis de ACL con la sintaxis XML de ACL de Amazon S3. Debe asegurarse de que las LCAs de Amazon S3 que utilice se correspondan con el modelo de LCAs de Cloud Storage. Por ejemplo, si tus herramientas y bibliotecas usan la sintaxis de las ACL de Amazon S3 para conceder el permiso WRITE de un segmento, también deben conceder el permiso READ del segmento, ya que los permisos de Cloud Storage son concéntricos. No es necesario que especifiques los permisos WRITE y READ cuando concedas el permiso WRITE con la sintaxis de Cloud Storage.

Cloud Storage admite la sintaxis de las ACL de Amazon S3 en los siguientes casos:

  • En una solicitud a Cloud Storage para recuperar las listas de control de acceso (por ejemplo, una solicitud de GETobjeto o de GETcubo), Cloud Storage devuelve la sintaxis de las listas de control de acceso de Amazon S3.
  • En una solicitud a Cloud Storage para aplicar LCA (por ejemplo, una solicitud de PUTobjeto o de PUTsegmento), Cloud Storage espera recibir la sintaxis de LCA de Amazon S3.

El encabezado Authorization en un escenario de migración sencillo usa AWS para el identificador de firma, pero con tu ID de acceso HMAC de Cloud Storage.

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 ACLs 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 ACL con la sintaxis de ACL 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 definir las listas de control de acceso de un objeto. En el ejemplo se muestra un cuerpo de solicitud con sintaxis de ACL 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>jeffersonloveshiking@gmail.com</EmailAddress>
      </Grantee>
      <Permission>FULL_CONTROL</Permission>
    </Grant>
  </AccessControlList>
</AccessControlPolicy>

Por último, en un escenario de migración sencillo, también puedes usar el identificador de firma GOOG1 en el encabezado Authorization. En este caso, debe usar la sintaxis de las LCA de Cloud Storage y asegurarse de que todos los encabezados x-amz-* se cambien a x-goog-*. Aunque es posible, te recomendamos que elijas una migración completa para disfrutar de todas las ventajas de Cloud Storage.

Compatibilidad con la API XML de Amazon S3

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

Siguientes pasos