Déplacer une instance de VM entre plusieurs zones ou régions


Ce document explique comment déplacer une instance de machine virtuelle (VM) entre des zones ou des régions.

Avant de commencer

  • Consultez la documentation sur les zones.
  • Configurez l'authentification.

    Sélectionnez l'onglet correspondant à la façon dont vous prévoyez d'utiliser les exemples de cette page :

    gcloud

    1. Installez Google Cloud CLI, puis initialisez-la en exécutant la commande suivante :

      gcloud init
    2. Définissez une région et une zone par défaut.

    Go

    Pour utiliser les exemples Go de cette page dans un environnement de développement local, installez et initialisez gcloud CLI, puis configurez le service Identifiants par défaut de l'application à l'aide de vos identifiants utilisateur.

    1. Installez Google Cloud CLI.
    2. Pour initialiser gcloudCLI, exécutez la commande suivante :

      gcloud init
    3. Créez des identifiants d'authentification locaux pour votre compte Google :

      gcloud auth application-default login

    Pour en savoir plus, consultez les sections sur Configurer l'authentification pour un environnement de développement local.

    Java

    Pour utiliser les exemples Java de cette page dans un environnement de développement local, installez et initialisez gcloud CLI, puis configurez le service Identifiants par défaut de l'application à l'aide de vos identifiants utilisateur.

    1. Installez Google Cloud CLI.
    2. Pour initialiser gcloudCLI, exécutez la commande suivante :

      gcloud init
    3. Créez des identifiants d'authentification locaux pour votre compte Google :

      gcloud auth application-default login

    Pour en savoir plus, consultez les sections sur Configurer l'authentification pour un environnement de développement local.

    Node.js

    Pour utiliser les exemples Node.js de cette page dans un environnement de développement local, installez et initialisez gcloud CLI, puis configurez le service Identifiants par défaut de l'application à l'aide de vos identifiants utilisateur.

    1. Installez Google Cloud CLI.
    2. Pour initialiser gcloudCLI, exécutez la commande suivante :

      gcloud init
    3. Créez des identifiants d'authentification locaux pour votre compte Google :

      gcloud auth application-default login

    Pour en savoir plus, consultez les sections sur Configurer l'authentification pour un environnement de développement local.

    Python

    Pour utiliser les exemples Python de cette page dans un environnement de développement local, installez et initialisez gcloud CLI, puis configurez le service Identifiants par défaut de l'application à l'aide de vos identifiants utilisateur.

    1. Installez Google Cloud CLI.
    2. Pour initialiser gcloudCLI, exécutez la commande suivante :

      gcloud init
    3. Créez des identifiants d'authentification locaux pour votre compte Google :

      gcloud auth application-default login

    Pour en savoir plus, consultez les sections sur Configurer l'authentification pour un environnement de développement local.

Conditions requises

Cette section répertorie les exigences pour déplacer une VM entre des zones et des régions :

  • Quota du projet. Votre projet doit disposer d'un quota suffisant pour effectuer les opérations suivantes :

    • Créer des instantanés.
    • Convertir les adresses IP externes éphémères.
    • Créer des VM et des disques dans la région de destination.

      Par exemple, si la VM que vous souhaitez déplacer est associée à trois disques, vous devez disposer d'un quota suffisant pour pouvoir créer trois instantanés de disque persistant temporaires et trois disques. Après avoir créé vos disques, vous pouvez supprimer vos instantanés temporaires.

    Consultez la page Quotas pour vous assurer que vous disposez d'un quota suffisant pour les ressources précédentes. Pour en savoir plus, consultez la page Comprendre les quotas.

  • Disques persistants. Les disques persistants associés à la VM que vous souhaitez déplacer ne sont pas associés à d'autres VM.

  • Disques SSD locaux. Les disques SSD locaux sont destinés au stockage temporaire. Les données stockées sur ces disques ne sont pas conservées lorsque vous arrêtez manuellement une VM. Si vous devez conserver les données présentes sur des disques SSD locaux, répliquez-les à l'aide d'une option de stockage durable (telle que des disques persistants).

  • GPU. Si votre VM comprend des GPU, vérifiez que ceux que vous souhaitez utiliser sont disponibles dans la zone de destination de la VM. Pour obtenir la liste des GPU et des zones dans lesquelles ils sont disponibles, consultez la section GPU sur Compute Engine.

  • Sous-réseau. Si vous souhaitez déplacer votre VM entre des régions (par exemple, entre us-west1-a et asia-south1-b) et que votre VM appartient à un sous-réseau, vous devez sélectionner un nouveau sous-réseau pour votre VM. Pour obtenir des instructions sur la création de sous-réseaux, consultez la section Ajouter des sous-réseaux.

Limite

Si vous déplacez une VM d'une région à une autre, vous ne pouvez pas conserver son adresse IP interne ou externe éphémère. Vous devez choisir une nouvelle adresse IP lors de la recréation de la VM.

Propriétés de la ressource

Pour déplacer votre VM, vous devez l'arrêter, la déplacer vers la zone ou la région de destination, puis la redémarrer. Après avoir déplacé votre VM, mettez à jour les références à votre ressource d'origine, telles que les VM ou les pools cibles qui pointent vers la VM précédente.

Pendant le déplacement, certaines propriétés générées par le serveur associées à votre VM et à vos disques changent.

Propriétés modifiées pour les VM

Le tableau suivant décrit les propriétés qui changent pour les VM :

Nom de propriété Modifications
Adresse IP interne Une nouvelle adresse IP interne est généralement attribuée, mais il est possible que la VM conserve son adresse IP interne d'origine.
Adresse IP externe Si vous déplacez la VM entre plusieurs zones au sein de la même région, l'adresse IP externe reste la même. Dans le cas contraire, choisissez une adresse IP différente pour l'instance de VM.
Plate-forme du processeur Selon la plate-forme de processeur disponible dans votre zone de destination, votre VM peut disposer d'une plate-forme différente après son déplacement. Pour obtenir la liste complète des plates-formes de processeur disponibles dans chaque zone, consultez la section Régions et zones disponibles.
Réseau/Sous-réseau Si votre VM appartient à un sous-réseau et que vous la déplacez vers une autre région, vous devez choisir un nouveau sous-réseau pour votre VM. Si vous déplacez une VM vers une zone de la même région, celle-ci conserve son sous-réseau.

Propriétés modifiées pour les disques

Le tableau suivant décrit les propriétés modifiées pour les disques :

Nom de propriété Modifications
Instantané source L'instantané source du nouveau disque est remplacé par l'instantané temporaire créé pendant le déplacement.
ID de l'instantané source L'ID de l'instantané source est remplacé par l'ID de l'instantané temporaire.
Image source Le champ d'image source est vide.
ID de l'image L'ID de l'image est vide.
Dernier horodatage de dissociation Le dernier horodatage de dissociation est vide.
Dernier horodatage d'association Le dernier horodatage d'association est défini sur l'horodatage lié à l'association du nouveau disque à la nouvelle instance.

Propriétés modifiées pour les VM et les disques

Le tableau suivant décrit les propriétés modifiées pour les VM et les disques :

Nom de propriété Modifications
ID Un nouvel ID de ressource est généré.
Horodatage de création Un nouvel horodatage de création est généré.
URL des ressources de la zone Toutes les URL des ressources de la zone sont modifiées pour correspondre à la zone de destination. La liste suivante indique les URL de ressources modifiées :
  • L'URL du disque source d'une VM
  • L'URL du type de machine d'une VM
  • Les URL des liens auto
  • Les URL de zone
  • Les URL de type de disque
  • Toutes les URL des VM répertoriées dans la liste users[] d'un disque

Déplacer une VM entre des zones ou des régions

Pour déplacer une VM d'une zone ou d'une région à une autre, procédez comme suit :

  1. Créez une image système de votre VM source.
  2. Créez une VM à partir de l'image système dans une zone ou une région différente.

Les exemples suivants montrent comment déplacer une VM entre des zones.

gcloud

Dans cet exemple, vous déplacez une VM nommée myinstance qui comporte deux disques persistants nommés mybootdisk et mydatadisk, de europe-west1-c à us-west1-b.

  1. Identifiez les disques associés à VM que vous souhaitez déplacer :

    gcloud compute instances describe myinstance --format="list(name,status,disks)"
    

    Dans cet exemple, les deux disques suivants sont associés à la VM myinstance :

    • Un disque de démarrage appelé mybootdisk
    • Un disque de données appelé mydatadisk
  2. Définissez l'état de suppression automatique de mybootdisk et de mydatadisk sur false, pour vous assurer de conserver les disques lors de la suppression de la VM.

    gcloud compute instances set-disk-auto-delete myinstance --zone europe-west1-c \
        --disk mybootdisk --no-auto-delete

    Si l'état de suppression automatique a bien été mis à jour, gcloud compute renvoie la réponse Updated [...]. S'il était déjà défini sur "false", gcloud compute renvoie la réponse suivante :

    No change requested; skipping update for [myinstance].
  3. (Facultatif) Enregistrez vos métadonnées de VM.

    Lorsque vous supprimez votre VM, les métadonnées de la VM sont également effacées. Vous pouvez sauvegarder ces informations dans un fichier distinct, puis réutiliser les métadonnées dans la nouvelle VM.

    Décrivez les métadonnées de votre VM en exécutant la commande suivante :

    gcloud compute instances describe myinstance --zone europe-west1-c

    Enregistrez le contenu dans un fichier séparé.

  4. Créez des sauvegardes de vos données à l'aide d'instantanés de disque persistant.

    Par précaution, sauvegardez vos données pendant que les disques persistants sont associés à la VM, en utilisant des instantanés de disque persistant. Avant de prendre un instantané, assurez-vous qu'il est cohérent avec l'état du disque persistant en respectant les bonnes pratiques concernant les instantanés.

    Après avoir effacé les tampons de votre disque, créez les instantanés :

    gcloud compute disks snapshot mybootdisk mydatadisk \
        --snapshot-names backup-mybootsnapshot,backup-mydatasnapshot \
        --zone europe-west1-c 

    Pour vérifier que l'instantané a bien été créé, exécutez la commande gcloud compute snapshots list.

  5. (Facultatif) Si vous déplacez une VM entre des zones de la même région et que vous souhaitez conserver son adresse IP interne ou externe éphémère, convertissez l'instance interne ou une adresse IP externe vers une adresse IP statique que vous pouvez réutiliser ultérieurement.

  6. Supprimez votre VM.

    La suppression de votre VM l'arrête correctement et dissocie tous les disques persistants.

    gcloud compute instances delete myinstance --zone europe-west1-c

    gcloud vous invite à confirmer la suppression :

    
    The following VMs are deleted. Any attached disks configured to
    be auto-deleted are deleted unless they are attached to any other
    VMs or the `--keep-disks` flag is given and specifies them for keeping.
    Deleting a disk is irreversible and any data on the disk is lost.
    — [myinstance] in [europe-west1-c]
    

    Do you want to continue (Y/n)?

    Comme vous avez précédemment désactivé l'état de suppression automatique des disques, appuyez sur Y pour ignorer l'avertissement et continuer.

  7. Créez ensuite un autre instantané du disque de démarrage et du disque de données.

    gcloud compute disks snapshot mybootdisk mydatadisk \
        --snapshot-names mybootsnapshot,mydatasnapshot \
        --zone europe-west1-c 
    Created [.../mydatasnapshot].
    Created [.../mybootsnapshot].
  8. (Facultatif) Supprimez vos disques persistants.

    Si vous prévoyez de réutiliser les noms des disques persistants pour les nouveaux disques, vous devez supprimer les disques existants afin de libérer les noms. Cette suppression permet également de réduire les coûts de stockage sur disque persistant.

    Si vous n'envisagez pas de réutiliser les mêmes noms de disques, il n'est pas nécessaire de les supprimer.

    gcloud compute disks delete mybootdisk mydatadisk --zone europe-west1-c
  9. Créez des disques persistants dans us-west1-b à partir des instantanés que vous avez créés. Commencez par créer le disque de démarrage.

    gcloud compute disks create mybootdiskb --source-snapshot mybootsnapshot \
        --zone us-west1-b
    Created [.../mybootdiskb].
    NAME        ZONE           SIZE_GB TYPE        STATUS
    mybootdiskb us-west1-b     100     pd-standard READY

    Créez ensuite le disque de données.

    gcloud compute disks create mydatadiskb --source-snapshot mydatasnapshot \
        --zone us-west1-b
    Created [.../mydatadiskb].
    NAME        ZONE           SIZE_GB TYPE        STATUS
    mydatadiskb us-west1-b 4000    pd-standard READY
  10. Recréez votre VM dans us-west1-b.

    • Si vous avez choisi d'enregistrer vos métadonnées de VM dans un fichier (par exemple, myinstance.describe), vous pouvez l'exploiter pour définir les mêmes métadonnées sur votre VM.

    • Si votre VM possédait une adresse IP externe statique, vous pouvez la réattribuer à votre nouvelle VM en spécifiant l'option --address [ADDRESS]. Si vous déplacez une VM d'une région à une autre, vous devez choisir une adresse IP externe différente pour la nouvelle instance de VM.

    • Si votre VM possédait une adresse IP interne statique, vous pouvez la réattribuer à votre nouvelle VM en spécifiant l'option --private-network-ip ADDRESS. Si vous déplacez une VM d'une région à une autre, vous devez choisir une adresse IP interne différente pour la nouvelle instance de VM.

    • Si votre VM incluait des GPU, ajoutez des GPU à la VM à l'aide de l'option --accelerator.

    • Si la VM utilise un sous-réseau spécifique, ajoutez l'option --subnet [SUBNET_NAME].

    Pour obtenir la liste complète des indicateurs supplémentaires, consultez la page concernant gcloud compute instances create.

    gcloud compute instances create myinstanceb --machine-type n1-standard-4 \
        --zone us-west1-b \
        --disk name=mybootdiskb,boot=yes,mode=rw \
        --disk name=mydatadiskb,mode=rw 
    Created [.../myinstanceb].
    NAME        ZONE           MACHINE_TYPE  INTERNAL_IP    EXTERNAL_IP     STATUS
    myinstanceb us-west1-b     n1-standard-4 10.240.173.229 146.148.112.106 RUNNING
  11. (Facultatif) Supprimez vos instantanés de disque persistant.

    Après avoir confirmé le déplacement de vos machines virtuelles, supprimez les instantanés temporaires que vous avez créés afin de réduire les coûts de stockage.

    gcloud compute snapshots delete mybootsnapshot mydatasnapshot

    Si vous n'avez plus besoin de vos instantanés de sauvegarde, supprimez-les également :

    gcloud compute snapshots delete backup-mybootsnapshot backup-mydatasnapshot

Go

  1. Obtenez des informations sur la VM et identifiez les disques qui lui sont associés.

    import (
    	"context"
    	"fmt"
    	"io"
    
    	compute "cloud.google.com/go/compute/apiv1"
    	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
    )
    
    // getInstance prints a name of a VM instance in the given zone in the specified project.
    func getInstance(w io.Writer, projectID, zone, instanceName string) error {
    	// projectID := "your_project_id"
    	// zone := "europe-central2-b"
    	// instanceName := "your_instance_name"
    
    	ctx := context.Background()
    	instancesClient, err := compute.NewInstancesRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewInstancesRESTClient: %w", err)
    	}
    	defer instancesClient.Close()
    
    	reqInstance := &computepb.GetInstanceRequest{
    		Project:  projectID,
    		Zone:     zone,
    		Instance: instanceName,
    	}
    
    	instance, err := instancesClient.Get(ctx, reqInstance)
    	if err != nil {
    		return fmt.Errorf("unable to get instance: %w", err)
    	}
    
    	fmt.Fprintf(w, "Instance: %s\n", instance.GetName())
    
    	return nil
    }
    
  2. Définissez l'état de suppression automatique du disque de démarrage et du disque de données sur false pour vous assurer de conserver les disques lors de la suppression de la VM.

    import (
    	"context"
    	"fmt"
    	"io"
    
    	compute "cloud.google.com/go/compute/apiv1"
    	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
    )
    
    // setDiskAutodelete sets the autodelete flag of a disk to given value.
    func setDiskAutoDelete(
    	w io.Writer,
    	projectID, zone, instanceName, diskName string, autoDelete bool,
    ) error {
    	// projectID := "your_project_id"
    	// zone := "us-west3-b"
    	// instanceName := "your_instance_name"
    	// diskName := "your_disk_name"
    	// autoDelete := true
    
    	ctx := context.Background()
    	instancesClient, err := compute.NewInstancesRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewInstancesRESTClient: %w", err)
    	}
    	defer instancesClient.Close()
    
    	getInstanceReq := &computepb.GetInstanceRequest{
    		Project:  projectID,
    		Zone:     zone,
    		Instance: instanceName,
    	}
    
    	instance, err := instancesClient.Get(ctx, getInstanceReq)
    	if err != nil {
    		return fmt.Errorf("unable to get instance: %w", err)
    	}
    
    	diskExists := false
    
    	for _, disk := range instance.GetDisks() {
    		if disk.GetDeviceName() == diskName {
    			diskExists = true
    			break
    		}
    	}
    
    	if !diskExists {
    		return fmt.Errorf(
    			"instance %s doesn't have a disk named %s attached",
    			instanceName,
    			diskName,
    		)
    	}
    
    	req := &computepb.SetDiskAutoDeleteInstanceRequest{
    		Project:    projectID,
    		Zone:       zone,
    		Instance:   instanceName,
    		DeviceName: diskName,
    		AutoDelete: autoDelete,
    	}
    
    	op, err := instancesClient.SetDiskAutoDelete(ctx, req)
    	if err != nil {
    		return fmt.Errorf("unable to set disk autodelete field: %w", err)
    	}
    
    	if err = op.Wait(ctx); err != nil {
    		return fmt.Errorf("unable to wait for the operation: %w", err)
    	}
    
    	fmt.Fprintf(w, "disk autoDelete field updated.\n")
    
    	return nil
    }
    
  3. Créez des sauvegardes de vos données à l'aide d'instantanés de disque persistant.

    Par précaution, sauvegardez vos données pendant que les disques persistants sont associés à la VM, en utilisant des instantanés de disque persistant. Avant de prendre un instantané, assurez-vous qu'il est cohérent avec l'état du disque persistant en respectant les bonnes pratiques concernant les instantanés.

    Après avoir effacé les tampons de votre disque, créez les instantanés :

    import (
    	"context"
    	"fmt"
    	"io"
    
    	compute "cloud.google.com/go/compute/apiv1"
    	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
    	"google.golang.org/protobuf/proto"
    )
    
    // createSnapshot creates a snapshot of a disk.
    func createSnapshot(
    	w io.Writer,
    	projectID, diskName, snapshotName, zone, region, location, diskProjectID string,
    ) error {
    	// projectID := "your_project_id"
    	// diskName := "your_disk_name"
    	// snapshotName := "your_snapshot_name"
    	// zone := "europe-central2-b"
    	// region := "eupore-central2"
    	// location = "eupore-central2"
    	// diskProjectID = "YOUR_DISK_PROJECT_ID"
    
    	ctx := context.Background()
    
    	snapshotsClient, err := compute.NewSnapshotsRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewSnapshotsRESTClient: %w", err)
    	}
    	defer snapshotsClient.Close()
    
    	if zone == "" && region == "" {
    		return fmt.Errorf("you need to specify `zone` or `region` for this function to work")
    	}
    
    	if zone != "" && region != "" {
    		return fmt.Errorf("you can't set both `zone` and `region` parameters")
    	}
    
    	if diskProjectID == "" {
    		diskProjectID = projectID
    	}
    
    	disk := &computepb.Disk{}
    	locations := []string{}
    	if location != "" {
    		locations = append(locations, location)
    	}
    
    	if zone != "" {
    		disksClient, err := compute.NewDisksRESTClient(ctx)
    		if err != nil {
    			return fmt.Errorf("NewDisksRESTClient: %w", err)
    		}
    		defer disksClient.Close()
    
    		getDiskReq := &computepb.GetDiskRequest{
    			Project: projectID,
    			Zone:    zone,
    			Disk:    diskName,
    		}
    
    		disk, err = disksClient.Get(ctx, getDiskReq)
    		if err != nil {
    			return fmt.Errorf("unable to get disk: %w", err)
    		}
    	} else {
    		regionDisksClient, err := compute.NewRegionDisksRESTClient(ctx)
    		if err != nil {
    			return fmt.Errorf("NewRegionDisksRESTClient: %w", err)
    		}
    		defer regionDisksClient.Close()
    
    		getDiskReq := &computepb.GetRegionDiskRequest{
    			Project: projectID,
    			Region:  region,
    			Disk:    diskName,
    		}
    
    		disk, err = regionDisksClient.Get(ctx, getDiskReq)
    		if err != nil {
    			return fmt.Errorf("unable to get disk: %w", err)
    		}
    	}
    
    	req := &computepb.InsertSnapshotRequest{
    		Project: projectID,
    		SnapshotResource: &computepb.Snapshot{
    			Name:             proto.String(snapshotName),
    			SourceDisk:       proto.String(disk.GetSelfLink()),
    			StorageLocations: locations,
    		},
    	}
    
    	op, err := snapshotsClient.Insert(ctx, req)
    	if err != nil {
    		return fmt.Errorf("unable to create snapshot: %w", err)
    	}
    
    	if err = op.Wait(ctx); err != nil {
    		return fmt.Errorf("unable to wait for the operation: %w", err)
    	}
    
    	fmt.Fprintf(w, "Snapshot created\n")
    
    	return nil
    }
    
  4. Supprimez votre VM de la zone source.

    import (
    	"context"
    	"fmt"
    	"io"
    
    	compute "cloud.google.com/go/compute/apiv1"
    	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
    )
    
    // deleteInstance sends a delete request to the Compute Engine API and waits for it to complete.
    func deleteInstance(w io.Writer, projectID, zone, instanceName string) error {
    	// projectID := "your_project_id"
    	// zone := "europe-central2-b"
    	// instanceName := "your_instance_name"
    	ctx := context.Background()
    	instancesClient, err := compute.NewInstancesRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewInstancesRESTClient: %w", err)
    	}
    	defer instancesClient.Close()
    
    	req := &computepb.DeleteInstanceRequest{
    		Project:  projectID,
    		Zone:     zone,
    		Instance: instanceName,
    	}
    
    	op, err := instancesClient.Delete(ctx, req)
    	if err != nil {
    		return fmt.Errorf("unable to delete instance: %w", err)
    	}
    
    	if err = op.Wait(ctx); err != nil {
    		return fmt.Errorf("unable to wait for the operation: %w", err)
    	}
    
    	fmt.Fprintf(w, "Instance deleted\n")
    
    	return nil
    }
    
  5. Créez ensuite un autre instantané du disque de démarrage et du disque de données.

    import (
    	"context"
    	"fmt"
    	"io"
    
    	compute "cloud.google.com/go/compute/apiv1"
    	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
    	"google.golang.org/protobuf/proto"
    )
    
    // createSnapshot creates a snapshot of a disk.
    func createSnapshot(
    	w io.Writer,
    	projectID, diskName, snapshotName, zone, region, location, diskProjectID string,
    ) error {
    	// projectID := "your_project_id"
    	// diskName := "your_disk_name"
    	// snapshotName := "your_snapshot_name"
    	// zone := "europe-central2-b"
    	// region := "eupore-central2"
    	// location = "eupore-central2"
    	// diskProjectID = "YOUR_DISK_PROJECT_ID"
    
    	ctx := context.Background()
    
    	snapshotsClient, err := compute.NewSnapshotsRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewSnapshotsRESTClient: %w", err)
    	}
    	defer snapshotsClient.Close()
    
    	if zone == "" && region == "" {
    		return fmt.Errorf("you need to specify `zone` or `region` for this function to work")
    	}
    
    	if zone != "" && region != "" {
    		return fmt.Errorf("you can't set both `zone` and `region` parameters")
    	}
    
    	if diskProjectID == "" {
    		diskProjectID = projectID
    	}
    
    	disk := &computepb.Disk{}
    	locations := []string{}
    	if location != "" {
    		locations = append(locations, location)
    	}
    
    	if zone != "" {
    		disksClient, err := compute.NewDisksRESTClient(ctx)
    		if err != nil {
    			return fmt.Errorf("NewDisksRESTClient: %w", err)
    		}
    		defer disksClient.Close()
    
    		getDiskReq := &computepb.GetDiskRequest{
    			Project: projectID,
    			Zone:    zone,
    			Disk:    diskName,
    		}
    
    		disk, err = disksClient.Get(ctx, getDiskReq)
    		if err != nil {
    			return fmt.Errorf("unable to get disk: %w", err)
    		}
    	} else {
    		regionDisksClient, err := compute.NewRegionDisksRESTClient(ctx)
    		if err != nil {
    			return fmt.Errorf("NewRegionDisksRESTClient: %w", err)
    		}
    		defer regionDisksClient.Close()
    
    		getDiskReq := &computepb.GetRegionDiskRequest{
    			Project: projectID,
    			Region:  region,
    			Disk:    diskName,
    		}
    
    		disk, err = regionDisksClient.Get(ctx, getDiskReq)
    		if err != nil {
    			return fmt.Errorf("unable to get disk: %w", err)
    		}
    	}
    
    	req := &computepb.InsertSnapshotRequest{
    		Project: projectID,
    		SnapshotResource: &computepb.Snapshot{
    			Name:             proto.String(snapshotName),
    			SourceDisk:       proto.String(disk.GetSelfLink()),
    			StorageLocations: locations,
    		},
    	}
    
    	op, err := snapshotsClient.Insert(ctx, req)
    	if err != nil {
    		return fmt.Errorf("unable to create snapshot: %w", err)
    	}
    
    	if err = op.Wait(ctx); err != nil {
    		return fmt.Errorf("unable to wait for the operation: %w", err)
    	}
    
    	fmt.Fprintf(w, "Snapshot created\n")
    
    	return nil
    }
    
  6. (Facultatif) Supprimez vos disques persistants.

    Si vous prévoyez de réutiliser les noms des disques persistants pour les nouveaux disques, vous devez supprimer les disques existants afin de libérer les noms. Cette suppression permet également de réduire les coûts de stockage sur disque persistant.

    Si vous n'envisagez pas de réutiliser les mêmes noms de disques, il n'est pas nécessaire de les supprimer.

    import (
    	"context"
    	"fmt"
    	"io"
    
    	compute "cloud.google.com/go/compute/apiv1"
    	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
    )
    
    // deleteDisk deletes a disk from a project.
    func deleteDisk(w io.Writer, projectID, zone, diskName string) error {
    	// projectID := "your_project_id"
    	// zone := "us-west3-b"
    	// diskName := "your_disk_name"
    
    	ctx := context.Background()
    	disksClient, err := compute.NewDisksRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewDisksRESTClient: %w", err)
    	}
    	defer disksClient.Close()
    
    	req := &computepb.DeleteDiskRequest{
    		Project: projectID,
    		Zone:    zone,
    		Disk:    diskName,
    	}
    
    	op, err := disksClient.Delete(ctx, req)
    	if err != nil {
    		return fmt.Errorf("unable to delete disk: %w", err)
    	}
    
    	if err = op.Wait(ctx); err != nil {
    		return fmt.Errorf("unable to wait for the operation: %w", err)
    	}
    
    	fmt.Fprintf(w, "Disk deleted\n")
    
    	return nil
    }
    
  7. Créez des disques persistants dans la zone de destination à partir des instantanés que vous avez créés. Commencez par créer le disque de démarrage, puis les disques de données.

    import (
    	"context"
    	"fmt"
    	"io"
    
    	compute "cloud.google.com/go/compute/apiv1"
    	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
    	"google.golang.org/protobuf/proto"
    )
    
    // createDiskFromSnapshot creates a new disk in a project in given zone.
    func createDiskFromSnapshot(
    	w io.Writer,
    	projectID, zone, diskName, diskType, snapshotLink string,
    	diskSizeGb int64,
    ) error {
    	// projectID := "your_project_id"
    	// zone := "us-west3-b" // should match diskType below
    	// diskName := "your_disk_name"
    	// diskType := "zones/us-west3-b/diskTypes/pd-ssd"
    	// snapshotLink := "projects/your_project_id/global/snapshots/snapshot_name"
    	// diskSizeGb := 120
    
    	ctx := context.Background()
    	disksClient, err := compute.NewDisksRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewDisksRESTClient: %w", err)
    	}
    	defer disksClient.Close()
    
    	req := &computepb.InsertDiskRequest{
    		Project: projectID,
    		Zone:    zone,
    		DiskResource: &computepb.Disk{
    			Name:           proto.String(diskName),
    			Zone:           proto.String(zone),
    			Type:           proto.String(diskType),
    			SourceSnapshot: proto.String(snapshotLink),
    			SizeGb:         proto.Int64(diskSizeGb),
    		},
    	}
    
    	op, err := disksClient.Insert(ctx, req)
    	if err != nil {
    		return fmt.Errorf("unable to create disk: %w", err)
    	}
    
    	if err = op.Wait(ctx); err != nil {
    		return fmt.Errorf("unable to wait for the operation: %w", err)
    	}
    
    	fmt.Fprintf(w, "Disk created\n")
    
    	return nil
    }
    
  8. Recréez votre VM avec les nouveaux disques dans la zone de destination.