Move a VM instance between zones or regions Stay organized with collections Save and categorize content based on your preferences.
This document describes how to move a virtual machine (VM) instance betweenzones or regions.
Before you begin
- Read thezones documentation.
- If you haven't already, set upauthentication. Authentication verifies your identity for access to Google Cloud services and APIs. To run code or samples from a local development environment, you can authenticate to Compute Engine by selecting one of the following options:
Select the tab for how you plan to use the samples on this page:
gcloud
Install the Google Cloud CLI. After installation,initialize the Google Cloud CLI by running the following command:
gcloudinit
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
Note: If you installed the gcloud CLI previously, make sure you have the latest version by runninggcloud components update.- Set a default region and zone.
Go
To use the Go samples on this page in a local development environment, install and initialize the gcloud CLI, and then set up Application Default Credentials with your user credentials.
Install the Google Cloud CLI.
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
Note: If you installed the gcloud CLI previously, make sure you have the latest version by runninggcloud components update.If you're using a local shell, then create local authentication credentials for your user account:
gcloudauthapplication-defaultlogin
You don't need to do this if you're using Cloud Shell.
If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.
For more information, see Set up authentication for a local development environment.
Java
To use the Java samples on this page in a local development environment, install and initialize the gcloud CLI, and then set up Application Default Credentials with your user credentials.
Install the Google Cloud CLI.
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
Note: If you installed the gcloud CLI previously, make sure you have the latest version by runninggcloud components update.If you're using a local shell, then create local authentication credentials for your user account:
gcloudauthapplication-defaultlogin
You don't need to do this if you're using Cloud Shell.
If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.
For more information, see Set up authentication for a local development environment.
Node.js
To use the Node.js samples on this page in a local development environment, install and initialize the gcloud CLI, and then set up Application Default Credentials with your user credentials.
Install the Google Cloud CLI.
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
Note: If you installed the gcloud CLI previously, make sure you have the latest version by runninggcloud components update.If you're using a local shell, then create local authentication credentials for your user account:
gcloudauthapplication-defaultlogin
You don't need to do this if you're using Cloud Shell.
If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.
For more information, see Set up authentication for a local development environment.
Python
To use the Python samples on this page in a local development environment, install and initialize the gcloud CLI, and then set up Application Default Credentials with your user credentials.
Install the Google Cloud CLI.
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
Note: If you installed the gcloud CLI previously, make sure you have the latest version by runninggcloud components update.If you're using a local shell, then create local authentication credentials for your user account:
gcloudauthapplication-defaultlogin
You don't need to do this if you're using Cloud Shell.
If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.
For more information, see Set up authentication for a local development environment.
Requirements
This section lists requirements for moving a VM between zones andregions:
Project quota. Your project must have enough quota to do the following:
- Create new snapshots.
- Promote any ephemeral external IP addresses.
Create new VMs and disks in your destination region.
For example, if you have three disks attached to the VM you want tomove, you need enough quota to create three temporary persistent disksnapshots and three new disks. After you create your new disks, you candelete your temporary snapshots.
Check theQuotas page to ensure thatyou have enough quota for the preceding resources. For more information, seeUnderstanding quotas.
Persistent disks. The persistent disks attached to the VM that you want tomove are not attached to other VMs.
Local SSDs. Local SSDs are meant for temporary storage, and data on localSSDs is not preserved through manual VM terminations. If you need to preservelocal SSD data, replicate it by using adurable storage optionlike persistent disks.
GPUs. If your VM includes GPUs, verify that the GPUs you want to use areavailable in the VM's destination zone. For a list of GPUs and the zones that theyare available in, seeGPUs on Compute Engine.
Subnetwork. If you want to move your VM between regions, such asbetween
Note: The method of moving a VM described in this section also works for VMsin a TERMINATED state, orShielded VMthat use UEFI firmware.us-west1-aandasia-south1-b, and your VM belongs to a subnetwork,you must select a new subnetwork for your VM. For instructions on how to createsubnets, seeAdding subnets.
Limitation
If you move a VM across regions, you cannot preserve the VM's ephemeral internalor external IP address. You must choose a new IP address when you recreate theVM.
Resource properties
To move your VM, you must shut down the VM, move it to the destination zone orregion, and then restart it. After you move your VM, update any references thatyou have to the original resource, such as any target VMs or target pools thatpoint to the earlier VM.
During the move, some server-generated properties of your VM anddisks change.
Properties that change for VMs
The following table describes properties that change for VMs:
| Property name | Changes |
|---|---|
| Internal IP address | A new internal IP address is usually assigned, but the VM might keep the original internal IP address. |
| External IP address | If the VM is moving between zones in thesame region, theexternal IP address remains the same. Otherwise, pick a different external IPaddress for the VM instance. |
| CPU platform | Depending on the available CPU platform in your destination zone, yourVM might have a different CPU platform after it has been moved. For afull list of CPU platforms in each zone, seeAvailable regions and zones. |
| Network/subnetwork | If your VM belongs to a subnetwork and you are moving a VM across regions, you must pick a new subnetwork for your VM. VMs moving across zones in the same region retain the same subnetwork. |
Properties that change for disks
The following table describes properties that change for disks:
| Property name | Changes |
|---|---|
| Source snapshot | The source snapshot of the new disk is set to the temporarysnapshot that is created during the move. |
| Source snapshot ID | The source snapshot ID is set to the temporary snapshot's ID. |
| Source image | The source image field is empty. |
| Image ID | The image ID is empty. |
| Last detached timestamp | The last detached timestamp is empty. |
| Last attached timestamp | The last attached timestamp changes to the timestamp when the new diskwas attached to the new instance. |
Properties changing for both VMs and disks
The following table describes properties that change for both VMs and disks:
| Property name | Changes |
|---|---|
| ID | A new resource ID is generated. |
| Creation timestamp | A new creation timestamp is generated. |
| Zone resource URLs | All zone resource URLs change to reflect the destination zone. Thefollowing list shows the resource URLs that change:
|
Move a VM across zones or regions
To move a VM across zones or regions, you can do the following:
- Create a machine imageof your source VM.
- Create a VM from the machine image in a different zone or region.
The following examples show how to move a VM across zones.
gcloud
In this example, you move a VM namedmyinstance that has two persistent disksnamedmybootdisk andmydatadisk, fromeurope-west1-c tous-west1-b.
Identify the disks that are associated with the VM that you want to move:
gcloud compute instances describe myinstance --format="list(name,status,disks)"
In this example, you find the following two associated disks for the
myinstanceVM:- A boot disk called
mybootdisk - A data disk called
mydatadisk
- A boot disk called
Set the auto-delete state of
mybootdiskandmydatadisktofalsetoensure that the disks are not automatically deleted when the VM isdeleted.gcloud compute instances set-disk-auto-delete myinstance --zone europe-west1-c \ --disk mybootdisk --no-auto-delete
If the state was updated,
gcloud computereturns the responseUpdated [...]. If the auto-delete state was already set to false,thengcloud computereturns:No change requested; skipping update for [myinstance].
(Optional) Save your VM metadata.
When you delete your VM, the VM metadata is also removed. Youcan save that information in a separate file, then reapply the VMmetadata to the new VM.
Describe your VM's metadata like so:
gcloud compute instances describe myinstance --zone europe-west1-c
Save the contents to a separate file.
Create backups of your data by using persistent disk snapshots.
As a precaution, create backups of your data while the persistent disks arestill attached to the VM by using persistent disk snapshots. Beforeyou take a snapshot, ensure that it is consistent with the state of thepersistent disk by adhering tosnapshot best practices.
Note: If you are running a Windows VM, the VM must be terminatedbefore you can create a snapshot. Follow the steps tocreate a snapshot for Windows VM.After you clear your disk buffers, create the snapshots:
gcloud compute disks snapshot mybootdisk mydatadisk \ --snapshot-names backup-mybootsnapshot,backup-mydatasnapshot \ --zone europe-west1-c
To verify that the snapshot is created, run
gcloud compute snapshots list.(Optional) If you're moving a VM across zones within the same region,and you want to preserve its ephemeral internal or external IP address,promote theinternalorexternalIP address to a static IP address, which you can reuse later.
Note: If you're moving your VM across regions, you cannot preserve anVM's ephemeral internal or external IP address . You must choose a newIP address when you recreate the VM.Delete your VM.
Note: If you already terminated your Windows VM in a previous step,skip this step.Deleting your VM shuts it down cleanly and detach any persistentdisks.
gcloud compute instances delete myinstance --zone europe-west1-c
gcloudprompts you to confirm the deletion:The following VMs are deleted. Any attached disks configured tobe auto-deleted are deleted unless they are attached to any otherVMs 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)?
Because you turned off the auto-delete state for the disks earlier inthis process, enterY to continue and ignore the warning.
Next, create another snapshot of both the boot disk and the data disk.
gcloud compute disks snapshot mybootdisk mydatadisk \ --snapshot-names mybootsnapshot,mydatasnapshot \ --zone europe-west1-c
Created [.../mydatasnapshot].Created [.../mybootsnapshot].
(Optional) Delete your persistent disks.
If you plan to reuse the names of the persistent disks for the newdisks, you must delete the existing disks to release the names. Deletingyour disks also saves on persistent disk storage costs.
If you do not plan to reuse the same disk names, you don't need to deletethem.
gcloud compute disks delete mybootdisk mydatadisk --zone europe-west1-c
Create new persistent disks in
us-west1-bfrom the snapshots youcreated. First create the boot disk.gcloud compute disks create mybootdiskb --source-snapshot mybootsnapshot \ --zone us-west1-b
Created [.../mybootdiskb].NAME ZONE SIZE_GB TYPE STATUSmybootdiskb us-west1-b 100 pd-standard READY
Then create the data disk.
gcloud compute disks create mydatadiskb --source-snapshot mydatasnapshot \ --zone us-west1-b
Created [.../mydatadiskb].NAME ZONE SIZE_GB TYPE STATUSmydatadiskb us-west1-b 4000 pd-standard READY
Recreate your VM in
us-west1-b.If you had opted to save your VM metadata in a file, for example
myinstance.describe, you can use it toset the same metadataon your VM.If your VM had a static external IP address, you can reassign thataddress to your new VM by specifying the
--address [ADDRESS]option.If you are moving a VM across regions, you must pick a differentexternal IP address for the new VM instance.If your VM had a static internal IP address, you can reassign thataddress to your new VM by specifying the
--private-network-ipADDRESSoption. If you are moving a VM across regions, you must picka different internal IP address for the new VM instance.If your VM included GPUs, add GPUs to the VM using the
--acceleratoroption.If the VM uses a specific subnet, add the
--subnet [SUBNET_NAME]flag.
For a complete list of additional flags, seegcloud 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 STATUSmyinstanceb us-west1-b n1-standard-4 10.240.173.229 146.148.112.106 RUNNING
(Optional) Delete your persistent disk snapshots.
After you confirm that your virtual machines are moved, save onstorage costs by deleting the temporary snapshots that you created.
gcloud compute snapshots delete mybootsnapshot mydatasnapshot
If you no longer need your backup snapshots, delete those snapshotsas well:
gcloud compute snapshots delete backup-mybootsnapshot backup-mydatasnapshot
Go
Get the details of the VM and identify the disks that are attached to the VM.
import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1"computepb"cloud.google.com/go/compute/apiv1/computepb")// getInstance prints a name of a VM instance in the given zone in the specified project.funcgetInstance(wio.Writer,projectID,zone,instanceNamestring)error{// projectID := "your_project_id"// zone := "europe-central2-b"// instanceName := "your_instance_name"ctx:=context.Background()instancesClient,err:=compute.NewInstancesRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewInstancesRESTClient: %w",err)}deferinstancesClient.Close()reqInstance:=&computepb.GetInstanceRequest{Project:projectID,Zone:zone,Instance:instanceName,}instance,err:=instancesClient.Get(ctx,reqInstance)iferr!=nil{returnfmt.Errorf("unable to get instance: %w",err)}fmt.Fprintf(w,"Instance: %s\n",instance.GetName())returnnil}Set the auto-delete state of the boot disk and data disk to
falsetoensure that the disks are not automatically deleted when the VM isdeleted.import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1"computepb"cloud.google.com/go/compute/apiv1/computepb")// setDiskAutodelete sets the autodelete flag of a disk to given value.funcsetDiskAutoDelete(wio.Writer,projectID,zone,instanceName,diskNamestring,autoDeletebool,)error{// projectID := "your_project_id"// zone := "us-west3-b"// instanceName := "your_instance_name"// diskName := "your_disk_name"// autoDelete := truectx:=context.Background()instancesClient,err:=compute.NewInstancesRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewInstancesRESTClient: %w",err)}deferinstancesClient.Close()getInstanceReq:=&computepb.GetInstanceRequest{Project:projectID,Zone:zone,Instance:instanceName,}instance,err:=instancesClient.Get(ctx,getInstanceReq)iferr!=nil{returnfmt.Errorf("unable to get instance: %w",err)}diskExists:=falsefor_,disk:=rangeinstance.GetDisks(){ifdisk.GetDeviceName()==diskName{diskExists=truebreak}}if!diskExists{returnfmt.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)iferr!=nil{returnfmt.Errorf("unable to set disk autodelete field: %w",err)}iferr=op.Wait(ctx);err!=nil{returnfmt.Errorf("unable to wait for the operation: %w",err)}fmt.Fprintf(w,"disk autoDelete field updated.\n")returnnil}Create backups of your data by using persistent disk snapshots.
As a precaution, create backups of your data while the persistent disks arestill attached to the VM by using persistent disk snapshots. Beforeyou take a snapshot, ensure that it is consistent with the state of thepersistent disk by adhering tosnapshot best practices.
Note: If you are running a Windows VM, the VM must be terminatedbefore you can create a snapshot. Follow the steps tocreate a snapshot for Windows VM.After you clear your disk buffers, create the snapshots:
import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1"computepb"cloud.google.com/go/compute/apiv1/computepb""google.golang.org/protobuf/proto")// createSnapshot creates a snapshot of a disk.funccreateSnapshot(wio.Writer,projectID,diskName,snapshotName,zone,region,location,diskProjectIDstring,)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)iferr!=nil{returnfmt.Errorf("NewSnapshotsRESTClient: %w",err)}defersnapshotsClient.Close()ifzone=="" &®ion==""{returnfmt.Errorf("you need to specify `zone` or `region` for this function to work")}ifzone!="" &®ion!=""{returnfmt.Errorf("you can't set both `zone` and `region` parameters")}ifdiskProjectID==""{diskProjectID=projectID}disk:=&computepb.Disk{}locations:=[]string{}iflocation!=""{locations=append(locations,location)}ifzone!=""{disksClient,err:=compute.NewDisksRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewDisksRESTClient: %w",err)}deferdisksClient.Close()getDiskReq:=&computepb.GetDiskRequest{Project:projectID,Zone:zone,Disk:diskName,}disk,err=disksClient.Get(ctx,getDiskReq)iferr!=nil{returnfmt.Errorf("unable to get disk: %w",err)}}else{regionDisksClient,err:=compute.NewRegionDisksRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewRegionDisksRESTClient: %w",err)}deferregionDisksClient.Close()getDiskReq:=&computepb.GetRegionDiskRequest{Project:projectID,Region:region,Disk:diskName,}disk,err=regionDisksClient.Get(ctx,getDiskReq)iferr!=nil{returnfmt.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)iferr!=nil{returnfmt.Errorf("unable to create snapshot: %w",err)}iferr=op.Wait(ctx);err!=nil{returnfmt.Errorf("unable to wait for the operation: %w",err)}fmt.Fprintf(w,"Snapshot created\n")returnnil}Delete your VM from the source zone.
import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1"computepb"cloud.google.com/go/compute/apiv1/computepb")// deleteInstance sends a delete request to the Compute Engine API and waits for it to complete.funcdeleteInstance(wio.Writer,projectID,zone,instanceNamestring)error{// projectID := "your_project_id"// zone := "europe-central2-b"// instanceName := "your_instance_name"ctx:=context.Background()instancesClient,err:=compute.NewInstancesRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewInstancesRESTClient: %w",err)}deferinstancesClient.Close()req:=&computepb.DeleteInstanceRequest{Project:projectID,Zone:zone,Instance:instanceName,}op,err:=instancesClient.Delete(ctx,req)iferr!=nil{returnfmt.Errorf("unable to delete instance: %w",err)}iferr=op.Wait(ctx);err!=nil{returnfmt.Errorf("unable to wait for the operation: %w",err)}fmt.Fprintf(w,"Instance deleted\n")returnnil}Next, create another snapshot of both the boot disk and the data disks.
import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1"computepb"cloud.google.com/go/compute/apiv1/computepb""google.golang.org/protobuf/proto")// createSnapshot creates a snapshot of a disk.funccreateSnapshot(wio.Writer,projectID,diskName,snapshotName,zone,region,location,diskProjectIDstring,)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)iferr!=nil{returnfmt.Errorf("NewSnapshotsRESTClient: %w",err)}defersnapshotsClient.Close()ifzone=="" &®ion==""{returnfmt.Errorf("you need to specify `zone` or `region` for this function to work")}ifzone!="" &®ion!=""{returnfmt.Errorf("you can't set both `zone` and `region` parameters")}ifdiskProjectID==""{diskProjectID=projectID}disk:=&computepb.Disk{}locations:=[]string{}iflocation!=""{locations=append(locations,location)}ifzone!=""{disksClient,err:=compute.NewDisksRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewDisksRESTClient: %w",err)}deferdisksClient.Close()getDiskReq:=&computepb.GetDiskRequest{Project:projectID,Zone:zone,Disk:diskName,}disk,err=disksClient.Get(ctx,getDiskReq)iferr!=nil{returnfmt.Errorf("unable to get disk: %w",err)}}else{regionDisksClient,err:=compute.NewRegionDisksRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewRegionDisksRESTClient: %w",err)}deferregionDisksClient.Close()getDiskReq:=&computepb.GetRegionDiskRequest{Project:projectID,Region:region,Disk:diskName,}disk,err=regionDisksClient.Get(ctx,getDiskReq)iferr!=nil{returnfmt.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)iferr!=nil{returnfmt.Errorf("unable to create snapshot: %w",err)}iferr=op.Wait(ctx);err!=nil{returnfmt.Errorf("unable to wait for the operation: %w",err)}fmt.Fprintf(w,"Snapshot created\n")returnnil}(Optional) Delete your persistent disks.
If you plan to reuse the names of the persistent disks for the newdisks, you must delete the existing disks to release the names. Deletingyour disks also saves on persistent disk storage costs.
If you do not plan to reuse the same disk names, you don't need to deletethem.
import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1"computepb"cloud.google.com/go/compute/apiv1/computepb")// deleteDisk deletes a disk from a project.funcdeleteDisk(wio.Writer,projectID,zone,diskNamestring)error{// projectID := "your_project_id"// zone := "us-west3-b"// diskName := "your_disk_name"ctx:=context.Background()disksClient,err:=compute.NewDisksRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewDisksRESTClient: %w",err)}deferdisksClient.Close()req:=&computepb.DeleteDiskRequest{Project:projectID,Zone:zone,Disk:diskName,}op,err:=disksClient.Delete(ctx,req)iferr!=nil{returnfmt.Errorf("unable to delete disk: %w",err)}iferr=op.Wait(ctx);err!=nil{returnfmt.Errorf("unable to wait for the operation: %w",err)}fmt.Fprintf(w,"Disk deleted\n")returnnil}Create new persistent disks in the destination zone from the snapshotsyou created. First create the boot disk, and then the data disks.
import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1"computepb"cloud.google.com/go/compute/apiv1/computepb""google.golang.org/protobuf/proto")// createDiskFromSnapshot creates a new disk in a project in given zone.funccreateDiskFromSnapshot(wio.Writer,projectID,zone,diskName,diskType,snapshotLinkstring,diskSizeGbint64,)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 := 120ctx:=context.Background()disksClient,err:=compute.NewDisksRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewDisksRESTClient: %w",err)}deferdisksClient.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)iferr!=nil{returnfmt.Errorf("unable to create disk: %w",err)}iferr=op.Wait(ctx);err!=nil{returnfmt.Errorf("unable to wait for the operation: %w",err)}fmt.Fprintf(w,"Disk created\n")returnnil}Recreate your VM with the new disks in the destination zone.
import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1"computepb"cloud.google.com/go/compute/apiv1/computepb""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.funccreateWithExistingDisks(wio.Writer,projectID,zone,instanceNamestring,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)iferr!=nil{returnfmt.Errorf("NewInstancesRESTClient: %w",err)}deferinstancesClient.Close()disksClient,err:=compute.NewDisksRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewDisksRESTClient: %w",err)}deferdisksClient.Close()disks:=[](*computepb.Disk){}for_,diskName:=rangediskNames{reqDisk:=&computepb.GetDiskRequest{Project:projectID,Zone:zone,Disk:diskName,}disk,err:=disksClient.Get(ctx,reqDisk)iferr!=nil{returnfmt.Errorf("unable to get disk: %w",err)}disks=append(disks,disk)}attachedDisks:=[](*computepb.AttachedDisk){}for_,disk:=rangedisks{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)iferr!=nil{returnfmt.Errorf("unable to create instance: %w",err)}iferr=op.Wait(ctx);err!=nil{returnfmt.Errorf("unable to wait for the operation: %w",err)}fmt.Fprintf(w,"Instance created\n")returnnil}(Optional) Delete the temporary disk snapshots.After you confirm that your virtual machines are moved, save on storagecosts by deleting the temporary snapshots that you created.
import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1"computepb"cloud.google.com/go/compute/apiv1/computepb")// deleteSnapshot deletes a snapshot of a disk.funcdeleteSnapshot(wio.Writer,projectID,snapshotNamestring)error{// projectID := "your_project_id"// snapshotName := "your_snapshot_name"ctx:=context.Background()snapshotsClient,err:=compute.NewSnapshotsRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewSnapshotsRESTClient: %w",err)}defersnapshotsClient.Close()req:=&computepb.DeleteSnapshotRequest{Project:projectID,Snapshot:snapshotName,}op,err:=snapshotsClient.Delete(ctx,req)iferr!=nil{returnfmt.Errorf("unable to delete snapshot: %w",err)}iferr=op.Wait(ctx);err!=nil{returnfmt.Errorf("unable to wait for the operation: %w",err)}fmt.Fprintf(w,"Snapshot deleted\n")returnnil}
Java
Get the details of the VM and identify the disks that are attached to the VM.
importcom.google.cloud.compute.v1.Instance;importcom.google.cloud.compute.v1.InstancesClient;importjava.io.IOException;publicclassGetInstance{publicstaticvoidmain(String[]args)throwsIOException{// TODO(developer): Replace these variables before running the sample.// Project ID or project number of the Cloud project you want to use.StringprojectId="YOUR_PROJECT_ID";// Name of the zone you want to use. For example: 'us-west3-b'.Stringzone="europe-central2-b";// Name of the VM instance you want to query.StringinstanceName="YOUR_INSTANCE_NAME";getInstance(projectId,zone,instanceName);}// Prints information about a VM instance in the given zone in the specified project.publicstaticvoidgetInstance(StringprojectId,Stringzone,StringinstanceName)throwsIOException{// 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(InstancesClientinstancesClient=InstancesClient.create()){Instanceinstance=instancesClient.get(projectId,zone,instanceName);System.out.printf("Retrieved the instance %s",instance.toString());}}}Set the auto-delete state of the boot disk and data disk to
falsetoensure that the disks are not automatically deleted when the VM isdeleted.importcom.google.cloud.compute.v1.Instance;importcom.google.cloud.compute.v1.InstancesClient;importcom.google.cloud.compute.v1.Operation;importcom.google.cloud.compute.v1.SetDiskAutoDeleteInstanceRequest;importjava.io.IOException;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassSetDiskAutodelete{publicstaticvoidmain(String[]args)throwsIOException,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.StringprojectId="YOUR_PROJECT_ID";// The zone of the disk that you want to modify.Stringzone="europe-central2-b";// Name of the instance the disk is attached to.StringinstanceName="YOUR_INSTANCE_NAME";// The name of the disk for which you want to modify the autodelete flag.StringdiskName="YOUR_DISK_NAME";// The new value of the autodelete flag.booleanautoDelete=true;setDiskAutodelete(projectId,zone,instanceName,diskName,autoDelete);}// Sets the autodelete flag of a disk to given value.publicstaticvoidsetDiskAutodelete(StringprojectId,Stringzone,StringinstanceName,StringdiskName,booleanautoDelete)throwsIOException,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(InstancesClientinstancesClient=InstancesClient.create()){// Retrieve the instance given by the instanceName.Instanceinstance=instancesClient.get(projectId,zone,instanceName);// Check if the instance contains a disk that matches the given diskName.booleandiskNameMatch=instance.getDisksList().stream().anyMatch(disk->disk.getDeviceName().equals(diskName));if(!diskNameMatch){thrownewError(String.format("Instance %s doesn't have a disk named %s attached",instanceName,diskName));}// Create the request object.SetDiskAutoDeleteInstanceRequestrequest=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.Operationresponse=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());}}}Create backups of your data by using persistent disk snapshots.
As a precaution, create backups of your data while the persistent disks arestill attached to the VM by using persistent disk snapshots. Beforeyou take a snapshot, ensure that it is consistent with the state of thepersistent disk by adhering tosnapshot best practices.
Note: If you are running a Windows VM, the VM must be terminatedbefore you can create a snapshot. Follow the steps tocreate a snapshot for Windows VM.After you clear your disk buffers, create the snapshots:
importcom.google.cloud.compute.v1.Disk;importcom.google.cloud.compute.v1.DisksClient;importcom.google.cloud.compute.v1.Operation;importcom.google.cloud.compute.v1.RegionDisksClient;importcom.google.cloud.compute.v1.Snapshot;importcom.google.cloud.compute.v1.SnapshotsClient;importjava.io.IOException;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassCreateSnapshot{publicstaticvoidmain(String[]args)throwsIOException,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.StringprojectId="YOUR_PROJECT_ID";// Name of the disk you want to create.StringdiskName="YOUR_DISK_NAME";// Name of the snapshot that you want to create.StringsnapshotName="YOUR_SNAPSHOT_NAME";// The zone of the source disk from which you create the snapshot (for zonal disks).Stringzone="europe-central2-b";// The region of the source disk from which you create the snapshot (for regional disks).Stringregion="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-locationsStringlocation="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.StringdiskProjectId="YOUR_DISK_PROJECT_ID";createSnapshot(projectId,diskName,snapshotName,zone,region,location,diskProjectId);}// Creates a snapshot of a disk.publicstaticvoidcreateSnapshot(StringprojectId,StringdiskName,StringsnapshotName,Stringzone,Stringregion,Stringlocation,StringdiskProjectId)throwsIOException,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(SnapshotsClientsnapshotsClient=SnapshotsClient.create()){if(zone.isEmpty() &®ion.isEmpty()){thrownewError("You need to specify 'zone' or 'region' for this function to work");}if(!zone.isEmpty() &&!region.isEmpty()){thrownewError("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.Diskdisk;if(!zone.isEmpty()){DisksClientdisksClient=DisksClient.create();disk=disksClient.get(projectId,zone,diskName);}else{RegionDisksClientregionDisksClient=RegionDisksClient.create();disk=regionDisksClient.get(diskProjectId,region,diskName);}// Set the snapshot properties.SnapshotsnapshotResource;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.Operationoperation=snapshotsClient.insertAsync(projectId,snapshotResource).get(3,TimeUnit.MINUTES);if(operation.hasError()){System.out.println("Snapshot creation failed!"+operation);return;}// Retrieve the created snapshot.Snapshotsnapshot=snapshotsClient.get(projectId,snapshotName);System.out.printf("Snapshot created: %s",snapshot.getName());}}}Delete your VM from the source zone.
importcom.google.api.gax.longrunning.OperationFuture;importcom.google.cloud.compute.v1.DeleteInstanceRequest;importcom.google.cloud.compute.v1.InstancesClient;importcom.google.cloud.compute.v1.Operation;importjava.io.IOException;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassDeleteInstance{publicstaticvoidmain(String[]args)throwsIOException,InterruptedException,ExecutionException,TimeoutException{// TODO(developer): Replace these variables before running the sample.Stringproject="your-project-id";Stringzone="zone-name";StringinstanceName="instance-name";deleteInstance(project,zone,instanceName);}// Delete the instance specified by `instanceName`// if it's present in the given project and zone.publicstaticvoiddeleteInstance(Stringproject,Stringzone,StringinstanceName)throwsIOException,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(InstancesClientinstancesClient=InstancesClient.create()){System.out.printf("Deleting instance: %s ",instanceName);// Describe which instance is to be deleted.DeleteInstanceRequestdeleteInstanceRequest=DeleteInstanceRequest.newBuilder().setProject(project).setZone(zone).setInstance(instanceName).build();OperationFuture<Operation,Operation>operation=instancesClient.deleteAsync(deleteInstanceRequest);// Wait for the operation to complete.Operationresponse=operation.get(3,TimeUnit.MINUTES);if(response.hasError()){System.out.println("Instance deletion failed ! ! "+response);return;}System.out.println("Operation Status: "+response.getStatus());}}}Next, create another snapshot of both the boot disk and the data disks.
importcom.google.cloud.compute.v1.Disk;importcom.google.cloud.compute.v1.DisksClient;importcom.google.cloud.compute.v1.Operation;importcom.google.cloud.compute.v1.RegionDisksClient;importcom.google.cloud.compute.v1.Snapshot;importcom.google.cloud.compute.v1.SnapshotsClient;importjava.io.IOException;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassCreateSnapshot{publicstaticvoidmain(String[]args)throwsIOException,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.StringprojectId="YOUR_PROJECT_ID";// Name of the disk you want to create.StringdiskName="YOUR_DISK_NAME";// Name of the snapshot that you want to create.StringsnapshotName="YOUR_SNAPSHOT_NAME";// The zone of the source disk from which you create the snapshot (for zonal disks).Stringzone="europe-central2-b";// The region of the source disk from which you create the snapshot (for regional disks).Stringregion="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-locationsStringlocation="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.StringdiskProjectId="YOUR_DISK_PROJECT_ID";createSnapshot(projectId,diskName,snapshotName,zone,region,location,diskProjectId);}// Creates a snapshot of a disk.publicstaticvoidcreateSnapshot(StringprojectId,StringdiskName,StringsnapshotName,Stringzone,Stringregion,Stringlocation,StringdiskProjectId)throwsIOException,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(SnapshotsClientsnapshotsClient=SnapshotsClient.create()){if(zone.isEmpty() &®ion.isEmpty()){thrownewError("You need to specify 'zone' or 'region' for this function to work");}if(!zone.isEmpty() &&!region.isEmpty()){thrownewError("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.Diskdisk;if(!zone.isEmpty()){DisksClientdisksClient=DisksClient.create();disk=disksClient.get(projectId,zone,diskName);}else{RegionDisksClientregionDisksClient=RegionDisksClient.create();disk=regionDisksClient.get(diskProjectId,region,diskName);}// Set the snapshot properties.SnapshotsnapshotResource;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.Operationoperation=snapshotsClient.insertAsync(projectId,snapshotResource).get(3,TimeUnit.MINUTES);if(operation.hasError()){System.out.println("Snapshot creation failed!"+operation);return;}// Retrieve the created snapshot.Snapshotsnapshot=snapshotsClient.get(projectId,snapshotName);System.out.printf("Snapshot created: %s",snapshot.getName());}}}(Optional) Delete your persistent disks.
If you plan to reuse the names of the persistent disks for the newdisks, you must delete the existing disks to release the names. Deletingyour disks also saves on persistent disk storage costs.
If you do not plan to reuse the same disk names, you don't need to deletethem.
importcom.google.cloud.compute.v1.DeleteDiskRequest;importcom.google.cloud.compute.v1.DisksClient;importcom.google.cloud.compute.v1.Operation;importjava.io.IOException;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassDeleteDisk{publicstaticvoidmain(String[]args)throwsIOException,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.StringprojectId="YOUR_PROJECT_ID";// The zone from where you want to delete the disk.Stringzone="europe-central2-b";// Name of the disk you want to delete.StringdiskName="YOUR_DISK_NAME";deleteDisk(projectId,zone,diskName);}// Deletes a disk from a project.publicstaticvoiddeleteDisk(StringprojectId,Stringzone,StringdiskName)throwsIOException,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(DisksClientdisksClient=DisksClient.create()){// Create the request object.DeleteDiskRequestdeleteDiskRequest=DeleteDiskRequest.newBuilder().setProject(projectId).setZone(zone).setDisk(diskName).build();// Wait for the delete disk operation to complete.Operationresponse=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());}}}Create new persistent disks in the destination zone from the snapshotsyou created. First create the boot disk, and then the data disks.
importcom.google.cloud.compute.v1.Disk;importcom.google.cloud.compute.v1.DisksClient;importcom.google.cloud.compute.v1.InsertDiskRequest;importcom.google.cloud.compute.v1.Operation;importjava.io.IOException;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassCreateDiskFromSnapshot{publicstaticvoidmain(String[]args)throwsIOException,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.StringprojectId="YOUR_PROJECT_ID";// Name of the zone in which you want to create the disk.Stringzone="europe-central2-b";// Name of the disk you want to create.StringdiskName="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"StringdiskType=String.format("zones/%s/diskTypes/pd-ssd",zone);// Size of the new disk in gigabytes.longdiskSizeGb=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}"StringsnapshotLink=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.publicstaticvoidcreateDiskFromSnapshot(StringprojectId,Stringzone,StringdiskName,StringdiskType,longdiskSizeGb,StringsnapshotLink)throwsIOException,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(DisksClientdisksClient=DisksClient.create()){// Set the disk properties and the source snapshot.Diskdisk=Disk.newBuilder().setName(diskName).setZone(zone).setSizeGb(diskSizeGb).setType(diskType).setSourceSnapshot(snapshotLink).build();// Create the insert disk request.InsertDiskRequestinsertDiskRequest=InsertDiskRequest.newBuilder().setProject(projectId).setZone(zone).setDiskResource(disk).build();// Wait for the create disk operation to complete.Operationresponse=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());}}}Recreate your VM with the new disks in the destination zone.
importcom.google.cloud.compute.v1.AttachedDisk;importcom.google.cloud.compute.v1.Disk;importcom.google.cloud.compute.v1.DisksClient;importcom.google.cloud.compute.v1.InsertInstanceRequest;importcom.google.cloud.compute.v1.Instance;importcom.google.cloud.compute.v1.InstancesClient;importcom.google.cloud.compute.v1.NetworkInterface;importcom.google.cloud.compute.v1.Operation;importjava.io.IOException;importjava.util.ArrayList;importjava.util.List;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassCreateInstanceWithExistingDisks{publicstaticvoidmain(String[]args)throwsIOException,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.StringprojectId="YOUR_PROJECT_ID";// Name of the zone to create the instance in. For example: "us-west3-b"Stringzone="europe-central2-b";// Name of the new virtual machine (VM) instance.StringinstanceName="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.publicstaticvoidcreateInstanceWithExistingDisks(StringprojectId,Stringzone,StringinstanceName,List<String>diskNames)throwsIOException,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(InstancesClientinstancesClient=InstancesClient.create();DisksClientdisksClient=DisksClient.create()){if(diskNames.size()==0){thrownewError("At least one disk should be provided");}// Create the list of attached disks to be used in instance creation.List<AttachedDisk>attachedDisks=newArrayList<>();for(inti=0;i <diskNames.size();i++){StringdiskName=diskNames.get(i);Diskdisk=disksClient.get(projectId,zone,diskName);AttachedDiskattDisk=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.Instanceinstance=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.InsertInstanceRequestinsertInstanceRequest=InsertInstanceRequest.newBuilder().setProject(projectId).setZone(zone).setInstanceResource(instance).build();// Wait for the create operation to complete.Operationresponse=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());}}}(Optional) Delete the temporary disk snapshots.After you confirm that your virtual machines are moved, save on storagecosts by deleting the temporary snapshots that you created.
importcom.google.cloud.compute.v1.Operation;importcom.google.cloud.compute.v1.SnapshotsClient;importjava.io.IOException;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassDeleteSnapshot{publicstaticvoidmain(String[]args)throwsIOException,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.StringprojectId="YOUR_PROJECT_ID";// Name of the snapshot to be deleted.StringsnapshotName="YOUR_SNAPSHOT_NAME";deleteSnapshot(projectId,snapshotName);}// Delete a snapshot of a disk.publicstaticvoiddeleteSnapshot(StringprojectId,StringsnapshotName)throwsIOException,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(SnapshotsClientsnapshotsClient=SnapshotsClient.create()){Operationoperation=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
Get the details of the VM and identify the disks that are attached to the VM.
/** * 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'constcompute=require('@google-cloud/compute');asyncfunctiongetInstance(){constinstancesClient=newcompute.InstancesClient();const[instance]=awaitinstancesClient.get({project:projectId,zone,instance:instanceName,});console.log(`Instance${instanceName} data:\n${JSON.stringify(instance,null,4)}`);}getInstance();Set the auto-delete state of the boot disk and data disk to
falsetoensure that the disks are not automatically deleted when the VM isdeleted./** * 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;constcompute=require('@google-cloud/compute');asyncfunctionsetDiskAutodelete(){constinstancesClient=newcompute.InstancesClient();const[instance]=awaitinstancesClient.get({project:projectId,zone,instance:instanceName,});if(!instance.disks.some(disk=>disk.deviceName===diskName)){thrownewError(`Instance${instanceName} doesn't have a disk named${diskName} attached.`);}const[response]=awaitinstancesClient.setDiskAutoDelete({project:projectId,zone,instance:instanceName,deviceName:diskName,autoDelete,});letoperation=response.latestResponse;constoperationsClient=newcompute.ZoneOperationsClient();// Wait for the update instance operation to complete.while(operation.status!=='DONE'){[operation]=awaitoperationsClient.wait({operation:operation.name,project:projectId,zone:operation.zone.split('/').pop(),});}console.log('Disk autoDelete field updated.');}setDiskAutodelete();Create backups of your data by using persistent disk snapshots.
As a precaution, create backups of your data while the persistent disks arestill attached to the VM by using persistent disk snapshots. Beforeyou take a snapshot, ensure that it is consistent with the state of thepersistent disk by adhering tosnapshot best practices.
Note: If you are running a Windows VM, the VM must be terminatedbefore you can create a snapshot. Follow the steps tocreate a snapshot for Windows VM.After you clear your disk buffers, create the 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';constcompute=require('@google-cloud/compute');asyncfunctioncreateSnapshot(){constsnapshotsClient=newcompute.SnapshotsClient();letdisk;if(!zone &&!region){thrownewError('You need to specify `zone` or `region` for this function to work.');}if(zone &®ion){thrownewError("You can't set both `zone` and `region` parameters");}if(!diskProjectId){diskProjectId=projectId;}if(zone){constdisksClient=newcompute.DisksClient();[disk]=awaitdisksClient.get({project:diskProjectId,zone,disk:diskName,});}else{constregionDisksClient=newcompute.RegionDisksClient();[disk]=awaitregionDisksClient.get({project:diskProjectId,region,disk:diskName,});}constsnapshotResource={name:snapshotName,sourceDisk:disk.selfLink,};if(location){snapshotResource.storageLocations=[location];}const[response]=awaitsnapshotsClient.insert({project:projectId,snapshotResource,});letoperation=response.latestResponse;constoperationsClient=newcompute.GlobalOperationsClient();// Wait for the create snapshot operation to complete.while(operation.status!=='DONE'){[operation]=awaitoperationsClient.wait({operation:operation.name,project:projectId,});}console.log('Snapshot created.');}createSnapshot();Delete your VM from the source zone.
/** * TODO(developer): Uncomment these variables before running the sample. */// const projectId = 'YOUR_PROJECT_ID';// const zone = 'europe-central2-b'// const instanceName = 'YOUR_INSTANCE_NAME';constcompute=require('@google-cloud/compute');// Delete the instance specified by `instanceName` if it's present in the given project and zone.asyncfunctiondeleteInstance(){constinstancesClient=newcompute.InstancesClient();console.log(`Deleting${instanceName} from${zone}...`);const[response]=awaitinstancesClient.delete({project:projectId,zone,instance:instanceName,});letoperation=response.latestResponse;constoperationsClient=newcompute.ZoneOperationsClient();// Wait for the delete operation to complete.while(operation.status!=='DONE'){[operation]=awaitoperationsClient.wait({operation:operation.name,project:projectId,zone:operation.zone.split('/').pop(),});}console.log('Instance deleted.');}deleteInstance();Next, create another snapshot of both the boot disk and the data disks.
/** * 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';constcompute=require('@google-cloud/compute');asyncfunctioncreateSnapshot(){constsnapshotsClient=newcompute.SnapshotsClient();letdisk;if(!zone &&!region){thrownewError('You need to specify `zone` or `region` for this function to work.');}if(zone &®ion){thrownewError("You can't set both `zone` and `region` parameters");}if(!diskProjectId){diskProjectId=projectId;}if(zone){constdisksClient=newcompute.DisksClient();[disk]=awaitdisksClient.get({project:diskProjectId,zone,disk:diskName,});}else{constregionDisksClient=newcompute.RegionDisksClient();[disk]=awaitregionDisksClient.get({project:diskProjectId,region,disk:diskName,});}constsnapshotResource={name:snapshotName,sourceDisk:disk.selfLink,};if(location){snapshotResource.storageLocations=[location];}const[response]=awaitsnapshotsClient.insert({project:projectId,snapshotResource,});letoperation=response.latestResponse;constoperationsClient=newcompute.GlobalOperationsClient();// Wait for the create snapshot operation to complete.while(operation.status!=='DONE'){[operation]=awaitoperationsClient.wait({operation:operation.name,project:projectId,});}console.log('Snapshot created.');}createSnapshot();(Optional) Delete your persistent disks.
If you plan to reuse the names of the persistent disks for the newdisks, you must delete the existing disks to release the names. Deletingyour disks also saves on persistent disk storage costs.
If you do not plan to reuse the same disk names, you don't need to deletethem.
/** * 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';constcompute=require('@google-cloud/compute');asyncfunctiondeleteDisk(){constdisksClient=newcompute.DisksClient();const[response]=awaitdisksClient.delete({project:projectId,zone,disk:diskName,});letoperation=response.latestResponse;constoperationsClient=newcompute.ZoneOperationsClient();// Wait for the create disk operation to complete.while(operation.status!=='DONE'){[operation]=awaitoperationsClient.wait({operation:operation.name,project:projectId,zone:operation.zone.split('/').pop(),});}console.log('Disk deleted.');}deleteDisk();Create new persistent disks in the destination zone from the snapshotsyou created. First create the boot disk, and then the data disks.
/** * 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';constcompute=require('@google-cloud/compute');asyncfunctioncreateDiskFromSnapshot(){constdisksClient=newcompute.DisksClient();const[response]=awaitdisksClient.insert({project:projectId,zone,diskResource:{sizeGb:diskSizeGb,name:diskName,zone,type:diskType,sourceSnapshot:snapshotLink,},});letoperation=response.latestResponse;constoperationsClient=newcompute.ZoneOperationsClient();// Wait for the create disk operation to complete.while(operation.status!=='DONE'){[operation]=awaitoperationsClient.wait({operation:operation.name,project:projectId,zone:operation.zone.split('/').pop(),});}console.log('Disk created.');}createDiskFromSnapshot();Recreate your VM with the new disks in the destination zone.
/** * 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'];constcompute=require('@google-cloud/compute');asyncfunctioncreateWithExistingDisks(){constinstancesClient=newcompute.InstancesClient();constdisksClient=newcompute.DisksClient();if(diskNames.length <1){thrownewError('At least one disk should be provided');}constdisks=[];for(constdiskNameofdiskNames){const[disk]=awaitdisksClient.get({project:projectId,zone,disk:diskName,});disks.push(disk);}constattachedDisks=[];for(constdiskofdisks){attachedDisks.push({source:disk.selfLink,});}attachedDisks[0].boot=true;const[response]=awaitinstancesClient.insert({project:projectId,zone,instanceResource:{name:instanceName,disks:attachedDisks,machineType:`zones/${zone}/machineTypes/n1-standard-1`,networkInterfaces:[{name:'global/networks/default',},],},});letoperation=response.latestResponse;constoperationsClient=newcompute.ZoneOperationsClient();// Wait for the create operation to complete.while(operation.status!=='DONE'){[operation]=awaitoperationsClient.wait({operation:operation.name,project:projectId,zone:operation.zone.split('/').pop(),});}console.log('Instance created.');}createWithExistingDisks();(Optional) Delete the temporary disk snapshots.After you confirm that your virtual machines are moved, save on storagecosts by deleting the temporary snapshots that you created.
/** * TODO(developer): Uncomment and replace these variables before running the sample. */// const projectId = 'YOUR_PROJECT_ID';// const snapshotName = 'YOUR_SNAPSHOT_NAME';constcompute=require('@google-cloud/compute');asyncfunctiondeleteSnapshot(){constsnapshotsClient=newcompute.SnapshotsClient();const[response]=awaitsnapshotsClient.delete({project:projectId,snapshot:snapshotName,});letoperation=response.latestResponse;constoperationsClient=newcompute.GlobalOperationsClient();// Wait for the create disk operation to complete.while(operation.status!=='DONE'){[operation]=awaitoperationsClient.wait({operation:operation.name,project:projectId,});}console.log('Snapshot deleted.');}deleteSnapshot();
Python
Get the details of the VM and identify the disks that are attached to the VM.
fromgoogle.cloudimportcompute_v1defget_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)returninstanceSet the auto-delete state of the boot disk and data disk to
falsetoensure that the disks are not automatically deleted when the VM isdeleted.from__future__importannotationsimportsysfromtypingimportAnyfromgoogle.api_core.extended_operationimportExtendedOperationfromgoogle.cloudimportcompute_v1defwait_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)ifoperation.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)raiseoperation.exception()orRuntimeError(operation.error_message)ifoperation.warnings:print(f"Warnings during{verbose_name}:\n",file=sys.stderr,flush=True)forwarninginoperation.warnings:print(f" -{warning.code}:{warning.message}",file=sys.stderr,flush=True)returnresultdefset_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)fordiskininstance.disks:ifdisk.device_name==disk_name:breakelse:raiseRuntimeError(f"Instance{instance_name} doesn't have a disk named{disk_name} attached.")disk.auto_delete=autodeleteoperation=instance_client.update(project=project_id,zone=zone,instance=instance_name,instance_resource=instance,)wait_for_extended_operation(operation,"disk update")Create backups of your data by using persistent disk snapshots.
As a precaution, create backups of your data while the persistent disks arestill attached to the VM by using persistent disk snapshots. Beforeyou take a snapshot, ensure that it is consistent with the state of thepersistent disk by adhering tosnapshot best practices.
Note: If you are running a Windows VM, the VM must be terminatedbefore you can create a snapshot. Follow the steps tocreate a snapshot for Windows VM.After you clear your disk buffers, create the snapshots:
from__future__importannotationsimportsysfromtypingimportAnyfromgoogle.api_core.extended_operationimportExtendedOperationfromgoogle.cloudimportcompute_v1defwait_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)ifoperation.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)raiseoperation.exception()orRuntimeError(operation.error_message)ifoperation.warnings:print(f"Warnings during{verbose_name}:\n",file=sys.stderr,flush=True)forwarninginoperation.warnings:print(f" -{warning.code}:{warning.message}",file=sys.stderr,flush=True)returnresultdefcreate_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. """ifzoneisNoneandregionisNone:raiseRuntimeError("You need to specify `zone` or `region` for this function to work.")ifzoneisnotNoneandregionisnotNone:raiseRuntimeError("You can't set both `zone` and `region` parameters.")ifdisk_project_idisNone:disk_project_id=project_idifzoneisnotNone: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_linksnapshot.name=snapshot_nameiflocation: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")returnsnapshot_client.get(project=project_id,snapshot=snapshot_name)Delete your VM from the source zone.
from__future__importannotationsimportsysfromtypingimportAnyfromgoogle.api_core.extended_operationimportExtendedOperationfromgoogle.cloudimportcompute_v1defwait_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)ifoperation.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)raiseoperation.exception()orRuntimeError(operation.error_message)ifoperation.warnings:print(f"Warnings during{verbose_name}:\n",file=sys.stderr,flush=True)forwarninginoperation.warnings:print(f" -{warning.code}:{warning.message}",file=sys.stderr,flush=True)returnresultdefdelete_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=compcompute_v1tInstancesClientprint(f"Deleting{machine_name} from{zone}...")operation=instinstance_client.deleteproject=project_id,zone=zone,instance=machine_name)wait_for_extended_operation(operation,"instance deletion")print(f"Instance{machine_name} deleted.")Next, create another snapshot of both the boot disk and the data disks.
from__future__importannotationsimportsysfromtypingimportAnyfromgoogle.api_core.extended_operationimportExtendedOperationfromgoogle.cloudimportcompute_v1defwait_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)ifoperation.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)raiseoperation.exception()orRuntimeError(operation.error_message)ifoperation.warnings:print(f"Warnings during{verbose_name}:\n",file=sys.stderr,flush=True)forwarninginoperation.warnings:print(f" -{warning.code}:{warning.message}",file=sys.stderr,flush=True)returnresultdefcreate_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. """ifzoneisNoneandregionisNone:raiseRuntimeError("You need to specify `zone` or `region` for this function to work.")ifzoneisnotNoneandregionisnotNone:raiseRuntimeError("You can't set both `zone` and `region` parameters.")ifdisk_project_idisNone:disk_project_id=project_idifzoneisnotNone: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_linksnapshot.name=snapshot_nameiflocation: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")returnsnapshot_client.get(project=project_id,snapshot=snapshot_name)(Optional) Delete your persistent disks.
If you plan to reuse the names of the persistent disks for the newdisks, you must delete the existing disks to release the names. Deletingyour disks also saves on persistent disk storage costs.
If you do not plan to reuse the same disk names, you don't need to deletethem.
from__future__importannotationsimportsysfromtypingimportAnyfromgoogle.api_core.extended_operationimportExtendedOperationfromgoogle.cloudimportcompute_v1defwait_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)ifoperation.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)raiseoperation.exception()orRuntimeError(operation.error_message)ifoperation.warnings:print(f"Warnings during{verbose_name}:\n",file=sys.stderr,flush=True)forwarninginoperation.warnings:print(f" -{warning.code}:{warning.message}",file=sys.stderr,flush=True)returnresultdefdelete_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")Create new persistent disks in the destination zone from the snapshotsyou created. First create the boot disk, and then the data disks.
from__future__importannotationsimportsysfromtypingimportAnyfromgoogle.api_core.extended_operationimportExtendedOperationfromgoogle.cloudimportcompute_v1defwait_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)ifoperation.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)raiseoperation.exception()orRuntimeError(operation.error_message)ifoperation.warnings:print(f"Warnings during{verbose_name}:\n",file=sys.stderr,flush=True)forwarninginoperation.warnings:print(f" -{warning.code}:{warning.message}",file=sys.stderr,flush=True)returnresultdefcreate_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=zonedisk.size_gb=disk_size_gbdisk.source_snapshot=snapshot_linkdisk.type_=disk_typedisk.name=disk_nameoperation=disk_client.insert(project=project_id,zone=zone,disk_resource=disk)wait_for_extended_operation(operation,"disk creation")returndisk_client.get(project=project_id,zone=zone,disk=disk_name)Recreate your VM with the new disks in the destination zone.
from__future__importannotationsimportreimportsysfromtypingimportAnyimportwarningsfromgoogle.api_core.extended_operationimportExtendedOperationfromgoogle.cloudimportcompute_v1defget_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()returndisk_client.get(project=project_id,zone=zone,disk=disk_name)defwait_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)ifoperation.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)raiseoperation.exception()orRuntimeError(operation.error_message)ifoperation.warnings:print(f"Warnings during{verbose_name}:\n",file=sys.stderr,flush=True)forwarninginoperation.warnings:print(f" -{warning.code}:{warning.message}",file=sys.stderr,flush=True)returnresultdefcreate_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_linkifsubnetwork_link:network_interface.subnetwork=subnetwork_linkifinternal_ip:network_interface.network_i_p=internal_ipifexternal_access:access=compute_v1.AccessConfig()access.type_=compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.nameaccess.name="External NAT"access.network_tier=access.NetworkTier.PREMIUM.nameifexternal_ipv4:access.nat_i_p=external_ipv4network_interface.access_configs=[access]# Collect information into the Instance object.instance=compute_v1.Instance()instance.network_interfaces=[network_interface]instance.name=instance_nameinstance.disks=disksifre.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$",machine_type):instance.machine_type=machine_typeelse:instance.machine_type=f"zones/{zone}/machineTypes/{machine_type}"instance.scheduling=compute_v1.Scheduling()ifaccelerators:instance.guest_accelerators=acceleratorsinstance.scheduling.on_host_maintenance=(compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name)ifpreemptible:# Set the preemptible settingwarnings.warn("Preemptible VMs are being replaced by Spot VMs.",DeprecationWarning)instance.scheduling=compute_v1.Scheduling()instance.scheduling.preemptible=Trueifspot:# Set the Spot VM settinginstance.scheduling.provisioning_model=(compute_v1.Scheduling.ProvisioningModel.SPOT.name)instance.scheduling.instance_termination_action=instance_termination_actionifcustom_hostnameisnotNone:# Set the custom hostname for the instanceinstance.hostname=custom_hostnameifdelete_protection:# Set the delete protection bitinstance.deletion_protection=True# Prepare the request to insert an instance.request=compute_v1.InsertInstanceRequest()request.zone=zonerequest.project=project_idrequest.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.")returninstance_client.get(project=project_id,zone=zone,instance=instance_name)defcreate_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. """assertlen(disk_names) >=1disks=[get_disk(project_id,zone,disk_name)fordisk_nameindisk_names]attached_disks=[]fordiskindisks:adisk=compute_v1.AttachedDisk()adisk.source=disk.self_linkattached_disks.append(adisk)attached_disks[0].boot=Trueinstance=create_instance(project_id,zone,instance_name,attached_disks)returninstance(Optional) Delete the temporary disk snapshots.After you confirm that your virtual machines are moved, save on storagecosts by deleting the temporary snapshots that you created.
from__future__importannotationsimportsysfromtypingimportAnyfromgoogle.api_core.extended_operationimportExtendedOperationfromgoogle.cloudimportcompute_v1defwait_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)ifoperation.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)raiseoperation.exception()orRuntimeError(operation.error_message)ifoperation.warnings:print(f"Warnings during{verbose_name}:\n",file=sys.stderr,flush=True)forwarninginoperation.warnings:print(f" -{warning.code}:{warning.message}",file=sys.stderr,flush=True)returnresultdefdelete_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")
What's next
- Learn how tochange the default zone/region for your project.
- Learn aboutlive migration.
- Check a VM'sstatus.
- Learn aboutmigrating VMs to Compute Engine.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-15 UTC.