Mover uma instância de VM entre zonas ou regiões


Neste documento, você verá como mover uma instância de máquina virtual (VM, na sigla em inglês) entre zonas ou regiões.

Antes de começar

  • Leia a documentação sobre zonas.
  • Configure a autenticação, caso ainda não tenha feito isso. A autenticação é o processo de verificação da sua identidade para acesso a serviços e APIs do Google Cloud. Para executar códigos ou amostras de um ambiente de desenvolvimento local, autentique-se no Compute Engine da seguinte maneira.

    Selecione a guia para como planeja usar as amostras nesta página:

    gcloud

    1. Instale a Google Cloud CLI e inicialize-a executando o seguinte comando:

      gcloud init
    2. Defina uma região e uma zona padrão.

    Go

    Para usar as amostras de Go nesta página de um ambiente de desenvolvimento local, instale e inicialize a CLI gcloud e, em seguida, configure o Application Default Credentials com as credenciais de usuário.

    1. Instale a CLI do Google Cloud.
    2. Para inicializar a CLI gcloud, execute o seguinte comando:

      gcloud init
    3. Crie as credenciais de autenticação para sua Conta do Google:

      gcloud auth application-default login

    Veja mais informações em: Configurar a autenticação para um ambiente de desenvolvimento local.

    Java

    Para usar as amostras de Java nesta página de um ambiente de desenvolvimento local, instale e inicialize a CLI gcloud e, em seguida, configure o Application Default Credentials com as credenciais de usuário.

    1. Instale a CLI do Google Cloud.
    2. Para inicializar a CLI gcloud, execute o seguinte comando:

      gcloud init
    3. Crie as credenciais de autenticação para sua Conta do Google:

      gcloud auth application-default login

    Veja mais informações em: Configurar a autenticação para um ambiente de desenvolvimento local.

    Node.js

    Para usar as amostras de Node.js nesta página de um ambiente de desenvolvimento local, instale e inicialize a CLI gcloud e, em seguida, configure o Application Default Credentials com as credenciais de usuário.

    1. Instale a CLI do Google Cloud.
    2. Para inicializar a CLI gcloud, execute o seguinte comando:

      gcloud init
    3. Crie as credenciais de autenticação para sua Conta do Google:

      gcloud auth application-default login

    Veja mais informações em: Configurar a autenticação para um ambiente de desenvolvimento local.

    Python

    Para usar as amostras de Python nesta página de um ambiente de desenvolvimento local, instale e inicialize a CLI gcloud e, em seguida, configure o Application Default Credentials com as credenciais de usuário.

    1. Instale a CLI do Google Cloud.
    2. Para inicializar a CLI gcloud, execute o seguinte comando:

      gcloud init
    3. Crie as credenciais de autenticação para sua Conta do Google:

      gcloud auth application-default login

    Veja mais informações em: Configurar a autenticação para um ambiente de desenvolvimento local.

Requisitos

Nesta seção, listamos os requisitos para mover uma VM entre zonas e regiões:

  • Cota do projeto. O projeto precisa ter cota suficiente para:

    • Criar novos snapshots.
    • Promover endereços IP externos temporários.
    • Crie novas VMs e discos na região de destino.

      Por exemplo, se você tiver três discos anexados à VM que pretende mover, é preciso ter cota suficiente para criar três snapshots temporários de discos permanentes e três novos discos. Depois de criar os novos discos, você pode excluir os snapshots temporários.

    Verifique a página Cotas para garantir que você tenha cota suficiente para os recursos anteriores. Para mais informações, consulte Noções básicas sobre cotas.

  • Discos permanentes. Os discos permanentes conectados à VM que você pretende mover não são anexados a outras VMs.

  • SSDs locais. Os SSDs locais são destinados ao armazenamento temporário, e os dados nos SSDs locais não são preservados após o encerramento manual das VMs. Se você precisar preservar dados do SSD local, replique-os usando uma opção de armazenamento durável, como discos permanentes.

  • GPUs. Se a VM incluir GPUs, verifique se as GPUs que você quer usar estão disponíveis na zona de destino da VM. Para uma lista de GPUs e zonas em que estão disponíveis, consulte GPUs no Compute Engine.

  • Subrede. Se você quiser mover sua VM entre regiões, como entre us-west1-a e asia-south1-b, e sua VM pertencer a uma sub-rede, selecione uma nova sub-rede para a VM. Para instruções sobre como criar sub-redes, consulte Como adicionar sub-redes.

Limitação

Se você mover uma VM entre regiões, não será possível preservar o endereço IP interno ou externo efêmero da VM. É preciso escolher um novo endereço IP ao recriar a instância.

Propriedades do recurso

Para mover sua VM, encerre-a, mova-a para a zona ou região de destino e depois reinicie-a. Depois de mover a instância, atualize as referências existentes ao recurso original, como VMs ou pools de destino que apontam para a VM antiga.

Durante a mudança, algumas propriedades da VM e dos discos geradas pelo servidor são alteradas.

Propriedades alteradas para VMs

A tabela a seguir descreve as propriedades que são alteradas para as VMs:

Nome da propriedade Alterações
Endereço IP interno Geralmente, é atribuído um novo endereço IP interno, mas é possível que a VM mantenha o endereço IP interno original.
Endereço IP externo Se a VM for movida entre zonas na mesma região, o endereço IP externo continuará igual. Caso contrário, escolha um endereço IP externo diferente para a instância da VM.
Plataforma de CPU Dependendo da plataforma de CPU disponível na zona de destino, a VM poderá ter uma plataforma de CPU diferente depois que ela for movida. Para ver uma lista completa de plataformas de CPU em cada zona, consulte Regiões e zonas disponíveis.
Rede/sub-rede Se você estiver movendo entre regiões uma VM que pertence a uma sub-rede, escolha uma nova sub-rede para ela. As VMs instâncias movidas entre zonas da mesma região mantêm a mesma sub-rede.

Propriedades alteradas dos discos

A tabela a seguir descreve as propriedades que mudam nos discos:

Nome da propriedade Alterações
Snapshot de origem O snapshot de origem do novo disco é definido como o snapshot temporário criado durante a movimentação.
ID do snapshot de origem A ID do snapshot da origem é definida como a ID do snapshot temporário.
Imagem de origem O campo de imagem de origem está vazio.
ID da imagem A ID da imagem está vazia.
Carimbo de data/hora da última desconexão O carimbo de data/hora da última desconexão está vazio.
Carimbo de data/hora da última conexão O carimbo de data/hora da última conexão é alterado para o momento em que o disco novo é conectado à nova instância.

Propriedades alteradas para VMs e discos

Na tabela a seguir, descrevemos as propriedades que mudam nas VMs e nos discos:

Nome da propriedade Alterações
ID Uma nova ID do recurso é gerada.
Carimbo de data/hora da criação Um novo carimbo de data/hora da criação é gerado.
URLs de recursos da zona Todos os URLs de recursos da zona são alterados para refletir a zona de destino. A lista a seguir mostra os URLs dos recursos que mudam:
  • URL do disco de origem da VM
  • URL do tipo de máquina da VM
  • URLs de self link
  • URLs de zonas
  • URLs de tipos de disco
  • Quaisquer URLs de VMs que estiverem na lista users[] de um disco

Mover uma VM entre zonas ou regiões

Para mover uma VM entre zonas ou regiões, faça o seguinte:

  1. Crie uma imagem da máquina da VM de origem.
  2. Crie uma VM a partir da imagem de máquina em uma zona ou região diferente.

Nos exemplos a seguir, mostramos como mover uma VM entre zonas.

gcloud

Neste exemplo, você move uma VM chamada myinstance que tem dois discos permanentes chamados mybootdisk E mydatadisk, de europe-west1-c para us-west1-b.

  1. Identifique os discos associados à VM que você quer mover.

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

    Neste exemplo, você encontrará os dois discos associados a seguir para a VM myinstance:

    • Um disco de inicialização chamado mybootdisk
    • Um disco de dados chamado mydatadisk
  2. Defina o estado de exclusão automática de mybootdisk e mydatadisk para false a fim de garantir que os discos não sejam excluídos automaticamente quando a VM for excluída.

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

    Se o estado foi atualizado, gcloud compute retorna a resposta Updated [...]. Se o estado de exclusão automática já tiver sido definido como falso, gcloud compute retornará:

    No change requested; skipping update for [myinstance].
  3. (Opcional) Salve os metadados da VM.

    Quando você exclui a VM, os metadados dela também são removidos. É possível salvar essas informações em um arquivo separado e reaplicar os metadados à nova VM.

    Descreva os metadados da VM da seguinte forma:

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

    Salve o conteúdo em um arquivo separado.

  4. Crie backups dos seus dados usando snapshots de discos permanentes.

    Como precaução, crie backups dos dados enquanto os discos permanentes ainda estiverem conectados à VM usando snapshots de discos permanentes. Antes de criar um snapshot, verifique se ele é consistente com o estado do disco permanente seguindo as práticas recomendadas de snapshot.

    Depois de limpar os buffers de disco, crie os snapshots:

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

    Para verificar se o snapshot foi criado, execute gcloud compute snapshots list.

  5. (Opcional) Se você estiver movendo uma VM entre zonas dentro da mesma região e quiser preservar o endereço IP temporário interno ou externo, promova o endereço IP interno ou externo para um endereço IP estático, que pode ser reutilizado mais tarde.

  6. Exclua a VM.

    A exclusão da VM a encerra corretamente e remove quaisquer discos permanentes.

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

    A gcloudgcloud solicita que você confirme a exclusão:

    
    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)?

    Como você desativou o estado de exclusão automática de discos anteriormente neste processo, digite Y para continuar e ignorar o aviso.

  7. Em seguida, crie outro instantâneo do disco de inicialização e do disco de dados.

    gcloud compute disks snapshot mybootdisk mydatadisk \
        --snapshot-names mybootsnapshot,mydatasnapshot \
        --zone europe-west1-c 
    Created [.../mydatasnapshot].
    Created [.../mybootsnapshot].
  8. (Opcional) Exclua os discos permanentes.

    Se você pretende usar os mesmos nomes dos discos permanentes nos novos discos, precisa excluir os discos atuais para liberar os nomes. A exclusão dos discos também economiza custos com armazenamento em disco permanente.

    Se você não planeja reutilizar os mesmos nomes de disco, não é necessário excluí-los.

    gcloud compute disks delete mybootdisk mydatadisk --zone europe-west1-c
  9. Criar novos discos permanentes em us-west1-b dos snapshots que você criou. Primeiro, crie o disco de inicialização.

    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

    Em seguida, crie o disco de dados.

    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. Recrie sua VM em us-west1-b.

    • Se você salvou os metadados da VM em um arquivo, como myinstance.describe, é possível usá-lo para definir os mesmos metadados na VM.

    • Se a VM tinha um endereço IP externo estático, é possível reatribuir esse endereço à nova VM especificando a opção --address [ADDRESS]. Se você estiver movendo uma VM entre regiões, precisará escolher um endereço IP externo diferente para a nova instância de VM.

    • Se a VM tinha um endereço IP interno estático, é possível reatribuir esse endereço à nova VM especificando a opção --private-network-ip ADDRESS. Se você estiver movendo uma VM entre regiões, precisará escolher um endereço interno IP diferente para a instância de VM.

    • Se a VM tinha GPUs, adicione GPUs a ela usando a opção --accelerator.

    • Se a VM usar uma sub-rede específica, adicione a sinalização --subnet [SUBNET_NAME].

    Para uma lista completa de sinalizações opcionais, consulte 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. (Opcional) Exclua os snapshots de discos permanentes.

    Depois de confirmar que suas máquinas virtuais foram movidas, exclua os instantâneos temporários que você criou para economizar nos custos de armazenamento.

    gcloud compute snapshots delete mybootsnapshot mydatasnapshot

    Se você não precisar mais dos seus instantâneos de backup, exclua-os também:

    gcloud compute snapshots delete backup-mybootsnapshot backup-mydatasnapshot

Go

  1. Encontre os detalhes da VM e identifique os discos anexados a ela.

    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. Defina o estado de exclusão automática do disco de inicialização e do disco de dados como false para garantir que os discos não sejam excluídos automaticamente quando a VM for excluída.

    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. Crie backups dos seus dados usando snapshots de discos permanentes.

    Como precaução, crie backups dos dados enquanto os discos permanentes ainda estiverem conectados à VM usando snapshots de discos permanentes. Antes de criar um snapshot, verifique se ele é consistente com o estado do disco permanente seguindo as práticas recomendadas de snapshot.

    Depois de limpar os buffers de disco, crie os snapshots:

    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. Exclua a VM dA zona de origem.

    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. Em seguida, crie outro instantâneo do disco de inicialização e do disco de dados.

    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. (Opcional) Exclua os discos permanentes.

    Se você pretende usar os mesmos nomes dos discos permanentes nos novos discos, precisa excluir os discos atuais para liberar os nomes. A exclusão dos discos também economiza custos com armazenamento em disco permanente.

    Se você não planeja reutilizar os mesmos nomes de disco, não é necessário excluí-los.

    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. Criar novos discos permanentes na zona de destino com base nos snapshots criados. Primeiro, crie o disco de inicialização e depois os discos de dados.

    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. Recrie a VM com os novos discos na zona de destino.

    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"
    )
    
    // createWithExistingDisks create a new VM instance using selected disks.
    // The first disk in diskNames will be used as boot disk.
    func createWithExistingDisks(
    	w io.Writer,
    	projectID, zone, instanceName string,
    	diskNames []string,
    ) error {
    	// projectID := "your_project_id"
    	// zone := "europe-central2-b"
    	// instanceName := "your_instance_name"
    	// diskNames := []string{"boot_disk", "disk1", "disk2"}
    
    	ctx := context.Background()
    	instancesClient, err := compute.NewInstancesRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewInstancesRESTClient: %w", err)
    	}
    	defer instancesClient.Close()
    
    	disksClient, err := compute.NewDisksRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewDisksRESTClient: %w", err)
    	}
    	defer disksClient.Close()
    
    	disks := [](*computepb.Disk){}
    
    	for _, diskName := range diskNames {
    		reqDisk := &computepb.GetDiskRequest{
    			Project: projectID,
    			Zone:    zone,
    			Disk:    diskName,
    		}
    
    		disk, err := disksClient.Get(ctx, reqDisk)
    		if err != nil {
    			return fmt.Errorf("unable to get disk: %w", err)
    		}
    
    		disks = append(disks, disk)
    	}
    
    	attachedDisks := [](*computepb.AttachedDisk){}
    
    	for _, disk := range disks {
    		attachedDisk := &computepb.AttachedDisk{
    			Source: proto.String(disk.GetSelfLink()),
    		}
    		attachedDisks = append(attachedDisks, attachedDisk)
    	}
    
    	attachedDisks[0].Boot = proto.Bool(true)
    
    	instanceResource := &computepb.Instance{
    		Name:        proto.String(instanceName),
    		Disks:       attachedDisks,
    		MachineType: proto.String(fmt.Sprintf("zones/%s/machineTypes/n1-standard-1", zone)),
    		NetworkInterfaces: []*computepb.NetworkInterface{
    			{
    				Name: proto.String("global/networks/default"),
    			},
    		},
    	}
    
    	req := &computepb.InsertInstanceRequest{
    		Project:          projectID,
    		Zone:             zone,
    		InstanceResource: instanceResource,
    	}
    
    	op, err := instancesClient.Insert(ctx, req)
    	if err != nil {
    		return fmt.Errorf("unable to create 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 created\n")
    
    	return nil
    }
    
  9. (Opcional) Excluir os snapshots de discos temporários. Depois de confirmar que suas máquinas virtuais foram movidas, exclua os snapshots temporários que você criou para economizar nos custos de armazenamento.

    import (
    	"context"
    	"fmt"
    	"io"
    
    	compute "cloud.google.com/go/compute/apiv1"
    	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
    )
    
    // deleteSnapshot deletes a snapshot of a disk.
    func deleteSnapshot(w io.Writer, projectID, snapshotName string) error {
    	// projectID := "your_project_id"
    	// snapshotName := "your_snapshot_name"
    
    	ctx := context.Background()
    	snapshotsClient, err := compute.NewSnapshotsRESTClient(ctx)
    	if err != nil {
    		return fmt.Errorf("NewSnapshotsRESTClient: %w", err)
    	}
    	defer snapshotsClient.Close()
    
    	req := &computepb.DeleteSnapshotRequest{
    		Project:  projectID,
    		Snapshot: snapshotName,
    	}
    
    	op, err := snapshotsClient.Delete(ctx, req)
    	if err != nil {
    		return fmt.Errorf("unable to delete 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 deleted\n")
    
    	return nil
    }
    

Java

  1. Encontre os detalhes da VM e identifique os discos anexados a ela.

    
    import com.google.cloud.compute.v1.Instance;
    import com.google.cloud.compute.v1.InstancesClient;
    import java.io.IOException;
    
    public class GetInstance {
    
      public static void main(String[] args) throws IOException {
        // TODO(developer): Replace these variables before running the sample.
    
        // Project ID or project number of the Cloud project you want to use.
        String projectId = "YOUR_PROJECT_ID";
    
        // Name of the zone you want to use. For example: 'us-west3-b'.
        String zone = "europe-central2-b";
    
        // Name of the VM instance you want to query.
        String instanceName = "YOUR_INSTANCE_NAME";
    
        getInstance(projectId, zone, instanceName);
      }
    
      // Prints information about a VM instance in the given zone in the specified project.
      public static void getInstance(String projectId, String zone, String instanceName)
          throws IOException {
    
        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests. After completing all of your requests, call
        // the `instancesClient.close()` method on the client to safely
        // clean up any remaining background resources.
        try (InstancesClient instancesClient = InstancesClient.create()) {
    
          Instance instance = instancesClient.get(projectId, zone, instanceName);
    
          System.out.printf("Retrieved the instance %s", instance.toString());
        }
      }
    }
  2. Defina o estado de exclusão automática do disco de inicialização e do disco de dados como false para garantir que os discos não sejam excluídos automaticamente quando a VM for excluída.

    
    import com.google.cloud.compute.v1.Instance;
    import com.google.cloud.compute.v1.InstancesClient;
    import com.google.cloud.compute.v1.Operation;
    import com.google.cloud.compute.v1.SetDiskAutoDeleteInstanceRequest;
    import java.io.IOException;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    public class SetDiskAutodelete {
    
      public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
        // TODO(developer): Replace these variables before running the sample.
    
        // Project ID or project number of the Cloud project you want to use.
        String projectId = "YOUR_PROJECT_ID";
    
        // The zone of the disk that you want to modify.
        String zone = "europe-central2-b";
    
        // Name of the instance the disk is attached to.
        String instanceName = "YOUR_INSTANCE_NAME";
    
        // The name of the disk for which you want to modify the autodelete flag.
        String diskName = "YOUR_DISK_NAME";
    
        // The new value of the autodelete flag.
        boolean autoDelete = true;
    
        setDiskAutodelete(projectId, zone, instanceName, diskName, autoDelete);
      }
    
      // Sets the autodelete flag of a disk to given value.
      public static void setDiskAutodelete(String projectId, String zone, String instanceName,
          String diskName, boolean autoDelete)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    
        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests. After completing all of your requests, call
        // the `instancesClient.close()` method on the client to safely
        // clean up any remaining background resources.
        try (InstancesClient instancesClient = InstancesClient.create()) {
    
          // Retrieve the instance given by the instanceName.
          Instance instance = instancesClient.get(projectId, zone, instanceName);
    
          // Check if the instance contains a disk that matches the given diskName.
          boolean diskNameMatch = instance.getDisksList()
              .stream()
              .anyMatch(disk -> disk.getDeviceName().equals(diskName));
    
          if (!diskNameMatch) {
            throw new Error(
                String.format("Instance %s doesn't have a disk named %s attached", instanceName,
                    diskName));
          }
    
          // Create the request object.
          SetDiskAutoDeleteInstanceRequest request = SetDiskAutoDeleteInstanceRequest.newBuilder()
              .setProject(projectId)
              .setZone(zone)
              .setInstance(instanceName)
              .setDeviceName(diskName)
              // Update the autodelete property.
              .setAutoDelete(autoDelete)
              .build();
    
          // Wait for the update instance operation to complete.
          Operation response = instancesClient.setDiskAutoDeleteAsync(request)
              .get(3, TimeUnit.MINUTES);
    
          if (response.hasError()) {
            System.out.println("Failed to update Disk autodelete field!" + response);
            return;
          }
          System.out.println(
              "Disk autodelete field updated. Operation Status: " + response.getStatus());
        }
      }
    }
  3. Crie backups dos seus dados usando snapshots de discos permanentes.

    Como precaução, crie backups dos dados enquanto os discos permanentes ainda estiverem conectados à VM usando snapshots de discos permanentes. Antes de criar um snapshot, verifique se ele é consistente com o estado do disco permanente seguindo as práticas recomendadas de snapshot.

    Depois de limpar os buffers de disco, crie os snapshots:

    
    import com.google.cloud.compute.v1.Disk;
    import com.google.cloud.compute.v1.DisksClient;
    import com.google.cloud.compute.v1.Operation;
    import com.google.cloud.compute.v1.RegionDisksClient;
    import com.google.cloud.compute.v1.Snapshot;
    import com.google.cloud.compute.v1.SnapshotsClient;
    import java.io.IOException;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    public class CreateSnapshot {
    
      public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
        // TODO(developer): Replace these variables before running the sample.
        // You need to pass `zone` or `region` parameter relevant to the disk you want to
        // snapshot, but not both. Pass `zone` parameter for zonal disks and `region` for
        // regional disks.
    
        // Project ID or project number of the Cloud project you want to use.
        String projectId = "YOUR_PROJECT_ID";
    
        // Name of the disk you want to create.
        String diskName = "YOUR_DISK_NAME";
    
        // Name of the snapshot that you want to create.
        String snapshotName = "YOUR_SNAPSHOT_NAME";
    
        // The zone of the source disk from which you create the snapshot (for zonal disks).
        String zone = "europe-central2-b";
    
        // The region of the source disk from which you create the snapshot (for regional disks).
        String region = "your-disk-region";
    
        // The Cloud Storage multi-region or the Cloud Storage region where you
        // want to store your snapshot.
        // You can specify only one storage location. Available locations:
        // https://cloud.google.com/storage/docs/locations#available-locations
        String location = "europe-central2";
    
        // Project ID or project number of the Cloud project that
        // hosts the disk you want to snapshot. If not provided, the value will be defaulted
        // to 'projectId' value.
        String diskProjectId = "YOUR_DISK_PROJECT_ID";
    
        createSnapshot(projectId, diskName, snapshotName, zone, region, location, diskProjectId);
      }
    
      // Creates a snapshot of a disk.
      public static void createSnapshot(String projectId, String diskName, String snapshotName,
          String zone, String region, String location, String diskProjectId)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    
        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests. After completing all of your requests, call
        // the `snapshotsClient.close()` method on the client to safely
        // clean up any remaining background resources.
        try (SnapshotsClient snapshotsClient = SnapshotsClient.create()) {
    
          if (zone.isEmpty() && region.isEmpty()) {
            throw new Error("You need to specify 'zone' or 'region' for this function to work");
          }
    
          if (!zone.isEmpty() && !region.isEmpty()) {
            throw new Error("You can't set both 'zone' and 'region' parameters");
          }
    
          // If Disk's project id is not specified, then the projectId parameter will be used.
          if (diskProjectId.isEmpty()) {
            diskProjectId = projectId;
          }
    
          // If zone is not empty, use the DisksClient to create a disk.
          // Else, use the RegionDisksClient.
          Disk disk;
          if (!zone.isEmpty()) {
            DisksClient disksClient = DisksClient.create();
            disk = disksClient.get(projectId, zone, diskName);
          } else {
            RegionDisksClient regionDisksClient = RegionDisksClient.create();
            disk = regionDisksClient.get(diskProjectId, region, diskName);
          }
    
          // Set the snapshot properties.
          Snapshot snapshotResource;
          if (!location.isEmpty()) {
            snapshotResource = Snapshot.newBuilder()
                .setName(snapshotName)
                .setSourceDisk(disk.getSelfLink())
                .addStorageLocations(location)
                .build();
          } else {
            snapshotResource = Snapshot.newBuilder()
                .setName(snapshotName)
                .setSourceDisk(disk.getSelfLink())
                .build();
          }
    
          // Wait for the operation to complete.
          Operation operation = snapshotsClient.insertAsync(projectId, snapshotResource)
              .get(3, TimeUnit.MINUTES);
    
          if (operation.hasError()) {
            System.out.println("Snapshot creation failed!" + operation);
            return;
          }
    
          // Retrieve the created snapshot.
          Snapshot snapshot = snapshotsClient.get(projectId, snapshotName);
          System.out.printf("Snapshot created: %s", snapshot.getName());
    
        }
      }
    }
  4. Exclua a VM dA zona de origem.

    
    import com.google.api.gax.longrunning.OperationFuture;
    import com.google.cloud.compute.v1.DeleteInstanceRequest;
    import com.google.cloud.compute.v1.InstancesClient;
    import com.google.cloud.compute.v1.Operation;
    import java.io.IOException;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    public class DeleteInstance {
    
      public static void main(String[] args)
          throws IOException, InterruptedException, ExecutionException, TimeoutException {
        // TODO(developer): Replace these variables before running the sample.
        String project = "your-project-id";
        String zone = "zone-name";
        String instanceName = "instance-name";
        deleteInstance(project, zone, instanceName);
      }
    
      // Delete the instance specified by `instanceName`
      // if it's present in the given project and zone.
      public static void deleteInstance(String project, String zone, String instanceName)
          throws IOException, InterruptedException, ExecutionException, TimeoutException {
        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests. After completing all of your requests, call
        // the `instancesClient.close()` method on the client to safely
        // clean up any remaining background resources.
        try (InstancesClient instancesClient = InstancesClient.create()) {
    
          System.out.printf("Deleting instance: %s ", instanceName);
    
          // Describe which instance is to be deleted.
          DeleteInstanceRequest deleteInstanceRequest = DeleteInstanceRequest.newBuilder()
              .setProject(project)
              .setZone(zone)
              .setInstance(instanceName).build();
    
          OperationFuture<Operation, Operation> operation = instancesClient.deleteAsync(
              deleteInstanceRequest);
          // Wait for the operation to complete.
          Operation response = operation.get(3, TimeUnit.MINUTES);
    
          if (response.hasError()) {
            System.out.println("Instance deletion failed ! ! " + response);
            return;
          }
          System.out.println("Operation Status: " + response.getStatus());
        }
      }
    }
  5. Em seguida, crie outro instantâneo do disco de inicialização e do disco de dados.

    
    import com.google.cloud.compute.v1.Disk;
    import com.google.cloud.compute.v1.DisksClient;
    import com.google.cloud.compute.v1.Operation;
    import com.google.cloud.compute.v1.RegionDisksClient;
    import com.google.cloud.compute.v1.Snapshot;
    import com.google.cloud.compute.v1.SnapshotsClient;
    import java.io.IOException;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    public class CreateSnapshot {
    
      public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
        // TODO(developer): Replace these variables before running the sample.
        // You need to pass `zone` or `region` parameter relevant to the disk you want to
        // snapshot, but not both. Pass `zone` parameter for zonal disks and `region` for
        // regional disks.
    
        // Project ID or project number of the Cloud project you want to use.
        String projectId = "YOUR_PROJECT_ID";
    
        // Name of the disk you want to create.
        String diskName = "YOUR_DISK_NAME";
    
        // Name of the snapshot that you want to create.
        String snapshotName = "YOUR_SNAPSHOT_NAME";
    
        // The zone of the source disk from which you create the snapshot (for zonal disks).
        String zone = "europe-central2-b";
    
        // The region of the source disk from which you create the snapshot (for regional disks).
        String region = "your-disk-region";
    
        // The Cloud Storage multi-region or the Cloud Storage region where you
        // want to store your snapshot.
        // You can specify only one storage location. Available locations:
        // https://cloud.google.com/storage/docs/locations#available-locations
        String location = "europe-central2";
    
        // Project ID or project number of the Cloud project that
        // hosts the disk you want to snapshot. If not provided, the value will be defaulted
        // to 'projectId' value.
        String diskProjectId = "YOUR_DISK_PROJECT_ID";
    
        createSnapshot(projectId, diskName, snapshotName, zone, region, location, diskProjectId);
      }
    
      // Creates a snapshot of a disk.
      public static void createSnapshot(String projectId, String diskName, String snapshotName,
          String zone, String region, String location, String diskProjectId)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    
        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests. After completing all of your requests, call
        // the `snapshotsClient.close()` method on the client to safely
        // clean up any remaining background resources.
        try (SnapshotsClient snapshotsClient = SnapshotsClient.create()) {
    
          if (zone.isEmpty() && region.isEmpty()) {
            throw new Error("You need to specify 'zone' or 'region' for this function to work");
          }
    
          if (!zone.isEmpty() && !region.isEmpty()) {
            throw new Error("You can't set both 'zone' and 'region' parameters");
          }
    
          // If Disk's project id is not specified, then the projectId parameter will be used.
          if (diskProjectId.isEmpty()) {
            diskProjectId = projectId;
          }
    
          // If zone is not empty, use the DisksClient to create a disk.
          // Else, use the RegionDisksClient.
          Disk disk;
          if (!zone.isEmpty()) {
            DisksClient disksClient = DisksClient.create();
            disk = disksClient.get(projectId, zone, diskName);
          } else {
            RegionDisksClient regionDisksClient = RegionDisksClient.create();
            disk = regionDisksClient.get(diskProjectId, region, diskName);
          }
    
          // Set the snapshot properties.
          Snapshot snapshotResource;
          if (!location.isEmpty()) {
            snapshotResource = Snapshot.newBuilder()
                .setName(snapshotName)
                .setSourceDisk(disk.getSelfLink())
                .addStorageLocations(location)
                .build();
          } else {
            snapshotResource = Snapshot.newBuilder()
                .setName(snapshotName)
                .setSourceDisk(disk.getSelfLink())
                .build();
          }
    
          // Wait for the operation to complete.
          Operation operation = snapshotsClient.insertAsync(projectId, snapshotResource)
              .get(3, TimeUnit.MINUTES);
    
          if (operation.hasError()) {
            System.out.println("Snapshot creation failed!" + operation);
            return;
          }
    
          // Retrieve the created snapshot.
          Snapshot snapshot = snapshotsClient.get(projectId, snapshotName);
          System.out.printf("Snapshot created: %s", snapshot.getName());
    
        }
      }
    }
  6. (Opcional) Exclua os discos permanentes.

    Se você pretende usar os mesmos nomes dos discos permanentes nos novos discos, precisa excluir os discos atuais para liberar os nomes. A exclusão dos discos também economiza custos com armazenamento em disco permanente.

    Se você não planeja reutilizar os mesmos nomes de disco, não é necessário excluí-los.

    
    import com.google.cloud.compute.v1.DeleteDiskRequest;
    import com.google.cloud.compute.v1.DisksClient;
    import com.google.cloud.compute.v1.Operation;
    import java.io.IOException;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    public class DeleteDisk {
    
      public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
        // TODO(developer): Replace these variables before running the sample.
    
        // Project ID or project number of the Cloud project you want to use.
        String projectId = "YOUR_PROJECT_ID";
    
        // The zone from where you want to delete the disk.
        String zone = "europe-central2-b";
    
        // Name of the disk you want to delete.
        String diskName = "YOUR_DISK_NAME";
    
        deleteDisk(projectId, zone, diskName);
      }
    
      // Deletes a disk from a project.
      public static void deleteDisk(String projectId, String zone, String diskName)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    
        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests. After completing all of your requests, call
        // the `disksClient.close()` method on the client to safely
        // clean up any remaining background resources.
        try (DisksClient disksClient = DisksClient.create()) {
    
          // Create the request object.
          DeleteDiskRequest deleteDiskRequest = DeleteDiskRequest.newBuilder()
              .setProject(projectId)
              .setZone(zone)
              .setDisk(diskName)
              .build();
    
          // Wait for the delete disk operation to complete.
          Operation response = disksClient.deleteAsync(deleteDiskRequest)
              .get(3, TimeUnit.MINUTES);
    
          if (response.hasError()) {
            System.out.println("Disk deletion failed!" + response);
            return;
          }
          System.out.println("Operation Status: " + response.getStatus());
        }
      }
    }
  7. Criar novos discos permanentes na zona de destino com base nos snapshots criados. Primeiro, crie o disco de inicialização e depois os discos de dados.

    
    import com.google.cloud.compute.v1.Disk;
    import com.google.cloud.compute.v1.DisksClient;
    import com.google.cloud.compute.v1.InsertDiskRequest;
    import com.google.cloud.compute.v1.Operation;
    import java.io.IOException;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    public class CreateDiskFromSnapshot {
    
      public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
        // TODO(developer): Replace these variables before running the sample.
    
        // Project ID or project number of the Cloud project you want to use.
        String projectId = "YOUR_PROJECT_ID";
    
        // Name of the zone in which you want to create the disk.
        String zone = "europe-central2-b";
    
        // Name of the disk you want to create.
        String diskName = "YOUR_DISK_NAME";
    
        // The type of disk you want to create. This value uses the following format:
        // "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
        // For example: "zones/us-west3-b/diskTypes/pd-ssd"
        String diskType = String.format("zones/%s/diskTypes/pd-ssd", zone);
    
        // Size of the new disk in gigabytes.
        long diskSizeGb = 10;
    
        // The full path and name of the snapshot that you want to use as the source for the new disk.
        // This value uses the following format:
        // "projects/{projectName}/global/snapshots/{snapshotName}"
        String snapshotLink = String.format("projects/%s/global/snapshots/%s", projectId,
            "SNAPSHOT_NAME");
    
        createDiskFromSnapshot(projectId, zone, diskName, diskType, diskSizeGb, snapshotLink);
      }
    
      // Creates a new disk in a project in given zone, using a snapshot.
      public static void createDiskFromSnapshot(String projectId, String zone, String diskName,
          String diskType, long diskSizeGb, String snapshotLink)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    
        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests. After completing all of your requests, call
        // the `disksClient.close()` method on the client to safely
        // clean up any remaining background resources.
        try (DisksClient disksClient = DisksClient.create()) {
    
          // Set the disk properties and the source snapshot.
          Disk disk = Disk.newBuilder()
              .setName(diskName)
              .setZone(zone)
              .setSizeGb(diskSizeGb)
              .setType(diskType)
              .setSourceSnapshot(snapshotLink)
              .build();
    
          // Create the insert disk request.
          InsertDiskRequest insertDiskRequest = InsertDiskRequest.newBuilder()
              .setProject(projectId)
              .setZone(zone)
              .setDiskResource(disk)
              .build();
    
          // Wait for the create disk operation to complete.
          Operation response = disksClient.insertAsync(insertDiskRequest)
              .get(3, TimeUnit.MINUTES);
    
          if (response.hasError()) {
            System.out.println("Disk creation failed!" + response);
            return;
          }
          System.out.println("Disk created. Operation Status: " + response.getStatus());
        }
      }
    }
  8. Recrie a VM com os novos discos na zona de destino.

    
    import com.google.cloud.compute.v1.AttachedDisk;
    import com.google.cloud.compute.v1.Disk;
    import com.google.cloud.compute.v1.DisksClient;
    import com.google.cloud.compute.v1.InsertInstanceRequest;
    import com.google.cloud.compute.v1.Instance;
    import com.google.cloud.compute.v1.InstancesClient;
    import com.google.cloud.compute.v1.NetworkInterface;
    import com.google.cloud.compute.v1.Operation;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    public class CreateInstanceWithExistingDisks {
    
      public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
        // TODO(developer): Replace these variables before running the sample.
    
        // Project ID or project number of the Cloud project you want to use.
        String projectId = "YOUR_PROJECT_ID";
    
        // Name of the zone to create the instance in. For example: "us-west3-b"
        String zone = "europe-central2-b";
    
        // Name of the new virtual machine (VM) instance.
        String instanceName = "YOUR_INSTANCE_NAME";
    
        // Array of disk names to be attached to the new virtual machine.
        // First disk in this list will be used as the boot disk.
        List<String> diskNames = List.of("your-boot-disk", "another-disk1", "another-disk2");
    
        createInstanceWithExistingDisks(projectId, zone, instanceName, diskNames);
      }
    
      // Create a new VM instance using the selected disks.
      // The first disk in diskNames will be used as the boot disk.
      public static void createInstanceWithExistingDisks(String projectId, String zone,
          String instanceName, List<String> diskNames)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    
        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests. After completing all of your requests, call
        // the `instancesClient.close()` method on the client to safely
        // clean up any remaining background resources.
        try (InstancesClient instancesClient = InstancesClient.create();
            DisksClient disksClient = DisksClient.create()) {
    
          if (diskNames.size() == 0) {
            throw new Error("At least one disk should be provided");
          }
    
          // Create the list of attached disks to be used in instance creation.
          List<AttachedDisk> attachedDisks = new ArrayList<>();
          for (int i = 0; i < diskNames.size(); i++) {
            String diskName = diskNames.get(i);
            Disk disk = disksClient.get(projectId, zone, diskName);
            AttachedDisk attDisk = null;
    
            if (i == 0) {
              // Make the first disk in the list as the boot disk.
              attDisk = AttachedDisk.newBuilder()
                  .setSource(disk.getSelfLink())
                  .setBoot(true)
                  .build();
            } else {
              attDisk = AttachedDisk.newBuilder()
                  .setSource(disk.getSelfLink())
                  .build();
            }
            attachedDisks.add(attDisk);
          }
    
          // Create the instance.
          Instance instance = Instance.newBuilder()
              .setName(instanceName)
              // Add the attached disks to the instance.
              .addAllDisks(attachedDisks)
              .setMachineType(String.format("zones/%s/machineTypes/n1-standard-1", zone))
              .addNetworkInterfaces(
                  NetworkInterface.newBuilder().setName("global/networks/default").build())
              .build();
    
          // Create the insert instance request.
          InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
              .setProject(projectId)
              .setZone(zone)
              .setInstanceResource(instance)
              .build();
    
          // Wait for the create operation to complete.
          Operation response = instancesClient.insertAsync(insertInstanceRequest)
              .get(3, TimeUnit.MINUTES);
    
          if (response.hasError()) {
            System.out.println("Instance creation failed!" + response);
            return;
          }
          System.out.println("Operation Status: " + response.getStatus());
    
        }
      }
    }
  9. (Opcional) Excluir os snapshots de discos temporários. Depois de confirmar que suas máquinas virtuais foram movidas, exclua os snapshots temporários que você criou para economizar nos custos de armazenamento.

    
    import com.google.cloud.compute.v1.Operation;
    import com.google.cloud.compute.v1.SnapshotsClient;
    import java.io.IOException;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    public class DeleteSnapshot {
    
      public static void main(String[] args)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
        // TODO(developer): Replace these variables before running the sample.
    
        // Project ID or project number of the Cloud project you want to use.
        String projectId = "YOUR_PROJECT_ID";
    
        // Name of the snapshot to be deleted.
        String snapshotName = "YOUR_SNAPSHOT_NAME";
    
        deleteSnapshot(projectId, snapshotName);
      }
    
      // Delete a snapshot of a disk.
      public static void deleteSnapshot(String projectId, String snapshotName)
          throws IOException, ExecutionException, InterruptedException, TimeoutException {
    
        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests. After completing all of your requests, call
        // the `snapshotsClient.close()` method on the client to safely
        // clean up any remaining background resources.
        try (SnapshotsClient snapshotsClient = SnapshotsClient.create()) {
    
          Operation operation = snapshotsClient.deleteAsync(projectId, snapshotName)
              .get(3, TimeUnit.MINUTES);
    
          if (operation.hasError()) {
            System.out.println("Snapshot deletion failed!" + operation);
            return;
          }
    
          System.out.println("Snapshot deleted!");
        }
      }
    }

Node.js

  1. Encontre os detalhes da VM e identifique os discos anexados a ela.

    /**
     * TODO(developer): Uncomment and replace these variables before running the sample.
     */
    // const projectId = 'YOUR_PROJECT_ID';
    // const zone = 'europe-central2-b'
    // const instanceName = 'YOUR_INSTANCE_NAME'
    
    const compute = require('@google-cloud/compute');
    
    async function getInstance() {
      const instancesClient = new compute.InstancesClient();
    
      const [instance] = await instancesClient.get({
        project: projectId,
        zone,
        instance: instanceName,
      });
    
      console.log(
        `Instance ${instanceName} data:\n${JSON.stringify(instance, null, 4)}`
      );
    }
    getInstance();
  2. Defina o estado de exclusão automática do disco de inicialização e do disco de dados como false para garantir que os discos não sejam excluídos automaticamente quando a VM for excluída.

    /**
     * TODO(developer): Uncomment and replace these variables before running the sample.
     */
    // const projectId = 'YOUR_PROJECT_ID';
    // const zone = 'europe-central2-b';
    // const instanceName = 'YOUR_INSTANCE_NAME';
    // const diskName = 'YOUR_DISK_NAME';
    // const autoDelete = true;
    
    const compute = require('@google-cloud/compute');
    
    async function setDiskAutodelete() {
      const instancesClient = new compute.InstancesClient();
    
      const [instance] = await instancesClient.get({
        project: projectId,
        zone,
        instance: instanceName,
      });
    
      if (!instance.disks.some(disk => disk.deviceName === diskName)) {
        throw new Error(
          `Instance ${instanceName} doesn't have a disk named ${diskName} attached.`
        );
      }
    
      const [response] = await instancesClient.setDiskAutoDelete({
        project: projectId,
        zone,
        instance: instanceName,
        deviceName: diskName,
        autoDelete,
      });
      let operation = response.latestResponse;
      const operationsClient = new compute.ZoneOperationsClient();
    
      // Wait for the update instance operation to complete.
      while (operation.status !== 'DONE') {
        [operation] = await operationsClient.wait({
          operation: operation.name,
          project: projectId,
          zone: operation.zone.split('/').pop(),
        });
      }
    
      console.log('Disk autoDelete field updated.');
    }
    
    setDiskAutodelete();
  3. Crie backups dos seus dados usando snapshots de discos permanentes.

    Como precaução, crie backups dos dados enquanto os discos permanentes ainda estiverem conectados à VM usando snapshots de discos permanentes. Antes de criar um snapshot, verifique se ele é consistente com o estado do disco permanente seguindo as práticas recomendadas de snapshot.

    Depois de limpar os buffers de disco, crie os snapshots:

    /**
     * TODO(developer): Uncomment and replace these variables before running the sample.
     */
    // const projectId = 'YOUR_PROJECT_ID';
    // const diskName = 'YOUR_DISK_NAME';
    // const snapshotName = 'YOUR_SNAPSHOT_NAME';
    // const zone = 'europe-central2-b';
    // const region = '';
    // const location = 'europe-central2';
    // let diskProjectId = 'YOUR_DISK_PROJECT_ID';
    
    const compute = require('@google-cloud/compute');
    
    async function createSnapshot() {
      const snapshotsClient = new compute.SnapshotsClient();
    
      let disk;
    
      if (!zone && !region) {
        throw new Error(
          'You need to specify `zone` or `region` for this function to work.'
        );
      }
    
      if (zone && region) {
        throw new Error("You can't set both `zone` and `region` parameters");
      }
    
      if (!diskProjectId) {
        diskProjectId = projectId;
      }
    
      if (zone) {
        const disksClient = new compute.DisksClient();
        [disk] = await disksClient.get({
          project: diskProjectId,
          zone,
          disk: diskName,
        });
      } else {
        const regionDisksClient = new compute.RegionDisksClient();
        [disk] = await regionDisksClient.get({
          project: diskProjectId,
          region,
          disk: diskName,
        });
      }
    
      const snapshotResource = {
        name: snapshotName,
        sourceDisk: disk.selfLink,
      };
    
      if (location) {
        snapshotResource.storageLocations = [location];
      }
    
      const [response] = await snapshotsClient.insert({
        project: projectId,
        snapshotResource,
      });
      let operation = response.latestResponse;
      const operationsClient = new compute.GlobalOperationsClient();
    
      // Wait for the create snapshot operation to complete.
      while (operation.status !== 'DONE') {
        [operation] = await operationsClient.wait({
          operation: operation.name,
          project: projectId,
        });
      }
    
      console.log('Snapshot created.');
    }
    
    createSnapshot();
  4. Exclua a VM dA zona de origem.

    /**
     * TODO(developer): Uncomment these variables before running the sample.
     */
    // const projectId = 'YOUR_PROJECT_ID';
    // const zone = 'europe-central2-b'
    // const instanceName = 'YOUR_INSTANCE_NAME';
    
    const compute = require('@google-cloud/compute');
    
    // Delete the instance specified by `instanceName` if it's present in the given project and zone.
    async function deleteInstance() {
      const instancesClient = new compute.InstancesClient();
    
      console.log(`Deleting ${instanceName} from ${zone}...`);
    
      const [response] = await instancesClient.delete({
        project: projectId,
        zone,
        instance: instanceName,
      });
      let operation = response.latestResponse;
      const operationsClient = new compute.ZoneOperationsClient();
    
      // Wait for the delete operation to complete.
      while (operation.status !== 'DONE') {
        [operation] = await operationsClient.wait({
          operation: operation.name,
          project: projectId,
          zone: operation.zone.split('/').pop(),
        });
      }
    
      console.log('Instance deleted.');
    }
    
    deleteInstance();
  5. Em seguida, crie outro instantâneo do disco de inicialização e do disco de dados.

    /**
     * TODO(developer): Uncomment and replace these variables before running the sample.
     */
    // const projectId = 'YOUR_PROJECT_ID';
    // const diskName = 'YOUR_DISK_NAME';
    // const snapshotName = 'YOUR_SNAPSHOT_NAME';
    // const zone = 'europe-central2-b';
    // const region = '';
    // const location = 'europe-central2';
    // let diskProjectId = 'YOUR_DISK_PROJECT_ID';
    
    const compute = require('@google-cloud/compute');
    
    async function createSnapshot() {
      const snapshotsClient = new compute.SnapshotsClient();
    
      let disk;
    
      if (!zone && !region) {
        throw new Error(
          'You need to specify `zone` or `region` for this function to work.'
        );
      }
    
      if (zone && region) {
        throw new Error("You can't set both `zone` and `region` parameters");
      }
    
      if (!diskProjectId) {
        diskProjectId = projectId;
      }
    
      if (zone) {
        const disksClient = new compute.DisksClient();
        [disk] = await disksClient.get({
          project: diskProjectId,
          zone,
          disk: diskName,
        });
      } else {
        const regionDisksClient = new compute.RegionDisksClient();
        [disk] = await regionDisksClient.get({
          project: diskProjectId,
          region,
          disk: diskName,
        });
      }
    
      const snapshotResource = {
        name: snapshotName,
        sourceDisk: disk.selfLink,
      };
    
      if (location) {
        snapshotResource.storageLocations = [location];
      }
    
      const [response] = await snapshotsClient.insert({
        project: projectId,
        snapshotResource,
      });
      let operation = response.latestResponse;
      const operationsClient = new compute.GlobalOperationsClient();
    
      // Wait for the create snapshot operation to complete.
      while (operation.status !== 'DONE') {
        [operation] = await operationsClient.wait({
          operation: operation.name,
          project: projectId,
        });
      }
    
      console.log('Snapshot created.');
    }
    
    createSnapshot();
  6. (Opcional) Exclua os discos permanentes.

    Se você pretende usar os mesmos nomes dos discos permanentes nos novos discos, precisa excluir os discos atuais para liberar os nomes. A exclusão dos discos também economiza custos com armazenamento em disco permanente.

    Se você não planeja reutilizar os mesmos nomes de disco, não é necessário excluí-los.

    /**
     * TODO(developer): Uncomment and replace these variables before running the sample.
     */
    // const projectId = 'YOUR_PROJECT_ID';
    // const zone = 'europe-central2-b';
    // const diskName = 'YOUR_DISK_NAME';
    
    const compute = require('@google-cloud/compute');
    
    async function deleteDisk() {
      const disksClient = new compute.DisksClient();
    
      const [response] = await disksClient.delete({
        project: projectId,
        zone,
        disk: diskName,
      });
      let operation = response.latestResponse;
      const operationsClient = new compute.ZoneOperationsClient();
    
      // Wait for the create disk operation to complete.
      while (operation.status !== 'DONE') {
        [operation] = await operationsClient.wait({
          operation: operation.name,
          project: projectId,
          zone: operation.zone.split('/').pop(),
        });
      }
    
      console.log('Disk deleted.');
    }
    
    deleteDisk();
  7. Criar novos discos permanentes na zona de destino com base nos snapshots criados. Primeiro, crie o disco de inicialização e depois os discos de dados.

    /**
     * TODO(developer): Uncomment and replace these variables before running the sample.
     */
    // const projectId = 'YOUR_PROJECT_ID';
    // const zone = 'europe-central2-b';
    // const diskName = 'YOUR_DISK_NAME';
    // const diskType = 'zones/us-west3-b/diskTypes/pd-ssd';
    // const diskSizeGb = 10;
    // const snapshotLink = 'projects/project_name/global/snapshots/snapshot_name';
    
    const compute = require('@google-cloud/compute');
    
    async function createDiskFromSnapshot() {
      const disksClient = new compute.DisksClient();
    
      const [response] = await disksClient.insert({
        project: projectId,
        zone,
        diskResource: {
          sizeGb: diskSizeGb,
          name: diskName,
          zone,
          type: diskType,
          sourceSnapshot: snapshotLink,
        },
      });
      let operation = response.latestResponse;
      const operationsClient = new compute.ZoneOperationsClient();
    
      // Wait for the create disk operation to complete.
      while (operation.status !== 'DONE') {
        [operation] = await operationsClient.wait({
          operation: operation.name,
          project: projectId,
          zone: operation.zone.split('/').pop(),
        });
      }
    
      console.log('Disk created.');
    }
    
    createDiskFromSnapshot();
  8. Recrie a VM com os novos discos na zona de destino.

    /**
     * TODO(developer): Uncomment and replace these variables before running the sample.
     */
    // const projectId = 'YOUR_PROJECT_ID';
    // const zone = 'europe-central2-b';
    // const instanceName = 'YOUR_INSTANCE_NAME';
    // const diskNames = ['boot_disk', 'disk1', 'disk2'];
    
    const compute = require('@google-cloud/compute');
    
    async function createWithExistingDisks() {
      const instancesClient = new compute.InstancesClient();
      const disksClient = new compute.DisksClient();
    
      if (diskNames.length < 1) {
        throw new Error('At least one disk should be provided');
      }
    
      const disks = [];
      for (const diskName of diskNames) {
        const [disk] = await disksClient.get({
          project: projectId,
          zone,
          disk: diskName,
        });
        disks.push(disk);
      }
    
      const attachedDisks = [];
    
      for (const disk of disks) {
        attachedDisks.push({
          source: disk.selfLink,
        });
      }
    
      attachedDisks[0].boot = true;
    
      const [response] = await instancesClient.insert({
        project: projectId,
        zone,
        instanceResource: {
          name: instanceName,
          disks: attachedDisks,
          machineType: `zones/${zone}/machineTypes/n1-standard-1`,
          networkInterfaces: [
            {
              name: 'global/networks/default',
            },
          ],
        },
      });
      let operation = response.latestResponse;
      const operationsClient = new compute.ZoneOperationsClient();
    
      // Wait for the create operation to complete.
      while (operation.status !== 'DONE') {
        [operation] = await operationsClient.wait({
          operation: operation.name,
          project: projectId,
          zone: operation.zone.split('/').pop(),
        });
      }
    
      console.log('Instance created.');
    }
    
    createWithExistingDisks();
  9. (Opcional) Excluir os snapshots de discos temporários. Depois de confirmar que suas máquinas virtuais foram movidas, exclua os snapshots temporários que você criou para economizar nos custos de armazenamento.

    /**
     * TODO(developer): Uncomment and replace these variables before running the sample.
     */
    // const projectId = 'YOUR_PROJECT_ID';
    // const snapshotName = 'YOUR_SNAPSHOT_NAME';
    
    const compute = require('@google-cloud/compute');
    
    async function deleteSnapshot() {
      const snapshotsClient = new compute.SnapshotsClient();
    
      const [response] = await snapshotsClient.delete({
        project: projectId,
        snapshot: snapshotName,
      });
      let operation = response.latestResponse;
      const operationsClient = new compute.GlobalOperationsClient();
    
      // Wait for the create disk operation to complete.
      while (operation.status !== 'DONE') {
        [operation] = await operationsClient.wait({
          operation: operation.name,
          project: projectId,
        });
      }
    
      console.log('Snapshot deleted.');
    }
    
    deleteSnapshot();

Python

  1. Encontre os detalhes da VM e identifique os discos anexados a ela.

    from google.cloud import compute_v1
    
    def get_instance(project_id: str, zone: str, instance_name: str) -> compute_v1.Instance:
        """
        Get information about a VM instance in the given zone in the specified project.
    
        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone you want to use. For example: “us-west3-b”
            instance_name: name of the VM instance you want to query.
        Returns:
            An Instance object.
        """
        instance_client = compute_v1.InstancesClient()
        instance = instance_client.get(
            project=project_id, zone=zone, instance=instance_name
        )
    
        return instance
    
    
  2. Defina o estado de exclusão automática do disco de inicialização e do disco de dados como false para garantir que os discos não sejam excluídos automaticamente quando a VM for excluída.

    from __future__ import annotations
    
    import sys
    from typing import Any
    
    from google.api_core.extended_operation import ExtendedOperation
    from google.cloud import compute_v1
    
    def wait_for_extended_operation(
        operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
    ) -> Any:
        """
        Waits for the extended (long-running) operation to complete.
    
        If the operation is successful, it will return its result.
        If the operation ends with an error, an exception will be raised.
        If there were any warnings during the execution of the operation
        they will be printed to sys.stderr.
    
        Args:
            operation: a long-running operation you want to wait on.
            verbose_name: (optional) a more verbose name of the operation,
                used only during error and warning reporting.
            timeout: how long (in seconds) to wait for operation to finish.
                If None, wait indefinitely.
    
        Returns:
            Whatever the operation.result() returns.
    
        Raises:
            This method will raise the exception received from `operation.exception()`
            or RuntimeError if there is no exception set, but there is an `error_code`
            set for the `operation`.
    
            In case of an operation taking longer than `timeout` seconds to complete,
            a `concurrent.futures.TimeoutError` will be raised.
        """
        result = operation.result(timeout=timeout)
    
        if operation.error_code:
            print(
                f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
                file=sys.stderr,
                flush=True,
            )
            print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
            raise operation.exception() or RuntimeError(operation.error_message)
    
        if operation.warnings:
            print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
            for warning in operation.warnings:
                print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)
    
        return result
    
    def set_disk_autodelete(
        project_id: str, zone: str, instance_name: str, disk_name: str, autodelete: bool
    ) -> None:
        """
        Set the autodelete flag of a disk to given value.
    
        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone in which is the disk you want to modify.
            instance_name: name of the instance the disk is attached to.
            disk_name: the name of the disk which flag you want to modify.
            autodelete: the new value of the autodelete flag.
        """
        instance_client = compute_v1.InstancesClient()
        instance = instance_client.get(
            project=project_id, zone=zone, instance=instance_name
        )
    
        for disk in instance.disks:
            if disk.device_name == disk_name:
                break
        else:
            raise RuntimeError(
                f"Instance {instance_name} doesn't have a disk named {disk_name} attached."
            )
    
        disk.auto_delete = autodelete
    
        operation = instance_client.update(
            project=project_id,
            zone=zone,
            instance=instance_name,
            instance_resource=instance,
        )
    
        wait_for_extended_operation(operation, "disk update")
    
    
  3. Crie backups dos seus dados usando snapshots de discos permanentes.

    Como precaução, crie backups dos dados enquanto os discos permanentes ainda estiverem conectados à VM usando snapshots de discos permanentes. Antes de criar um snapshot, verifique se ele é consistente com o estado do disco permanente seguindo as práticas recomendadas de snapshot.

    Depois de limpar os buffers de disco, crie os snapshots:

    from __future__ import annotations
    
    import sys
    from typing import Any
    
    from google.api_core.extended_operation import ExtendedOperation
    from google.cloud import compute_v1
    
    def wait_for_extended_operation(
        operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
    ) -> Any:
        """
        Waits for the extended (long-running) operation to complete.
    
        If the operation is successful, it will return its result.
        If the operation ends with an error, an exception will be raised.
        If there were any warnings during the execution of the operation
        they will be printed to sys.stderr.
    
        Args:
            operation: a long-running operation you want to wait on.
            verbose_name: (optional) a more verbose name of the operation,
                used only during error and warning reporting.
            timeout: how long (in seconds) to wait for operation to finish.
                If None, wait indefinitely.
    
        Returns:
            Whatever the operation.result() returns.
    
        Raises:
            This method will raise the exception received from `operation.exception()`
            or RuntimeError if there is no exception set, but there is an `error_code`
            set for the `operation`.
    
            In case of an operation taking longer than `timeout` seconds to complete,
            a `concurrent.futures.TimeoutError` will be raised.
        """
        result = operation.result(timeout=timeout)
    
        if operation.error_code:
            print(
                f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
                file=sys.stderr,
                flush=True,
            )
            print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
            raise operation.exception() or RuntimeError(operation.error_message)
    
        if operation.warnings:
            print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
            for warning in operation.warnings:
                print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)
    
        return result
    
    def create_snapshot(
        project_id: str,
        disk_name: str,
        snapshot_name: str,
        *,
        zone: str | None = None,
        region: str | None = None,
        location: str | None = None,
        disk_project_id: str | None = None,
    ) -> compute_v1.Snapshot:
        """
        Create a snapshot of a disk.
    
        You need to pass `zone` or `region` parameter relevant to the disk you want to
        snapshot, but not both. Pass `zone` parameter for zonal disks and `region` for
        regional disks.
    
        Args:
            project_id: project ID or project number of the Cloud project you want
                to use to store the snapshot.
            disk_name: name of the disk you want to snapshot.
            snapshot_name: name of the snapshot to be created.
            zone: name of the zone in which is the disk you want to snapshot (for zonal disks).
            region: name of the region in which is the disk you want to snapshot (for regional disks).
            location: The Cloud Storage multi-region or the Cloud Storage region where you
                want to store your snapshot.
                You can specify only one storage location. Available locations:
                https://cloud.google.com/storage/docs/locations#available-locations
            disk_project_id: project ID or project number of the Cloud project that
                hosts the disk you want to snapshot. If not provided, will look for
                the disk in the `project_id` project.
    
        Returns:
            The new snapshot instance.
        """
        if zone is None and region is None:
            raise RuntimeError(
                "You need to specify `zone` or `region` for this function to work."
            )
        if zone is not None and region is not None:
            raise RuntimeError("You can't set both `zone` and `region` parameters.")
    
        if disk_project_id is None:
            disk_project_id = project_id
    
        if zone is not None:
            disk_client = compute_v1.DisksClient()
            disk = disk_client.get(project=disk_project_id, zone=zone, disk=disk_name)
        else:
            regio_disk_client = compute_v1.RegionDisksClient()
            disk = regio_disk_client.get(
                project=disk_project_id, region=region, disk=disk_name
            )
    
        snapshot = compute_v1.Snapshot()
        snapshot.source_disk = disk.self_link
        snapshot.name = snapshot_name
        if location:
            snapshot.storage_locations = [location]
    
        snapshot_client = compute_v1.SnapshotsClient()
        operation = snapshot_client.insert(project=project_id, snapshot_resource=snapshot)
    
        wait_for_extended_operation(operation, "snapshot creation")
    
        return snapshot_client.get(project=project_id, snapshot=snapshot_name)
    
    
  4. Exclua a VM dA zona de origem.

    from __future__ import annotations
    
    import sys
    from typing import Any
    
    from google.api_core.extended_operation import ExtendedOperation
    from google.cloud import compute_v1
    
    def wait_for_extended_operation(
        operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
    ) -> Any:
        """
        Waits for the extended (long-running) operation to complete.
    
        If the operation is successful, it will return its result.
        If the operation ends with an error, an exception will be raised.
        If there were any warnings during the execution of the operation
        they will be printed to sys.stderr.
    
        Args:
            operation: a long-running operation you want to wait on.
            verbose_name: (optional) a more verbose name of the operation,
                used only during error and warning reporting.
            timeout: how long (in seconds) to wait for operation to finish.
                If None, wait indefinitely.
    
        Returns:
            Whatever the operation.result() returns.
    
        Raises:
            This method will raise the exception received from `operation.exception()`
            or RuntimeError if there is no exception set, but there is an `error_code`
            set for the `operation`.
    
            In case of an operation taking longer than `timeout` seconds to complete,
            a `concurrent.futures.TimeoutError` will be raised.
        """
        result = operation.result(timeout=timeout)
    
        if operation.error_code:
            print(
                f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
                file=sys.stderr,
                flush=True,
            )
            print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
            raise operation.exception() or RuntimeError(operation.error_message)
    
        if operation.warnings:
            print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
            for warning in operation.warnings:
                print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)
    
        return result
    
    def delete_instance(project_id: str, zone: str, machine_name: str) -> None:
        """
        Send an instance deletion request to the Compute Engine API and wait for it to complete.
    
        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone you want to use. For example: “us-west3-b”
            machine_name: name of the machine you want to delete.
        """
        instance_client = compute_v1.InstancesClient()
    
        print(f"Deleting {machine_name} from {zone}...")
        operation = instance_client.delete(
            project=project_id, zone=zone, instance=machine_name
        )
        wait_for_extended_operation(operation, "instance deletion")
        print(f"Instance {machine_name} deleted.")
    
    
  5. Em seguida, crie outro instantâneo do disco de inicialização e do disco de dados.

    from __future__ import annotations
    
    import sys
    from typing import Any
    
    from google.api_core.extended_operation import ExtendedOperation
    from google.cloud import compute_v1
    
    def wait_for_extended_operation(
        operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
    ) -> Any:
        """
        Waits for the extended (long-running) operation to complete.
    
        If the operation is successful, it will return its result.
        If the operation ends with an error, an exception will be raised.
        If there were any warnings during the execution of the operation
        they will be printed to sys.stderr.
    
        Args:
            operation: a long-running operation you want to wait on.
            verbose_name: (optional) a more verbose name of the operation,
                used only during error and warning reporting.
            timeout: how long (in seconds) to wait for operation to finish.
                If None, wait indefinitely.
    
        Returns:
            Whatever the operation.result() returns.
    
        Raises:
            This method will raise the exception received from `operation.exception()`
            or RuntimeError if there is no exception set, but there is an `error_code`
            set for the `operation`.
    
            In case of an operation taking longer than `timeout` seconds to complete,
            a `concurrent.futures.TimeoutError` will be raised.
        """
        result = operation.result(timeout=timeout)
    
        if operation.error_code:
            print(
                f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
                file=sys.stderr,
                flush=True,
            )
            print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
            raise operation.exception() or RuntimeError(operation.error_message)
    
        if operation.warnings:
            print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
            for warning in operation.warnings:
                print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)
    
        return result
    
    def create_snapshot(
        project_id: str,
        disk_name: str,
        snapshot_name: str,
        *,
        zone: str | None = None,
        region: str | None = None,
        location: str | None = None,
        disk_project_id: str | None = None,
    ) -> compute_v1.Snapshot:
        """
        Create a snapshot of a disk.
    
        You need to pass `zone` or `region` parameter relevant to the disk you want to
        snapshot, but not both. Pass `zone` parameter for zonal disks and `region` for
        regional disks.
    
        Args:
            project_id: project ID or project number of the Cloud project you want
                to use to store the snapshot.
            disk_name: name of the disk you want to snapshot.
            snapshot_name: name of the snapshot to be created.
            zone: name of the zone in which is the disk you want to snapshot (for zonal disks).
            region: name of the region in which is the disk you want to snapshot (for regional disks).
            location: The Cloud Storage multi-region or the Cloud Storage region where you
                want to store your snapshot.
                You can specify only one storage location. Available locations:
                https://cloud.google.com/storage/docs/locations#available-locations
            disk_project_id: project ID or project number of the Cloud project that
                hosts the disk you want to snapshot. If not provided, will look for
                the disk in the `project_id` project.
    
        Returns:
            The new snapshot instance.
        """
        if zone is None and region is None:
            raise RuntimeError(
                "You need to specify `zone` or `region` for this function to work."
            )
        if zone is not None and region is not None:
            raise RuntimeError("You can't set both `zone` and `region` parameters.")
    
        if disk_project_id is None:
            disk_project_id = project_id
    
        if zone is not None:
            disk_client = compute_v1.DisksClient()
            disk = disk_client.get(project=disk_project_id, zone=zone, disk=disk_name)
        else:
            regio_disk_client = compute_v1.RegionDisksClient()
            disk = regio_disk_client.get(
                project=disk_project_id, region=region, disk=disk_name
            )
    
        snapshot = compute_v1.Snapshot()
        snapshot.source_disk = disk.self_link
        snapshot.name = snapshot_name
        if location:
            snapshot.storage_locations = [location]
    
        snapshot_client = compute_v1.SnapshotsClient()
        operation = snapshot_client.insert(project=project_id, snapshot_resource=snapshot)
    
        wait_for_extended_operation(operation, "snapshot creation")
    
        return snapshot_client.get(project=project_id, snapshot=snapshot_name)
    
    
  6. (Opcional) Exclua os discos permanentes.

    Se você pretende usar os mesmos nomes dos discos permanentes nos novos discos, precisa excluir os discos atuais para liberar os nomes. A exclusão dos discos também economiza custos com armazenamento em disco permanente.

    Se você não planeja reutilizar os mesmos nomes de disco, não é necessário excluí-los.

    from __future__ import annotations
    
    import sys
    from typing import Any
    
    from google.api_core.extended_operation import ExtendedOperation
    from google.cloud import compute_v1
    
    def wait_for_extended_operation(
        operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
    ) -> Any:
        """
        Waits for the extended (long-running) operation to complete.
    
        If the operation is successful, it will return its result.
        If the operation ends with an error, an exception will be raised.
        If there were any warnings during the execution of the operation
        they will be printed to sys.stderr.
    
        Args:
            operation: a long-running operation you want to wait on.
            verbose_name: (optional) a more verbose name of the operation,
                used only during error and warning reporting.
            timeout: how long (in seconds) to wait for operation to finish.
                If None, wait indefinitely.
    
        Returns:
            Whatever the operation.result() returns.
    
        Raises:
            This method will raise the exception received from `operation.exception()`
            or RuntimeError if there is no exception set, but there is an `error_code`
            set for the `operation`.
    
            In case of an operation taking longer than `timeout` seconds to complete,
            a `concurrent.futures.TimeoutError` will be raised.
        """
        result = operation.result(timeout=timeout)
    
        if operation.error_code:
            print(
                f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
                file=sys.stderr,
                flush=True,
            )
            print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
            raise operation.exception() or RuntimeError(operation.error_message)
    
        if operation.warnings:
            print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
            for warning in operation.warnings:
                print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)
    
        return result
    
    def delete_disk(project_id: str, zone: str, disk_name: str) -> None:
        """
        Deletes a disk from a project.
    
        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone in which is the disk you want to delete.
            disk_name: name of the disk you want to delete.
        """
        disk_client = compute_v1.DisksClient()
        operation = disk_client.delete(project=project_id, zone=zone, disk=disk_name)
        wait_for_extended_operation(operation, "disk deletion")
    
    
  7. Criar novos discos permanentes na zona de destino com base nos snapshots criados. Primeiro, crie o disco de inicialização e depois os discos de dados.

    from __future__ import annotations
    
    import sys
    from typing import Any
    
    from google.api_core.extended_operation import ExtendedOperation
    from google.cloud import compute_v1
    
    def wait_for_extended_operation(
        operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
    ) -> Any:
        """
        Waits for the extended (long-running) operation to complete.
    
        If the operation is successful, it will return its result.
        If the operation ends with an error, an exception will be raised.
        If there were any warnings during the execution of the operation
        they will be printed to sys.stderr.
    
        Args:
            operation: a long-running operation you want to wait on.
            verbose_name: (optional) a more verbose name of the operation,
                used only during error and warning reporting.
            timeout: how long (in seconds) to wait for operation to finish.
                If None, wait indefinitely.
    
        Returns:
            Whatever the operation.result() returns.
    
        Raises:
            This method will raise the exception received from `operation.exception()`
            or RuntimeError if there is no exception set, but there is an `error_code`
            set for the `operation`.
    
            In case of an operation taking longer than `timeout` seconds to complete,
            a `concurrent.futures.TimeoutError` will be raised.
        """
        result = operation.result(timeout=timeout)
    
        if operation.error_code:
            print(
                f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
                file=sys.stderr,
                flush=True,
            )
            print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
            raise operation.exception() or RuntimeError(operation.error_message)
    
        if operation.warnings:
            print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
            for warning in operation.warnings:
                print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)
    
        return result
    
    def create_disk_from_snapshot(
        project_id: str,
        zone: str,
        disk_name: str,
        disk_type: str,
        disk_size_gb: int,
        snapshot_link: str,
    ) -> compute_v1.Disk:
        """
        Creates a new disk in a project in given zone.
    
        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone in which you want to create the disk.
            disk_name: name of the disk you want to create.
            disk_type: the type of disk you want to create. This value uses the following format:
                "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
                For example: "zones/us-west3-b/diskTypes/pd-ssd"
            disk_size_gb: size of the new disk in gigabytes
            snapshot_link: a link to the snapshot you want to use as a source for the new disk.
                This value uses the following format: "projects/{project_name}/global/snapshots/{snapshot_name}"
    
        Returns:
            An unattached Disk instance.
        """
        disk_client = compute_v1.DisksClient()
        disk = compute_v1.Disk()
        disk.zone = zone
        disk.size_gb = disk_size_gb
        disk.source_snapshot = snapshot_link
        disk.type_ = disk_type
        disk.name = disk_name
        operation = disk_client.insert(project=project_id, zone=zone, disk_resource=disk)
    
        wait_for_extended_operation(operation, "disk creation")
    
        return disk_client.get(project=project_id, zone=zone, disk=disk_name)
    
    
  8. Recrie a VM com os novos discos na zona de destino.

    from __future__ import annotations
    
    import re
    import sys
    from typing import Any
    import warnings
    
    from google.api_core.extended_operation import ExtendedOperation
    from google.cloud import compute_v1
    
    def get_disk(project_id: str, zone: str, disk_name: str) -> compute_v1.Disk:
        """
        Gets a disk from a project.
    
        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone where the disk exists.
            disk_name: name of the disk you want to retrieve.
        """
        disk_client = compute_v1.DisksClient()
        return disk_client.get(project=project_id, zone=zone, disk=disk_name)
    
    def wait_for_extended_operation(
        operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
    ) -> Any:
        """
        Waits for the extended (long-running) operation to complete.
    
        If the operation is successful, it will return its result.
        If the operation ends with an error, an exception will be raised.
        If there were any warnings during the execution of the operation
        they will be printed to sys.stderr.
    
        Args:
            operation: a long-running operation you want to wait on.
            verbose_name: (optional) a more verbose name of the operation,
                used only during error and warning reporting.
            timeout: how long (in seconds) to wait for operation to finish.
                If None, wait indefinitely.
    
        Returns:
            Whatever the operation.result() returns.
    
        Raises:
            This method will raise the exception received from `operation.exception()`
            or RuntimeError if there is no exception set, but there is an `error_code`
            set for the `operation`.
    
            In case of an operation taking longer than `timeout` seconds to complete,
            a `concurrent.futures.TimeoutError` will be raised.
        """
        result = operation.result(timeout=timeout)
    
        if operation.error_code:
            print(
                f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
                file=sys.stderr,
                flush=True,
            )
            print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
            raise operation.exception() or RuntimeError(operation.error_message)
    
        if operation.warnings:
            print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
            for warning in operation.warnings:
                print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)
    
        return result
    
    def create_instance(
        project_id: str,
        zone: str,
        instance_name: str,
        disks: list[compute_v1.AttachedDisk],
        machine_type: str = "n1-standard-1",
        network_link: str = "global/networks/default",
        subnetwork_link: str = None,
        internal_ip: str = None,
        external_access: bool = False,
        external_ipv4: str = None,
        accelerators: list[compute_v1.AcceleratorConfig] = None,
        preemptible: bool = False,
        spot: bool = False,
        instance_termination_action: str = "STOP",
        custom_hostname: str = None,
        delete_protection: bool = False,
    ) -> compute_v1.Instance:
        """
        Send an instance creation request to the Compute Engine API and wait for it to complete.
    
        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone to create the instance in. For example: "us-west3-b"
            instance_name: name of the new virtual machine (VM) instance.
            disks: a list of compute_v1.AttachedDisk objects describing the disks
                you want to attach to your new instance.
            machine_type: machine type of the VM being created. This value uses the
                following format: "zones/{zone}/machineTypes/{type_name}".
                For example: "zones/europe-west3-c/machineTypes/f1-micro"
            network_link: name of the network you want the new instance to use.
                For example: "global/networks/default" represents the network
                named "default", which is created automatically for each project.
            subnetwork_link: name of the subnetwork you want the new instance to use.
                This value uses the following format:
                "regions/{region}/subnetworks/{subnetwork_name}"
            internal_ip: internal IP address you want to assign to the new instance.
                By default, a free address from the pool of available internal IP addresses of
                used subnet will be used.
            external_access: boolean flag indicating if the instance should have an external IPv4
                address assigned.
            external_ipv4: external IPv4 address to be assigned to this instance. If you specify
                an external IP address, it must live in the same region as the zone of the instance.
                This setting requires `external_access` to be set to True to work.
            accelerators: a list of AcceleratorConfig objects describing the accelerators that will
                be attached to the new instance.
            preemptible: boolean value indicating if the new instance should be preemptible
                or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
            spot: boolean value indicating if the new instance should be a Spot VM or not.
            instance_termination_action: What action should be taken once a Spot VM is terminated.
                Possible values: "STOP", "DELETE"
            custom_hostname: Custom hostname of the new VM instance.
                Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
            delete_protection: boolean value indicating if the new virtual machine should be
                protected against deletion or not.
        Returns:
            Instance object.
        """
        instance_client = compute_v1.InstancesClient()
    
        # Use the network interface provided in the network_link argument.
        network_interface = compute_v1.NetworkInterface()
        network_interface.network = network_link
        if subnetwork_link:
            network_interface.subnetwork = subnetwork_link
    
        if internal_ip:
            network_interface.network_i_p = internal_ip
    
        if external_access:
            access = compute_v1.AccessConfig()
            access.type_ = compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.name
            access.name = "External NAT"
            access.network_tier = access.NetworkTier.PREMIUM.name
            if external_ipv4:
                access.nat_i_p = external_ipv4
            network_interface.access_configs = [access]
    
        # Collect information into the Instance object.
        instance = compute_v1.Instance()
        instance.network_interfaces = [network_interface]
        instance.name = instance_name
        instance.disks = disks
        if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
            instance.machine_type = machine_type
        else:
            instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
    
        instance.scheduling = compute_v1.Scheduling()
        if accelerators:
            instance.guest_accelerators = accelerators
            instance.scheduling.on_host_maintenance = (
                compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name
            )
    
        if preemptible:
            # Set the preemptible setting
            warnings.warn(
                "Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning
            )
            instance.scheduling = compute_v1.Scheduling()
            instance.scheduling.preemptible = True
    
        if spot:
            # Set the Spot VM setting
            instance.scheduling.provisioning_model = (
                compute_v1.Scheduling.ProvisioningModel.SPOT.name
            )
            instance.scheduling.instance_termination_action = instance_termination_action
    
        if custom_hostname is not None:
            # Set the custom hostname for the instance
            instance.hostname = custom_hostname
    
        if delete_protection:
            # Set the delete protection bit
            instance.deletion_protection = True
    
        # Prepare the request to insert an instance.
        request = compute_v1.InsertInstanceRequest()
        request.zone = zone
        request.project = project_id
        request.instance_resource = instance
    
        # Wait for the create operation to complete.
        print(f"Creating the {instance_name} instance in {zone}...")
    
        operation = instance_client.insert(request=request)
    
        wait_for_extended_operation(operation, "instance creation")
    
        print(f"Instance {instance_name} created.")
        return instance_client.get(project=project_id, zone=zone, instance=instance_name)
    
    def create_with_existing_disks(
        project_id: str, zone: str, instance_name: str, disk_names: list[str]
    ) -> compute_v1.Instance:
        """
        Create a new VM instance using selected disks. The first disk in disk_names will
        be used as boot disk.
    
        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            zone: name of the zone to create the instance in. For example: "us-west3-b"
            instance_name: name of the new virtual machine (VM) instance.
            disk_names: list of disk names to be attached to the new virtual machine.
                First disk in this list will be used as the boot device.
    
        Returns:
            Instance object.
        """
        assert len(disk_names) >= 1
        disks = [get_disk(project_id, zone, disk_name) for disk_name in disk_names]
        attached_disks = []
        for disk in disks:
            adisk = compute_v1.AttachedDisk()
            adisk.source = disk.self_link
            attached_disks.append(adisk)
        attached_disks[0].boot = True
        instance = create_instance(project_id, zone, instance_name, attached_disks)
        return instance
    
    
  9. (Opcional) Excluir os snapshots de discos temporários. Depois de confirmar que suas máquinas virtuais foram movidas, exclua os snapshots temporários que você criou para economizar nos custos de armazenamento.

    from __future__ import annotations
    
    import sys
    from typing import Any
    
    from google.api_core.extended_operation import ExtendedOperation
    from google.cloud import compute_v1
    
    def wait_for_extended_operation(
        operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
    ) -> Any:
        """
        Waits for the extended (long-running) operation to complete.
    
        If the operation is successful, it will return its result.
        If the operation ends with an error, an exception will be raised.
        If there were any warnings during the execution of the operation
        they will be printed to sys.stderr.
    
        Args:
            operation: a long-running operation you want to wait on.
            verbose_name: (optional) a more verbose name of the operation,
                used only during error and warning reporting.
            timeout: how long (in seconds) to wait for operation to finish.
                If None, wait indefinitely.
    
        Returns:
            Whatever the operation.result() returns.
    
        Raises:
            This method will raise the exception received from `operation.exception()`
            or RuntimeError if there is no exception set, but there is an `error_code`
            set for the `operation`.
    
            In case of an operation taking longer than `timeout` seconds to complete,
            a `concurrent.futures.TimeoutError` will be raised.
        """
        result = operation.result(timeout=timeout)
    
        if operation.error_code:
            print(
                f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
                file=sys.stderr,
                flush=True,
            )
            print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
            raise operation.exception() or RuntimeError(operation.error_message)
    
        if operation.warnings:
            print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
            for warning in operation.warnings:
                print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)
    
        return result
    
    def delete_snapshot(project_id: str, snapshot_name: str) -> None:
        """
        Delete a snapshot of a disk.
    
        Args:
            project_id: project ID or project number of the Cloud project you want to use.
            snapshot_name: name of the snapshot to delete.
        """
    
        snapshot_client = compute_v1.SnapshotsClient()
        operation = snapshot_client.delete(project=project_id, snapshot=snapshot_name)
    
        wait_for_extended_operation(operation, "snapshot deletion")
    
    

A seguir