Duplicate a disk with clones Stay organized with collections Save and categorize content based on your preferences.
This document provides information about how disk clones work and how to createa disk clone. Disk cloning lets you make instantly usable duplicates of existingdisks. Create a disk clone in scenarios where you want to create an identicalcopy of an existing disk that you can instantly attach to a VM, such as thefollowing:
- Creating staging environments by duplicating production data to debug withoutdisturbing production
- Creating copies for database backup verification
- Moving non-boot disk data to a new project
- Duplicating disks while scaling out your VMs
To protect against disaster recovery, back up your disk withstandard snapshots instead of usingdisk clones. To capture disk contents at regular intervals without creating newdisks, useinstant snapshots becausethey're more storage-efficient than clones. For additional disk protectionoptions, seeData protection options.
Before you begin
- If you haven't already, then set up authentication.Authentication is the process by which your identity is verified 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:
Console
When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.
gcloud
Afterinstalling the Google Cloud CLI,initialize it 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.
Terraform
To use the Terraform 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.
Toinitialize the gcloud CLI, run the following command:
gcloudinit
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.
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.
Toinitialize the gcloud CLI, run the following command:
gcloudinit
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.
Toinitialize the gcloud CLI, run the following command:
gcloudinit
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.
Toinitialize the gcloud CLI, run the following command:
gcloudinit
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.
REST
To use the REST API samples on this page in a local development environment, you use the credentials you provide to the gcloud CLI.
Afterinstalling the Google Cloud CLI,initialize it 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.
For more information, seeAuthenticate for using REST in the Google Cloud authentication documentation.
How disk cloning works
When you clone a disk, you create a new disk that contains all the data on thesource disk. You can create a disk clone even if the existing disk is attachedto a VM instance.
The disk type of the clone must be the same as that of the source disk. However,you can modify properties on the clone, such as the disk size. You can alsodelete the source disk without any risk of deleting the clone.
Supported disk types
You can create disk clones only for the following disk types:
- Persistent Disk: All types of Persistent Disk
- Google Cloud Hyperdisk:
- Hyperdisk Balanced
- Hyperdisk Balanced High Availability
- Hyperdisk Extreme
- Hyperdisk Throughput
Restrictions
Depending on the type of disk, disk clones have the following restrictions:
General restrictions
The following restrictions apply to clones of all disk types:
- Thedisk type of the clonemust be the same as that of the source disk.
- You can't create a zonal disk clone of an existing zonal disk in a differentzone.
- The size of the clone must be at least the size of the source disk. If youcreate a clone using the Google Cloud console, then you can't specify a disk sizeand the clone will be the same size as the source disk.
- If you use acustomer-supplied encryption keyor acustomer-managed encryption keyto encrypt the source disk, you must use the same key to encrypt the clone.For more information, seeCreating a clone of an encrypted source disk.
- You can't delete the source disk while its clone is being created.
- The compute instance that the source disk is attached to won't be able topower on while the clone is being created.
- If the source disk was marked to be deleted along with the VM that it isattached to, then you can't delete the VM while the clone is being created.
- You can create at most one clone of a given source disk or its clones every 30seconds.
- You can have at most 1000 simultaneous disk clones of a given sourcedisk or its clones.Exceeding this limit returns an
internalError
.However, if you create a disk clone and delete it later, then the deleteddisk clone is not included in this limit. - After a disk is cloned, any subsequent clones of that disk or of its clonesare counted against the limit of 1000 simultaneous disk clones for theoriginal source disk and are counted against the limit of creating at mostone clone every 30 seconds.
- If you create a regional disk by cloning a zonal disk, then you can cloneat most 1 TiB of capacity every15 minutes, with a burst requestlimit of 257 TiB.
Restrictions for Persistent Disk clones
Disk clones for Persistent Disk have the following restrictions:
- You can't create a zonal disk clone from a regional disk.
- To create a regional disk clone from a zonal source disk, one of thereplica zonesof the regional disk clone must match the zone of the source disk.
- After creation, a regional disk clone is usable within 3 minutes, onaverage. However, the disk might take tens of minutes to become fullyreplicated and reach a state where therecovery point objective (RPO)is near zero.
- If you created a zonal disk from an image, then you can't use that zonal diskto create a regional disk clone.
Restrictions for Google Cloud Hyperdisk clones
You can't create a Hyperdisk Balanced High Availability disk by cloning a zonal disk. To create aHyperdisk Balanced High Availability disk from an existing zonal disk, complete the steps inChange a zonal disk to a regional Hyperdisk Balanced High Availability disk.
You can't clone Hyperdisk ML volumes.
Error messages
If you exceed the cloning frequency limits, the request fails with the followingerror:
RATE LIMIT: ERROR: (gcloud.compute.disks.create) Could not fetch resource: - Operation rate exceeded for resourceRESOURCE. Too frequent operations from the source resource.
Create disk clones
This section explains how you can duplicate an existing disk and create a diskclone.
For detailed steps, depending on the type of disk clone creation, see one of thefollowing sections in this document:
- Create a zonal disk clone
- Create a regional disk clone from a zonal disk
- Create a clone of an encrypted source disk
Permissions required for this task
To perform this task, you must have the followingpermissions:
compute.disks.create
on the projectcompute.disks.useReadOnly
on the source disk
Create a zonal disk clone
You can create zonal disk clones of an existing disk in the same zone as thesource disk by using the Google Cloud console, the Google Cloud CLI, orREST.
Console
In the Google Cloud console, go to theDisks page.
In the list of disks, navigate to the disk that you want to clone.
In theActions column, click the
menu button andselectClone disk.In theClone disk panel that appears, do the following:
- In theName field, specify a name for the cloned disk.
- ForLocation, verify thatSingle zone is selected.
- UnderProperties, review other details for the cloned disk.
- To finish creating the cloned disk, clickCreate.
gcloud
To clone a zonal source disk and create a new zonal disk, run thedisks create
commandand specify the--source-disk
flag:
gcloud compute disks createTARGET_DISK_NAME \ --description="cloned disk" \ --source-disk=projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME
Replace the following:
TARGET_DISK_NAME
: the name for the new disk.PROJECT_ID
: theproject IDwhere you want to clone the disk.ZONE
: the zone of the source and new disk.SOURCE_DISK_NAME
: the name of the source disk.
Terraform
To create a disk clone, use thegoogle_compute_disk
resource.
resource "google_compute_disk" "default" { name = "disk-name1" type = "pd-ssd" zone = "us-central1-a" image = "debian-11-bullseye-v20220719" labels = { environment = "dev" } physical_block_size_bytes = 4096}
To learn how to apply or remove a Terraform configuration, seeBasic Terraform commands.
Go
Go
Before trying this sample, follow theGo setup instructions in theCompute Engine quickstart using client libraries. For more information, see theCompute EngineGo API reference documentation.
To authenticate to Compute Engine, set up Application Default Credentials. For more information, seeSet up authentication for a local development environment.
import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1"computepb"cloud.google.com/go/compute/apiv1/computepb""google.golang.org/protobuf/proto")// createDiskFromDisk creates a new disk with the contents of// an already existitng disk. Type, and size and zone may differ.funccreateDiskFromDisk(wio.Writer,projectID,zone,diskName,diskType,sourceDiskLinkstring,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"// sourceDiskLink := "projects/your_project_id/global/disks/disk_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),SourceDisk:proto.String(sourceDiskLink),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}
Java
Java
Before trying this sample, follow theJava setup instructions in theCompute Engine quickstart using client libraries. For more information, see theCompute EngineJava API reference documentation.
To authenticate to Compute Engine, set up Application Default Credentials. For more information, seeSet up authentication for a local development environment.
importcom.google.cloud.compute.v1.Disk;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;publicclassCreateFromSource{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.Stringproject="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.intdiskSizeGb=10;// A link to the disk you want to use as a source for the new disk.// This value uses the following format:// "projects/{project_name}/zones/{zone}/disks/{disk_name}"StringdiskLink=String.format("projects/%s/zones/%s/disks/%s","PROJECT_NAME","ZONE","DISK_NAME");createDiskFromDisk(project,zone,diskName,diskType,diskSizeGb,diskLink);}// Creates a disk in a project in a given zone.publicstaticvoidcreateDiskFromDisk(Stringproject,Stringzone,StringdiskName,StringdiskType,intdiskSizeGb,StringdiskLink)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 disk.Diskdisk=Disk.newBuilder().setZone(zone).setSizeGb(diskSizeGb).setSourceDisk(diskLink).setType(diskType).setName(diskName).build();// Wait for the insert instance operation to complete.Operationoperation=disksClient.insertAsync(project,zone,disk).get(3,TimeUnit.MINUTES);if(operation.hasError()){System.out.println("Disk creation failed!");thrownewError(operation.getError().toString());}System.out.println("Disk created from source. Operation Status: "+operation.getStatus());}}}
Python
Python
Before trying this sample, follow thePython setup instructions in theCompute Engine quickstart using client libraries. For more information, see theCompute EnginePython API reference documentation.
To authenticate to Compute Engine, set up Application Default Credentials. For more information, seeSet up authentication for a local development environment.
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_disk(project_id:str,zone:str,disk_name:str,disk_type:str,disk_size_gb:int,disk_link:str,)->compute_v1.Disk:""" Creates a disk in a project in a 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 disk_link: a link to the disk you want to use as a source for the new disk. This value uses the following format: "projects/{project_name}/zones/{zone}/disks/{disk_name}" Returns: An attachable disk. """disk_client=compute_v1.DisksClient()disk=compute_v1.Disk()disk.zone=zonedisk.size_gb=disk_size_gbdisk.source_disk=disk_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)
REST
To clone a zonal source disk and create a new zonal disk, make aPOST
request to thecompute.disks.insert
method.In the request body, specify thename
andsourceDisk
parameters. Thedisk clone inherits all omitted properties from the source disk.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/disks{ "name": "TARGET_DISK_NAME" "sourceDisk": "projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME"}
Replace the following:
PROJECT_ID
: theproject IDwhere you want to clone the disk.ZONE
: the zone of the source and new disk.TARGET_DISK_NAME
: the name for the new disk.SOURCE_DISK_NAME
: the name of the source disk
Create a regional disk clone from a zonal disk
You can create a new regional Persistent Disk disk by cloning an existing zonalPersistent Disk volume. To migrate a zonal disk to a regional disk, Googlerecommends this option instead of creating a snapshot of the zonal disk andrestoring the snapshot to a new regional disk.
Console
In the Google Cloud console, go to theDisks page.
In the list of disks, navigate to the zonal Persistent Disk volume that youwant to clone.
In theActions column, click the
menu button andselectClone disk.In theClone disk panel that appears, do the following:
- In theName field, specify a name for the cloned disk.
- ForLocation, selectRegional and then select the secondaryreplica zone for the new regional cloned disk.
- UnderProperties, review other details for the cloned disk.
- To finish creating the cloned disk, clickCreate.
gcloud
To create a regional disk clone from a zonal disk, run thegcloud compute disks create
commandand specify the--region
and--replica-zones
parameters.
gcloud compute disks createTARGET_DISK_NAME \ --description="zonal to regional cloned disk" \ --region=CLONED_REGION \ --source-disk=SOURCE_DISK_NAME \ --source-disk-zone=SOURCE_DISK_ZONE \ --replica-zones=SOURCE_DISK_ZONE,REPLICA_ZONE_2 \ --project=PROJECT_ID
Replace the following:
TARGET_DISK_NAME
: the name for the new regional diskclone.CLONED_REGION
: the region of the source and cloneddisks.SOURCE_DISK_NAME
: the name of the zonal disk toclone.SOURCE_DISK_ZONE
: the zone for the source disk. Thiswill also be the first replica zone for the regional disk clone.REPLICA_ZONE_2
: the second replica zone forthe new regional disk clone.PROJECT_ID
: theproject IDwhere you want to clone the disk.
Terraform
To create a regional disk clone from a zonal disk, you can optionally create asnapshot of the zonal disk and then clone the snapshot. To do this, use thefollowing resources:
resource "google_compute_region_disk" "regiondisk" { name = "region-disk-name" snapshot = google_compute_snapshot.snapdisk.id type = "pd-ssd" region = "us-central1" physical_block_size_bytes = 4096 size = 11 replica_zones = ["us-central1-a", "us-central1-f"]}
To learn how to apply or remove a Terraform configuration, seeBasic Terraform commands.
Go
Go
Before trying this sample, follow theGo setup instructions in theCompute Engine quickstart using client libraries. For more information, see theCompute EngineGo API reference documentation.
To authenticate to Compute Engine, set up Application Default Credentials. For more information, seeSet up authentication for a local development environment.
import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1"computepb"cloud.google.com/go/compute/apiv1/computepb""google.golang.org/protobuf/proto")// createRegionalDiskFromDisk creates a new regional disk with the contents of// an already existitng zonal disk. Disk type and size may differ.funccreateRegionalDiskFromDisk(wio.Writer,projectID,regionstring,replicaZones[]string,diskName,diskType,sourceDiskLinkstring,diskSizeGbint64,)error{// projectID := "your_project_id"// region := "us-west3" // should match diskType below// diskName := "your_disk_name"// diskType := "regions/us-west3/diskTypes/pd-ssd"// sourceDiskLink := "projects/your_project_id/global/disks/disk_name"// diskSizeGb := 120// Exactly two replica zones must be specifiedreplicaZoneURLs:=[]string{fmt.Sprintf("projects/%s/zones/%s",projectID,replicaZones[0]),fmt.Sprintf("projects/%s/zones/%s",projectID,replicaZones[1]),}ctx:=context.Background()disksClient,err:=compute.NewRegionDisksRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewRegionDisksRESTClient: %w",err)}deferdisksClient.Close()req:=&computepb.InsertRegionDiskRequest{Project:projectID,Region:region,DiskResource:&computepb.Disk{Name:proto.String(diskName),Region:proto.String(region),Type:proto.String(diskType),SourceDisk:proto.String(sourceDiskLink),SizeGb:proto.Int64(diskSizeGb),ReplicaZones:replicaZoneURLs,},}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}
Java
Java
Before trying this sample, follow theJava setup instructions in theCompute Engine quickstart using client libraries. For more information, see theCompute EngineJava API reference documentation.
To authenticate to Compute Engine, set up Application Default Credentials. For more information, seeSet up authentication for a local development environment.
importcom.google.cloud.compute.v1.Disk;importcom.google.cloud.compute.v1.Operation;importcom.google.cloud.compute.v1.RegionDisksClient;importjava.io.IOException;importjava.util.ArrayList;importjava.util.List;importjava.util.Optional;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassRegionalCreateFromSource{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.Stringproject="YOUR_PROJECT_ID";// Name of the zone in which you want to create the disk.Stringregion="europe-central2";// An iterable collection of zone names in which you want to keep// the new disks' replicas. One of the replica zones of the clone must match// the zone of the source disk.List<String>replicaZones=newArrayList<>();// 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_NAME");// Size of the new disk in gigabytes.intdiskSizeGb=10;// A link to the disk you want to use as a source for the new disk.// This value uses the following format:// "projects/{project_name}/zones/{zone}/disks/{disk_name}"StringdiskLink=String.format("projects/%s/zones/%s/disks/%s","PROJECT_NAME","ZONE","DISK_NAME");// 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}"StringsnapshotLink=String.format("projects/%s/global/snapshots/%s","PROJECT_NAME","SNAPSHOT_NAME");createRegionalDisk(project,region,replicaZones,diskName,diskType,diskSizeGb,Optional.ofNullable(diskLink),Optional.ofNullable(snapshotLink));}// Creates a regional disk from an existing zonal disk in a given project.publicstaticvoidcreateRegionalDisk(Stringproject,Stringregion,List<String>replicaZones,StringdiskName,StringdiskType,intdiskSizeGb,Optional<String>diskLink,Optional<String>snapshotLink)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 `regionDisksClient.close()` method on the client to safely// clean up any remaining background resources.try(RegionDisksClientregionDisksClient=RegionDisksClient.create()){Disk.BuilderdiskBuilder=Disk.newBuilder().addAllReplicaZones(replicaZones).setName(diskName).setType(diskType).setSizeGb(diskSizeGb).setRegion(region);// Set source disk if diskLink is not empty.diskLink.ifPresent(diskBuilder::setSourceDisk);// Set source snapshot if the snapshot link is not empty.snapshotLink.ifPresent(diskBuilder::setSourceSnapshot);// Wait for the operation to complete.Operationoperation=regionDisksClient.insertAsync(project,region,diskBuilder.build()).get(3,TimeUnit.MINUTES);if(operation.hasError()){System.out.println("Disk creation failed!");thrownewError(operation.getError().toString());}System.out.println("Regional disk created. Operation Status: "+operation.getStatus());}}}
Python
Python
Before trying this sample, follow thePython setup instructions in theCompute Engine quickstart using client libraries. For more information, see theCompute EnginePython API reference documentation.
To authenticate to Compute Engine, set up Application Default Credentials. For more information, seeSet up authentication for a local development environment.
from__future__importannotationsfromcollections.abcimportIterableimportsysfromtypingimportAnyfromgoogle.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_regional_disk(project_id:str,region:str,replica_zones:Iterable[str],disk_name:str,disk_type:str,disk_size_gb:int,disk_link:str|None=None,snapshot_link:str|None=None,)->compute_v1.Disk:""" Creates a regional disk from an existing zonal disk in a given project. Args: project_id: project ID or project number of the Cloud project you want to use. region: name of the region in which you want to create the disk. replica_zones: an iterable collection of zone names in which you want to keep the new disks' replicas. One of the replica zones of the clone must match the zone of the source 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: "regions/{region}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)". For example: "regions/us-west3/diskTypes/pd-ssd" disk_size_gb: size of the new disk in gigabytes disk_link: a link to the disk you want to use as a source for the new disk. This value uses the following format: "projects/{project_name}/zones/{zone}/disks/{disk_name}" 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 attachable regional disk. """disk_client=compute_v1.RegionDisksClient()disk=compute_v1.Disk()disk.replica_zones=replica_zonesdisk.size_gb=disk_size_gbifdisk_link:disk.source_disk=disk_linkifsnapshot_link:disk.source_snapshot=snapshot_linkdisk.type_=disk_typedisk.region=regiondisk.name=disk_nameoperation=disk_client.insert(project=project_id,region=region,disk_resource=disk)wait_for_extended_operation(operation,"disk creation")returndisk_client.get(project=project_id,region=region,disk=disk_name)
REST
To create a regional disk clone from a zonal disk, make aPOST
request tothecompute.disks.insert
methodand specify thesourceDisk
andreplicaZone
parameters.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/CLONED_REGION/disks{ "name": "TARGET_DISK_NAME" "sourceDisk": "projects/PROJECT_ID/zones/SOURCE_DISK_ZONE/disks/SOURCE_DISK_NAME" "replicaZone": "SOURCE_DISK_ZONE,REPLICA_ZONE_2"}
Replace the following:
PROJECT_ID
: theproject IDwhere you want to clone the disk.TARGET_DISK_NAME
: the name for the new regional diskclone.CLONED_REGION
: the region of the source and cloneddisks.SOURCE_DISK_NAME
: the name of the zonal disk toclone.SOURCE_DISK_ZONE
: the zone for the source disk. Thiswill also be the first replica zone for the regional disk clone.REPLICA_ZONE_2
: the second replica zone forthe new regional disk clone.
Create a disk clone of an encrypted source disk
You can use acustomer-supplied encryption key (CSEK)or acustomer-managed encryption keyto encrypt your disks.
Create disk clones for CSEK-encrypted disks
If you use a CSEK to encrypt your source disk, you must also use the same keyto encrypt the clone.
Console
In the Google Cloud console, go to theDisks page.
In the list of zonal persistent disks, find the disk that you want toclone.
In theActions column, click the
menu button andselectClone disk.In theClone disk panel that appears, do the following:
- In theName field, specify a name for the cloned disk.
- In theDecryption and encryption field, provide the source diskencryption key.
- UnderProperties, review other details for the cloned disk.
- To finish creating the cloned disk, clickCreate.
gcloud
To create a disk clone for a CSEK-encrypted source disk, run thegcloud compute disks create
commandand provide the source disk encryption key using the--csek-key-file
flag. If you are using an RSA-wrapped key, use thegcloud beta compute disks create
command.
gcloud compute disks createTARGET_DISK_NAME \ --description="cloned disk" \ --source-disk=projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME \ --csek-key-file example-key-file.json
Replace the following:
TARGET_DISK_NAME
: the name for the new disk.PROJECT_ID
: theproject IDwhere you want to clone the disk.ZONE
: the zone of the source and new disk.SOURCE_DISK_NAME
: the name of the source disk
Go
Go
Before trying this sample, follow theGo setup instructions in theCompute Engine quickstart using client libraries. For more information, see theCompute EngineGo API reference documentation.
To authenticate to Compute Engine, set up Application Default Credentials. For more information, seeSet up authentication for a local development environment.
import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1"computepb"cloud.google.com/go/compute/apiv1/computepb""google.golang.org/protobuf/proto")// Creates a zonal non-boot persistent disk in a project with the copy of data from an existing disk.// The encryption key must be the same for the source disk and the new disk.// The disk type and size may differ.funccreateDiskFromCustomerEncryptedDisk(wio.Writer,projectID,zone,diskName,diskTypestring,diskSizeGbint64,diskLink,encryptionKeystring,)error{// projectID := "your_project_id"// zone := "us-west3-b" // should match diskType below// diskName := "your_disk_name"// diskType := "zones/us-west3/diskTypes/pd-ssd"// diskSizeGb := 120// diskLink := "projects/your_project_id/global/disks/disk_name"// encryptionKey := "SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=" // in base64ctx:=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),SizeGb:proto.Int64(diskSizeGb),SourceDisk:proto.String(diskLink),DiskEncryptionKey:&computepb.CustomerEncryptionKey{RawKey:&encryptionKey,},},}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}
Java
Java
Before trying this sample, follow theJava setup instructions in theCompute Engine quickstart using client libraries. For more information, see theCompute EngineJava API reference documentation.
To authenticate to Compute Engine, set up Application Default Credentials. For more information, seeSet up authentication for a local development environment.
importcom.google.cloud.compute.v1.CustomerEncryptionKey;importcom.google.cloud.compute.v1.Disk;importcom.google.cloud.compute.v1.DisksClient;importcom.google.cloud.compute.v1.InsertDiskRequest;importcom.google.cloud.compute.v1.Operation;importcom.google.protobuf.ByteString;importjava.io.IOException;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassCloneEncryptedDisk{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.Stringproject="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.intdiskSizeGb=10;// A link to the disk you want to use as a source for the new disk.// This value uses the following format:// "projects/{project_name}/zones/{zone}/disks/{disk_name}"StringdiskLink=String.format("projects/%s/zones/%s/disks/%s","PROJECT_NAME","ZONE","DISK_NAME");// Customer-supplied encryption key used for encrypting data in the source disk.// The data will be encrypted with the same key in the new disk.byte[]encryptionKey=null;createDiskFromCustomerEncryptedKey(project,zone,diskName,diskType,diskSizeGb,diskLink,encryptionKey);}// Creates a zonal non-boot persistent disk in a project with the copy of data// from an existing disk.// The encryption key must be the same for the source disk and the new disk.publicstaticvoidcreateDiskFromCustomerEncryptedKey(Stringproject,Stringzone,StringdiskName,StringdiskType,intdiskSizeGb,StringdiskLink,byte[]encryptionKey)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 a disk and set the encryption key.Diskdisk=Disk.newBuilder().setZone(zone).setName(diskName).setType(diskType).setSizeGb(diskSizeGb).setSourceDisk(diskLink).setDiskEncryptionKey(CustomerEncryptionKey.newBuilder().setRawKeyBytes(ByteString.copyFrom(encryptionKey)).build()).build();// Wait for the insert disk operation to complete.Operationoperation=disksClient.insertAsync(InsertDiskRequest.newBuilder().setProject(project).setZone(zone).setDiskResource(disk).build()).get(3,TimeUnit.MINUTES);if(operation.hasError()){System.out.println("Disk creation failed!");thrownewError(operation.getError().toString());}System.out.println("Disk cloned with customer encryption key. Operation Status: "+operation.getStatus());}}}
Python
Python
Before trying this sample, follow thePython setup instructions in theCompute Engine quickstart using client libraries. For more information, see theCompute EnginePython API reference documentation.
To authenticate to Compute Engine, set up Application Default Credentials. For more information, seeSet up authentication for a local development environment.
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_customer_encrypted_disk(project_id:str,zone:str,disk_name:str,disk_type:str,disk_size_gb:int,disk_link:str,encryption_key:bytes,)->compute_v1.Disk:""" Creates a zonal non-boot persistent disk in a project with the copy of data from an existing disk. The encryption key must be the same for the source disk and the new disk. 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 disk_link: a link to the disk you want to use as a source for the new disk. This value uses the following format: "projects/{project_name}/zones/{zone}/disks/{disk_name}" encryption_key: customer-supplied encryption key used for encrypting data in the source disk. The data will be encrypted with the same key in the new disk. Returns: An attachable copy of an existing disk. """disk_client=compute_v1.DisksClient()disk=compute_v1.Disk()disk.zone=zonedisk.size_gb=disk_size_gbdisk.source_disk=disk_linkdisk.type_=disk_typedisk.name=disk_namedisk.disk_encryption_key=compute_v1.CustomerEncryptionKey()disk.disk_encryption_key.raw_key=encryption_keyoperation=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)
REST
To create a disk clone for a CSEK-encrypted source disk, make aPOST
requestto thecompute.disks.insert
methodand provide the source disk encryption key using thediskEncryptionKey
property. If you are using an RSA-wrapped key, usethebeta
version of the method.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/disks{ "name": "TARGET_DISK_NAME" "sourceDisk": "projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME" "diskEncryptionKey": { "rsaEncryptedKey": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBibXUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+gJWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA==" },}
Replace the following:
PROJECT_ID
: theproject IDwhere you want to clone the disk.ZONE
: the zone of the source and new disk.TARGET_DISK_NAME
: the name for the new disk.SOURCE_DISK_NAME
: the name of the source disk
Create disk clones for CMEK-encrypted disks
If you use a CMEK to encrypt your source disk, you must also use the same keyto encrypt the clone.
Console
Compute Engine automatically encrypts the clone using the source diskencryption key.
gcloud
To create a disk clone for a CMEK-encrypted source disk, run thegcloud compute disks create
commandand provide the source disk encryption key using the--kms-key
flag.If you are using an RSA-wrapped key, use thegcloud beta compute disks create
command.
gcloud compute disks createTARGET_DISK_NAME \ --description="cloned disk" \ --source-disk=projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME \ --kms-key projects/KMS_PROJECT_ID/locations/REGION/keyRings/KEY_RING/cryptoKeys/KEY
Replace the following:
TARGET_DISK_NAME
: the name for the new disk.PROJECT_ID
: theproject IDwhere you want to clone the disk.ZONE
: the zone of the source and new disk.SOURCE_DISK_NAME
: the name of the source disk.KMS_PROJECT_ID
: the project ID for the encryptionkey.REGION
: the region of the encryption key.KEY_RING
: thekey ring of the encryption key.KEY
: the name of the encryption key.
Go
Go
Before trying this sample, follow theGo setup instructions in theCompute Engine quickstart using client libraries. For more information, see theCompute EngineGo API reference documentation.
To authenticate to Compute Engine, set up Application Default Credentials. For more information, seeSet up authentication for a local development environment.
import("context""fmt""io"compute"cloud.google.com/go/compute/apiv1"computepb"cloud.google.com/go/compute/apiv1/computepb""google.golang.org/protobuf/proto")// Creates a zonal non-boot persistent disk in a project with the copy of data from an existing disk.// The encryption key must be the same for the source disk and the new disk.// The disk type and size may differ.funccreateDiskFromKmsEncryptedDisk(wio.Writer,projectID,zone,diskName,diskTypestring,diskSizeGbint64,diskLink,kmsKeyLinkstring,)error{// projectID := "your_project_id"// zone := "us-west3-b" // should match diskType below// diskName := "your_disk_name"// diskType := "zones/us-west3/diskTypes/pd-ssd"// diskSizeGb := 120// diskLink := "projects/your_project_id/global/disks/disk_name"// kmsKeyLink := "projects/your_kms_project_id/locations/us-central1/keyRings/your_key_ring/cryptoKeys/your_key"ctx:=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),SizeGb:proto.Int64(diskSizeGb),SourceDisk:proto.String(diskLink),DiskEncryptionKey:&computepb.CustomerEncryptionKey{KmsKeyName:&kmsKeyLink,},},}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}
Java
Java
Before trying this sample, follow theJava setup instructions in theCompute Engine quickstart using client libraries. For more information, see theCompute EngineJava API reference documentation.
To authenticate to Compute Engine, set up Application Default Credentials. For more information, seeSet up authentication for a local development environment.
importcom.google.cloud.compute.v1.CustomerEncryptionKey;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;publicclassCloneEncryptedDiskManagedKey{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.Stringproject="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.intdiskSizeGb=10;// A link to the disk you want to use as a source for the new disk.// This value uses the following format:// "projects/{project_name}/zones/{zone}/disks/{disk_name}"StringdiskLink=String.format("projects/%s/zones/%s/disks/%s","PROJECT_NAME","ZONE","DISK_NAME");// URL of the key from KMS. The key might be from another project, as// long as you have access to it. The data will be encrypted with the same key// in the new disk. This value uses following format:// "projects/{kms_project_id}/locations/{region}/keyRings/{key_ring}/cryptoKeys/{key}"StringkmsKeyName="kms-key-name";createDiskFromKmsEncryptedDisk(project,zone,diskName,diskType,diskSizeGb,diskLink,kmsKeyName);}// Creates a zonal non-boot disk in a project with the copy of data from an existing disk.// The encryption key must be the same for the source disk and the new disk.publicstaticvoidcreateDiskFromKmsEncryptedDisk(Stringproject,Stringzone,StringdiskName,StringdiskType,intdiskSizeGb,StringdiskLink,StringkmsKeyName)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 a disk and set the KMS encryption key name.Diskdisk=Disk.newBuilder().setZone(zone).setName(diskName).setType(diskType).setSizeGb(diskSizeGb).setSourceDisk(diskLink).setDiskEncryptionKey(CustomerEncryptionKey.newBuilder().setKmsKeyName(kmsKeyName).build()).build();// Wait for the insert disk operation to complete.Operationoperation=disksClient.insertAsync(InsertDiskRequest.newBuilder().setProject(project).setZone(zone).setDiskResource(disk).build()).get(3,TimeUnit.MINUTES);if(operation.hasError()){System.out.println("Disk creation failed!");thrownewError(operation.getError().toString());}System.out.println("Disk cloned with KMS encryption key. Operation Status: "+operation.getStatus());}}}
Python
Python
Before trying this sample, follow thePython setup instructions in theCompute Engine quickstart using client libraries. For more information, see theCompute EnginePython API reference documentation.
To authenticate to Compute Engine, set up Application Default Credentials. For more information, seeSet up authentication for a local development environment.
from__future__importannotationsimportsysfromtypingimportAnyfromgoogle.api_core.exceptionsimportBadRequestfromgoogle.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_kms_encrypted_disk(project_id:str,zone:str,disk_name:str,disk_type:str,disk_size_gb:int,disk_link:str,kms_key_name:str,)->compute_v1.Disk:""" Creates a zonal non-boot disk in a project with the copy of data from an existing disk. The encryption key must be the same for the source disk and the new disk. To run this method, the service-<project_id>@compute-system.iam.gserviceaccount.com service account needs to have the cloudkms.cryptoKeyEncrypterDecrypter role, as described in documentation: https://cloud.google.com/compute/docs/disks/customer-managed-encryption#before_you_begin 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 disk_link: a link to the disk you want to use as a source for the new disk. This value uses the following format: "projects/{project_name}/zones/{zone}/disks/{disk_name}" kms_key_name: URL of the key from KMS. The key might be from another project, as long as you have access to it. The data will be encrypted with the same key in the new disk. This value uses following format: "projects/{kms_project_id}/locations/{region}/keyRings/{key_ring}/cryptoKeys/{key}" Returns: An attachable copy of an existing disk. """disk_client=compute_v1.DisksClient()disk=compute_v1.Disk()disk.zone=zonedisk.size_gb=disk_size_gbdisk.source_disk=disk_linkdisk.type_=disk_typedisk.name=disk_namedisk.disk_encryption_key=compute_v1.CustomerEncryptionKey()disk.disk_encryption_key.kms_key_name=kms_key_nametry:operation=disk_client.insert(project=project_id,zone=zone,disk_resource=disk)exceptBadRequestaserr:if"Permission 'cloudkms.cryptoKeyVersions.useToEncrypt' denied"inerr.message:print(f"Please provide the cloudkms.cryptoKeyEncrypterDecrypter role to"f"service-{project_id}@compute-system.iam.gserviceaccount.com")raiseerrwait_for_extended_operation(operation,"disk creation")returndisk_client.get(project=project_id,zone=zone,disk=disk_name)
REST
To create a disk clone for a CMEK-encrypted source disk, make aPOST
requestto thecompute.disks.insert
methodand provide the source disk encryption key using thekmsKeyName
property.If you are using an RSA-wrapped key, usethebeta
version of the method.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/disks{ "name": "TARGET_DISK_NAME" "sourceDisk": "projects/PROJECT_ID/zones/ZONE/disks/SOURCE_DISK_NAME" "diskEncryptionKey": { "kmsKeyName": "projects/KMS_PROJECT_ID/locations/REGION/keyRings/KEY_RING/cryptoKeys/KEY" },}
Replace the following:
PROJECT_ID
: theproject IDwhere you want to clone the disk.ZONE
: the zone of the source and new disk.TARGET_DISK_NAME
: the name for the new disk.SOURCE_DISK_NAME
: the name of the source disk.KMS_PROJECT_ID
: the project ID for the encryptionkey.REGION
: the region of the encryption key.KEY_RING
: thekey ring of the encryption key.KEY
: the name of the encryption key.
What's next
- Learn how to regularlybackup your disks using standard snapshotsto prevent unintended data loss.
- Learn how tobackup your disks in place using instant snapshots.
- Learn about usingregional persistent disksfor synchronous replication between two zones.
- Learn aboutAsynchronous Replication.
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-07-16 UTC.