Migration simple depuis Amazon S3 vers Cloud Storage

Cette page explique comment effectuer une migration simple depuis Amazon Simple Storage Service (Amazon S3) vers Cloud Storage. Lors d'une migration simple, vous utilisez vos outils et bibliothèques existants pour générer des requêtes REST authentifiées vers Amazon S3, afin d'envoyer plutôt des requêtes authentifiées à Cloud Storage.

Si vous débutez sur Cloud Storage et que vous ne souhaitez pas utiliser directement l'API, vous pouvez envisager d'utiliser la console Google Cloud pour définir et gérer les transferts. Google Cloud Console fournit une interface graphique à Cloud Storage qui vous permet, à l'aide d'un simple navigateur, d'accomplir la plupart de vos tâches de stockage, y compris la migration de vos données depuis Amazon S3 vers Cloud Storage.

Si vous souhaitez que Cloud Storage stocke une sauvegarde de vos données Amazon S3, envisagez d'utiliser des transferts basés sur des événements, qui utilisent les notifications d'événements Amazon S3 pour maintenir automatiquement la synchronisation d'un bucket Cloud Storage avec votre source Amazon S3.

Migrer depuis Amazon S3 vers Cloud Storage dans un scénario de migration simple

Vous devez procéder comme suit pour envoyer des requêtes à Cloud Storage :

  • Définissez un projet Google Cloud par défaut.
  • Obtenez une clé HMAC (Hash-based Message Authentication Code).
  • Effectuez les modifications suivantes dans vos outils ou bibliothèques existants :

    • Modifiez le point de terminaison de la requête pour utiliser le point de terminaison de requête de l'API XML pour Cloud Storage.
    • Remplacez la clé secrète et la clé d'accès d'Amazon Web Services (AWS) par l'ID d'accès et le secret correspondants de Cloud Storage (désignés par le terme unique "votre clé HMAC Cloud Storage").
    • Assurez-vous que vos en-têtes x-amz- utilisent des valeurs autorisées par Cloud Storage. Par exemple, x-amz-storage-class doit utiliser l'une des classes de stockage Cloud Storage disponibles.

      Lorsque vous utilisez l'API XML de Cloud Storage dans un scénario de migration simple, spécifier l'identifiant de signature AWS dans l'en-tête Authorization informe Cloud Storage de l'utilisation des en-têtes x-amz-* et de la syntaxe XML LCA d'Amazon S3 dans votre requête. Cloud Storage traite les en-têtes x-amz-* qui possèdent un équivalent x-goog-*, tels que ceux listés dans le tableau d'en-têtes.

Une fois ces modifications effectuées, vous pouvez commencer à utiliser vos outils et bibliothèques existants pour envoyer des requêtes HMAC à Cloud Storage.

Les exemples suivants montrent comment répertorier les buckets Cloud Storage à l'aide du SDK Amazon S3 :

Go

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage Go.

Pour vous authentifier auprès de Cloud Storage, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement 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

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage Java.

Pour vous authentifier auprès de Cloud Storage, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement 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

Pour en savoir plus, consultez la documentation de référence de l'API Cloud Storage en langage Python.

Pour vous authentifier auprès de Cloud Storage, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement 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

Définir un projet par défaut

Pour utiliser Cloud Storage dans un scénario de migration simple, il est recommandé de définir un projet par défaut, que Cloud Storage utilise pour effectuer certaines opérations, comme le service GET ou le bucket PUT. Si vous ne configurez pas de projet par défaut, vous devez spécifier un en-tête de projet dans certaines requêtes.

Pour définir un projet par défaut, procédez comme suit :

  1. Ouvrez la page Paramètres Cloud Storage dans Google Cloud Console.
  2. Sélectionnez l'onglet Interopérabilité.
  3. Cliquez sur Définir PROJECT-ID comme projet par défaut dans la section Projet par défaut pour l'accès interopérable.

    Si le projet est déjà le projet par défaut, le message PROJECT-ID est votre projet par défaut pour l'accès interopérable s'affiche.

Ce projet est maintenant défini comme votre projet par défaut. Vous pouvez modifier votre projet par défaut à tout moment en choisissant un projet différent et en suivant les instructions ci-dessous.

Vous pouvez également spécifier un en-tête de projet

Au lieu ou en plus de définir un projet par défaut, vous pouvez utiliser l'en-tête x-amz-project-id dans chaque requête nécessitant de spécifier un projet.

  • Une requête dont l'en-tête est défini sur x-amz-project-id utilise le projet spécifié dans cet en-tête, même s'il existe un projet par défaut.

L'en-tête x-amz-project-id est utile dans les cas suivants :

  • Vous utilisez plusieurs projets.
  • Vos requêtes sont effectuées par un compte de service associé à un autre projet, car les comptes de service utilisent leur projet parent comme projet par défaut.

Notez qu'Amazon S3 n'inclut pas de projets. Par conséquent, vous ne pouvez pas spécifier un en-tête x-amz-project-id selon les outils ou les bibliothèques clientes que vous utilisez. Dans ce cas, vous devez définir un projet par défaut.

Utiliser des clés HMAC

Pour utiliser l'API XML de Cloud Storage dans un scénario de migration simple, vous devez utiliser les clés HMAC (Hash-based Message Authentication Code) en tant qu'identifiants. En règle générale, vous devez créer une clé HMAC associée à un compte de service, mais vous pouvez également en utiliser une associée à un compte utilisateur.

S'authentifier dans un scénario de migration simple

Utiliser l'en-tête "Authorization"

Pour les opérations nécessitant une authentification dans le cadre d'un scénario de migration simple, vous devez inclure un en-tête de requête Authorization comme vous le feriez pour les requêtes adressées à Amazon S3. La syntaxe de l'en-tête Authorization pour une requête Amazon S3 est la suivante :

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

Dans un scénario de migration simple, vous modifiez uniquement l'en-tête pour utiliser votre ID d'accès HMAC Cloud Storage et vous vous assurez que la Signature qui y est jointe est bien calculée avec votre clé secrète HMAC Cloud Storage :

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

L'en-tête Authorization comporte les parties suivantes :

  • ALGORITHM : l'algorithme de signature et la version dont vous vous servez. L'utilisation de AWS4-HMAC-SHA256 indique que vous utilisez une signature HMAC V4 et que vous avez l'intention d'envoyer des en-têtes x-amz-*. Vous pouvez également vous servir de GOOG4-HMAC-SHA256, ce qui indiquerait que vous utilisez une signature HMAC V4 et que vous avez l'intention d'envoyer des en-têtes x-goog-*.

  • GOOG-ACCESS-ID : l'ID d'accès identifie l'entité qui émet et signe la requête. Dans une migration simple, remplacez l'ID de clé d'accès Amazon Web Service (AWS) que vous utilisez pour accéder à Amazon S3 par votre ID d'accès HMAC Cloud Storage. Votre ID d'accès HMAC Cloud Storage commence par GOOG.

  • CREDENTIAL_SCOPE : champ d'application des identifiants, tel que défini dans la signature. Dans le cadre d'une migration simple, vous n'avez pas besoin de modifier le champ d'application des identifiants si vous utilisez AWS4-HMAC-SHA256 comme valeur pour ALGORITHM.

  • SIGNED_HEADERS : liste des noms des en-têtes, séparés par des points-virgules, devant être inclus pour signer cette requête. Tous les en-têtes doivent être en lettres minuscules et triés par code de caractère.

    Voici un exemple de chaîne d'en-têtes signée de style Amazon S3 :

    content-type;host;x-amz-date

    Dans une migration simple, vous n'avez pas besoin de modifier la chaîne d'en-têtes signée.

  • SIGNATURE : signature permettant d'authentifier la requête. Dans une migration simple, remplacez les informations de la clé d'accès AWS par les informations de la clé HMAC Cloud Storage équivalentes.

Exemple de requête d'authentification

Les exemples suivants permettent d'importer un objet nommé /europe/france/paris.jpg dans un bucket nommé my-travel-maps, d'appliquer la LCA prédéfinie public-read et de définir un en-tête de métadonnées personnalisé pour les examinateurs. Voici la requête pour un bucket dans 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

Voici la requête pour un bucket dans 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

Voici la requête canonique correspondante ayant été créée pour cette requête :

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

Voici la chaîne de caractères à signer correspondante ayant été créée pour cette requête :

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

Cette requête n'ayant pas fourni d'en-tête Content-MD5, une chaîne vide est affichée dans le message (deuxième ligne).

Contrôle des accès dans un scénario de migration simple

Pour être compatible avec les migrations simples, Cloud Storage accepte les LCA produites par Amazon S3. Dans un scénario de migration simple, vous utiliserez AWS comme identifiant de signature indiquant à Cloud Storage de s'attendre à une syntaxe LCA utilisant la syntaxe XML de la LCA d'Amazon S3. Vous devez vous assurer que les LCA d'Amazon S3 que vous utilisez sont mappées sur le modèle LCA de Cloud Storage. Par exemple, si vos outils et bibliothèques utilisent la syntaxe LCA d'Amazon S3 pour accorder une autorisation de bucket WRITE, ils doivent également octroyer une autorisation de bucket READ, car les autorisations de Cloud Storage sont concentriques. Il n'est pas nécessaire de spécifier à la fois les autorisations WRITE et READ lorsque vous accordez l'autorisation WRITE à l'aide de la syntaxe de Cloud Storage.

Cloud Storage est compatible avec la syntaxe LCA d'Amazon S3 dans les scénarios suivants :

  • En cas de requête adressée à Cloud Storage pour récupérer des LCA (par exemple, une requête "GET Object" ou "GET Bucket"), Cloud Storage renvoie la syntaxe LCA d'Amazon S3.
  • En cas de requête adressée à Cloud Storage pour appliquer des LCA (par exemple, une requête "PUT Object" ou "PUT Bucket"), Cloud Storage s'attend à recevoir la syntaxe LCA d'Amazon S3.

Dans un scénario de migration simple, l'en-tête Authorization utilisera AWS comme identifiant de signature, mais avec votre ID d'accès Google.

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

L'exemple suivant est une requête GET adressée à Cloud Storage pour renvoyer les LCA à un objet.

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 réponse à la requête inclut la LCA utilisant la syntaxe d'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>

L'exemple suivant est une requête PUT adressée à Cloud Storage pour définir les LCA sur un objet. L'exemple montre un corps de requête avec la syntaxe LCA d'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>

Enfin, dans un scénario de migration simple, vous pouvez également utiliser l'identifiant de signature GOOG1 dans l'en-tête Authorization. Dans ce cas, vous devez utiliser la syntaxe LCA de Cloud Storage et vous assurer que tous vos en-têtes x-amz-* sont remplacés par x-goog-*. Bien que cela soit une possibilité, nous vous recommandons de choisir une migration complète afin de profiter de tous les avantages de Cloud Storage.

Compatibilité de l'API XML avec Amazon S3

Pour plus d'informations sur l'interopérabilité des API XML, consultez les discussions marquées par la balise google-cloud-storage sur Stack Overflow.

Étapes suivantes