Create custom images Stay organized with collections Save and categorize content based on your preferences.
You can create custom images from source disks, images, snapshots, or imagesstored in Cloud Storage and use these images to create virtual machine (VM)instances. Custom images are ideal for situations where you have created andmodified a persistent boot disk or specific image to a certain state and need tosave that state for creating VMs.
Alternatively, you can use thevirtual disk importtool to import boot disk imagesto Compute Engine from your existing systems and add them to your customimages list.
Note: If you want to create incremental backups of your persistent disk data,usesnapshots instead.Before you begin
- Read theImages document.
- 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:
Console
When you use the Google Cloud console to access Google Cloud services and APIs, you don't need to set up authentication.
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.
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.
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.For more information, seeAuthenticate for using REST in the Google Cloud authentication documentation.
Create a custom image
This section describes how to create a custom image on a Linux VM. Forinformation about creating a Windows image, seeCreating a Windowsimage.
Select an image storage location
When creating a custom image, you can specify the image'sCloud Storage location, excluding dual-regionlocations. By specifying the image storage location, you can meet yourregulatory and compliance requirements for data locality as well as your highavailability needs by providing redundancy across regions. To create, modify,and delete images stored in Cloud Storage, you must haveroles/compute.storageAdmin.
The storage location feature is optional. If you don't select a location,Compute Engine stores your image in the multi-region closest to theimage source. For example, when you create an image from a source disk that islocated inus-central1 and if you don't specify a location for the customimage, then Compute Engine stores the image in theus multi-region.
If the image is not available in a region where you are creating aVM, Compute Engine caches the image in that region the first time youcreate a VM.
To see the location where an image is stored, use theimages describecommand fromgcloud compute:
gcloud compute images describeIMAGE_NAME \ --project=PROJECT_ID
Replace the following:
IMAGE_NAME: the name of your image.
PROJECT_ID: the project ID to which the image belongs.
All of your existing images prior to this feature launch remain where they are,the only change is that you can view the image location of all your images. Ifyou have an existing image you want to move, you must recreate it in the newlocation.
Prepare your VM for an image
You can create an image from a disk even while it is attached to a runningVM. However, your image is more reliable if you put the VMin a state that is easier for the image to capture. This section describes howto prepare your boot disk for the image.
Minimize writing data to the persistent disk
Use one of the following processes to reduce the disk writes:
Stop the VMso that it can shut down and stop writing any data to the persistent disk.
If you can't stop your VM before you create the image, minimize theamount of writes to the disk and sync your file system. To minimizewriting to your persistent disk, follow these steps:
- Pause apps or operating system processes that write data tothat persistent disk.
- Run an app flush to disk if necessary. For example, MySQL has a
FLUSHstatement. Other apps might have similar processes. - Stop your apps from writing to your persistent disk.
- Run
sudo sync.
Disable the auto-delete option for the disk
By default, the auto-delete option is enabled on the boot disks. Before creatingan image from a disk, disable auto-delete to prevent the disk from beingautomatically deleted when you delete the VM.To disable auto-delete for the disk, use one of the following methods:
Console
In the Google Cloud console, go to theVM instances page.
Click the name of the VM that you're using as the source for creatingan image.
TheVM instance details page displays.
ClickEdit.
In theBoot disk section, for theDeletion rule, check thattheKeep disk option is selected.
ClickSave.
gcloud
In the Google Cloud CLI, use thegcloud compute instances set-disk-auto-delete commandto disable the auto-delete option for the disk.
gcloud compute instances set-disk-auto-deleteVM_NAME \ --no-auto-delete \ --disk=SOURCE_DISK
Replace the following:
VM_NAME: the name of your VM instance.SOURCE_DISK: the name of the disk from which you want to create the image.
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")// 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}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.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());}}}Node.js
Node.js
Before trying this sample, follow theNode.js setup instructions in theCompute Engine quickstart using client libraries. For more information, see theCompute EngineNode.js API reference documentation.
To authenticate to Compute Engine, set up Application Default Credentials. For more information, seeSet up authentication for a local development environment.
/** * 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();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)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")REST
To set the auto-delete option of a disk, make aPOST request to theinstances.setDiskAutoDelete method.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/VM_NAME/setDiskAutoDelete?autoDelete=false&deviceName=SOURCE_DISK
Replace the following:
PROJECT_ID: the project ID to which the source VM belongs.ZONE: the zone where the source VM is located.VM_NAME: the name of the source VM.SOURCE_DISK: the device name of the disk from whichyou want to create the image.
After you prepare the VM,create the image.
Create the image
You can create disk images from the following sources:- A persistent disk, even while that disk is attached to a VM
- A snapshot of a persistent disk
- Another image in your project
- An image that is shared from another project
- Acompressed RAW imagein Cloud Storage
You can create a disk image once every 10 minutes. If you want to issuea burst of requests to create a disk image, you can issue at most 6 requestsin 60 minutes. For more information, seeSnapshot frequency limits.
Console
In the Google Cloud console, go to theCreate an image page.
Specify theName of your image.
Specify theSource from which you want to create an image. Thiscan be a persistent disk, a snapshot, another image, or a disk.raw filein Cloud Storage.
If you are creating an image from a disk attached to a running VM,checkKeep instance running to confirm that you want to create theimage while the VM is running. You canprepare your VMbefore creating the image.
In theBased on source disk location (default) drop-down list,specify the location to store the image. For example, specify
ustostore the image in theusmulti-region, orus-central1to store it intheus-central1region. If you don't make a selection,Compute Engine stores the image in the multi-region closest toyour image's source location.Optional: specify the properties for your image.
- Family: theimage familythis new image belongs to.
- Description: a description for your custom image.
- Label: alabel to grouptogether resources.
Specify the encryption key. You can choose between a Google-owned and Google-managed encryption key,aCloud Key Management Service (Cloud KMS) key or acustomer-supplied encryption (CSEK)key. If no encryption key is specified, images are encryptedusing a Google-owned and Google-managed encryption key.
ClickCreate to create the image.
gcloud
In the Google Cloud CLI, use thegcloud compute images create commandto create a custom image.
Create an image from a source disk:
The--force flag is an optional flag that lets you create theimage from a running instance. By default, you cannot create images from runninginstances. Specify this flag only if you are sure that you want to createthe image while the instance is running.
gcloud compute images createIMAGE_NAME \ --source-disk=SOURCE_DISK \ --source-disk-zone=ZONE \ [--family=IMAGE_FAMILY] \ [--storage-location=LOCATION] \ [--force]
Replace the following:
IMAGE_NAME: a name for the new imageSOURCE_DISK: the disk from which you want to create the imageZONE: the zone where the disk is locatedIMAGE_FAMILY: Optional: a flag that specifies whichimage family this image belongs toLOCATION: Optional: a flag that lets you designate the region or multi-region where your image is stored. For example, specifyusto store the image in theusmulti-region, orus-central1to store it in theus-central1region. If you don't make a selection, Compute Engine stores the image in the multi-region closest to your image's source location.
Create an image from a source image:
gcloud compute images createIMAGE_NAME \ --source-image=SOURCE_IMAGE \ [--source-image-project=IMAGE_PROJECT] \ [--family=IMAGE_FAMILY] \ [--storage-location=LOCATION]
Replace the following:
IMAGE_NAME: a name for the new image.SOURCE_IMAGE: the image from which you want tocreate the new image.IMAGE_PROJECT: Optional: the project the sourceimage is located in. Use this parameter if you want to copy an image fromanother project.IMAGE_FAMILY: Optional: theimage family this new imagebelongs to.LOCATION: Optional: lets you designate the regionor multi-region where your image is stored. For example, specifyustostore the image in theusmulti-region, orus-central1to store it intheus-central1region. If you don't make a selection,Compute Engine stores the image in the multi-region closest toyour image's source location.
Create an image from a snapshot:
gcloud compute images createIMAGE_NAME \ --source-snapshot=SOURCE_SNAPSHOT \ [--storage-location=LOCATION]
Replace the following:
IMAGE_NAME: a name for the new imageSOURCE_SNAPSHOT: the snapshot from which you want to create the imageLOCATION: Optional: a flag that lets you designate the region or multi-region where your image is stored. For example, specifyusto store the image in theusmulti-region, orus-central1to store it in theus-central1region. If you don't make a selection, Compute Engine stores the image in the multi-region closest to your image's source location.
View an image location:
Use thegcloud compute images describe commandto view an image location.
gcloud compute images describeIMAGE_NAME
ReplaceIMAGE_NAME with the name of your image thatyou want to review.
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")// Creates a disk image from an existing diskfunccreateImageFromDisk(wio.Writer,projectID,zone,sourceDiskName,imageNamestring,storageLocations[]string,forceCreatebool,)error{// projectID := "your_project_id"// zone := "us-central1-a"// sourceDiskName := "your_disk_name"// imageName := "my_image"// // If storageLocations empty, automatically selects the closest one to the source// storageLocations = []string{}// // If forceCreate is set to `true`, proceeds even if the disk is attached to// // a running instance. This may compromise integrity of the image!// forceCreate = falsectx:=context.Background()disksClient,err:=compute.NewDisksRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewDisksRESTClient: %w",err)}deferdisksClient.Close()imagesClient,err:=compute.NewImagesRESTClient(ctx)iferr!=nil{returnfmt.Errorf("NewImagesRESTClient: %w",err)}deferimagesClient.Close()// Get the source disksource_req:=&computepb.GetDiskRequest{Disk:sourceDiskName,Project:projectID,Zone:zone,}disk,err:=disksClient.Get(ctx,source_req)iferr!=nil{returnfmt.Errorf("unable to get source disk: %w",err)}// Create the imagereq:=computepb.InsertImageRequest{ForceCreate:&forceCreate,ImageResource:&computepb.Image{Name:&imageName,SourceDisk:disk.SelfLink,StorageLocations:storageLocations,},Project:projectID,}op,err:=imagesClient.Insert(ctx,&req)iferr=op.Wait(ctx);err!=nil{returnfmt.Errorf("unable to wait for the operation: %w",err)}fmt.Fprintf(w,"Disk image %s created\n",imageName)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.Image;importcom.google.cloud.compute.v1.ImagesClient;importcom.google.cloud.compute.v1.InsertImageRequest;importcom.google.cloud.compute.v1.Instance;importcom.google.cloud.compute.v1.InstancesClient;importcom.google.cloud.compute.v1.Operation;importjava.io.IOException;importjava.util.Arrays;importjava.util.HashMap;importjava.util.Map;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.TimeoutException;publicclassCreateImage{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 use.Stringproject="your-project-id";// Zone of the disk you copy from.Stringzone="europe-central2-b";// Name of the source disk you copy from.StringsourceDiskName="source-disk-name";// Name of the image you want to create.StringimageName="your-image-name";// Storage location for the image. If the value is undefined,// function will store the image in the multi-region closest to your image's source location.StringstorageLocation="eu";// Create the image even if the source disk is attached to a running instance.booleanforceCreate=false;createImage(project,zone,sourceDiskName,imageName,storageLocation,forceCreate);}// Creates a new disk image from the specified source disk.publicstaticvoidcreateImage(Stringproject,Stringzone,StringsourceDiskName,StringimageName,StringstorageLocation,booleanforceCreate)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 `client.close()` method on the client to safely// clean up any remaining background resources.try(ImagesClientimagesClient=ImagesClient.create();InstancesClientinstancesClient=InstancesClient.create();DisksClientdisksClient=DisksClient.create()){Diskdisk=disksClient.get(project,zone,sourceDiskName);// Getting instances where source disk is attached.for(StringfullInstanceName:disk.getUsersList()){Map<String,String>instanceInfo=parseInstanceName(fullInstanceName);Instanceinstance=instancesClient.get(instanceInfo.get("instanceProjectId"),instanceInfo.get("instanceZone"),instanceInfo.get("instanceName"));// Сheck whether the instances are stopped.if(!Arrays.asList("TERMINATED","STOPPED").contains(instance.getStatus()) &&!forceCreate){thrownewIllegalStateException(String.format("Instance %s should be stopped. For Windows instances please stop the instance "+"using GCESysprep command. For Linux instances just shut it down normally."+" You can suppress this error and create an image of the disk by setting "+"'forceCreate' parameter to true (not recommended). "+"More information here: "+"* https://cloud.google.com/compute/docs/instances/windows/creating-windows-os-image#api"+"* https://cloud.google.com/compute/docs/images/create-delete-deprecate-private-images#prepare_instance_for_image",instanceInfo.get("instanceName")));}}if(forceCreate){System.out.println("Warning: forceCreate option compromise the integrity of your image. "+"Stop the instance before you create the image if possible.");}// Create Image.IImageimage=IImagenewBuilder().setName(imageName).setSourceDisk(String.format("/zones/%s/disks/%s",zone,sourceDiskName)).addStorageLocations(storageLocation.isEmpty()?"":storageLocation).build();IInsertImageRequestinsertImageRequest=IInsertImageRequestnewBuilder().setProject(project).ssetForceCreateforceCreate).setImageResource(image).build();OOperationresponse=imagesClient.insertAsync(insertImageRequest).get(5,TimeUnit.MINUTES);if(rresponse.hasError(){System.out.println("Image creation failed ! ! "+response);return;}System.out.println("Image created.");}}publicstaticMap<String,String>parseInstanceName(Stringname){String[]parsedName=name.split("/");intsplitLength=parsedName.length;if(splitLength <5){thrownewIllegalArgumentException("Provide correct instance name in the following format: "+"https://www.googleapis.com/compute/v1/projects/PROJECT/zones/ZONE/instances/INSTANCE_NAME");}returnnewHashMap<>(){{put("instanceName",parsedName[splitLength-1]);put("instanceZone",parsedName[splitLength-3]);put("instanceProjectId",parsedName[splitLength-5]);}};}}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__importannotationsimportsysfromtypingimportAnyimportwarningsfromgoogle.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)returnresultSTOPPED_MACHINE_STATUS=(compute_v1.Instance.Status.TERMINATED.name,compute_v1.Instance.Status.STOPPED.name,)defcreate_image_from_disk(project_id:str,zone:str,source_disk_name:str,image_name:str,storage_location:str|None=None,force_create:bool=False,)->compute_v1.Image:""" Creates a new disk image. Args: project_id: project ID or project number of the Cloud project you use. zone: zone of the disk you copy from. source_disk_name: name of the source disk you copy from. image_name: name of the image you want to create. storage_location: storage location for the image. If the value is undefined, function will store the image in the multi-region closest to your image's source location. force_create: create the image even if the source disk is attached to a running instance. Returns: An Image object. """image_client=compute_v1.ImagesClient()disk_client=compute_v1.DisksClient()instance_client=compute_v1.InstancesClient()# Get source diskdisk=disk_client.get(project=project_id,zone=zone,disk=source_disk_name)fordisk_userindisk.users:instance_name=disk_user.split("/")[-1]instance=instance_client.get(project=project_id,zone=zone,instance=instance_name)ifinstance.statusinSTOPPED_MACHINE_STATUS:continueifnotforce_create:raiseRuntimeError(f"Instance{disk_user} should be stopped. For Windows instances please "f"stop the instance using `GCESysprep` command. For Linux instances just "f"shut it down normally. You can supress this error and create an image of"f"the disk by setting `force_create` parameter to true (not recommended).\n"f"More information here:\n"f" * https://cloud.google.com/compute/docs/instances/windows/creating-windows-os-image#api\n"f" * https://cloud.google.com/compute/docs/images/create-delete-deprecate-private-images#prepare_instance_for_image")else:warnings.warn(f"Warning: The `force_create` option may compromise the integrity of your image. "f"Stop the{disk_user} instance before you create the image if possible.")# Create imageimage=compute_v1.Image()image.source_disk=disk.self_linkimage.name=image_nameifstorage_location:image.storage_locations=[storage_location]operation=image_client.insert(project=project_id,image_resource=image)wait_for_extended_operation(operation,"image creation from disk")returnimage_client.get(project=project_id,image=image_name)REST
Make aPOST request to theimages().insert method,a URL in the request body that points to the source object from whichyou want to create the image. Specify URLs to your resources using yourown project ID and resource names.
Create an image from a persistent disk:
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/images{ "name": "IMAGE_NAME", "sourceDisk": "/zones/ZONE/disks/SOURCE_DISK", ("storageLocations": "LOCATION",) ("forceCreate": "TRUE")}Replace the following:
PROJECT_ID: the project ID to which the image belongs.IMAGE_NAME: a name for the new image that you wantto create.ZONE: the zone where the source disk is located.SOURCE_DISK: the disk from which you want to createthe image.LOCATION: Optional: the storage location of yourimage. For example, specifyusto store the image in theusmulti-region, orus-central1to store it in theus-central1region.If you don't make a selection, Compute Engine stores theimage in the multi-region closest to your image's source location.
The optionalforceCreate parameter lets you create the image from arunning VM. SpecifyTRUE only if you are sure that you want tocreate the image from a running VM. TheforceCreate default settingisFALSE.
Create an image from another image:
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/images{ "name": "IMAGE_NAME", "sourceImage": "/global/images/SOURCE_IMAGE", ("storageLocations": "LOCATION")}Replace the following:
PROJECT_ID: the project to which the imagebelongs.IMAGE_NAME: a name for the new image that youwant to create.SOURCE_IMAGE: the image from which you want tocreate the image.LOCATION: Optional: the storage location of yourimage. For example, specifyusto store the image in theusmulti-region, orus-central1to store it in theus-central1region. If you don't make a selection, Compute Engine storesthe image in the multi-region closest to your image's source location.
Create an image from a snapshot:
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/images{ "name": "IMAGE_NAME", "sourceSnapshot": "(/SOURCE_PROJECT_ID)/global/snapshots/SOURCE_SNAPSHOT", ("storageLocations": "LOCATION")}Replace the following:
PROJECT_ID: the project to which the image belongs.IMAGE_NAME: a name for the new image that you wantto create.SOURCE_PROJECT_ID: Optional: the project thesnapshot is located in. You must have permission to access the snapshotresource in that project.SOURCE_SNAPSHOT: the snapshot from which you wantto create the image.LOCATION: Optional: the storage location of yourimage. For example, specifyusto store the image in theusmulti-region, orus-central1to store it in theus-central1region.If you don't make a selection, Compute Engine stores theimage in the multi-region closest to your image's source location.
For more information about adding images, see theimages reference.
Share the image
After creating a custom image, you canshare it acrossprojects. If you allow users from another project to use your customimages, then they canaccess these images by specifying the imageproject intheir request.
Enable guest operating system features
Use guest operating system (OS) features to configure the following networking,security, storage, and OS options on custom images. Custom imageswith these configured features are used as boot disks.
gcloud
Use thegcloud compute imagescreate command with the--guest-os-features flag to create a new custom image from an existingcustom image.
gcloud compute images createIMAGE_NAME \ --source-image=SOURCE_IMAGE \ [--source-image-project=IMAGE_PROJECT] \ --guest-os-features="FEATURES,..." \ [--storage-location=LOCATION]
Replace the following:
IMAGE_NAME: the name for the new imageSOURCE_IMAGE: an image to base the new image onIMAGE_PROJECT: Optional: the project containingthe source imageUse this parameter to copy an image from anotherproject.
FEATURES: guest OS tags to enable features for VMsthat you create from imagesTo add multiple values, use commas to separate values. Set to one ormore of the following values:
VIRTIO_SCSI_MULTIQUEUE. Use on local SSD devices as an alternative to NVMe. For more information about images that support SCSI, seeChoosing an interface.For Linux images, you can enable multi-queue SCSI on local SSD devices on images with kernel versions 3.17 or later. For Windows images, you can enable multi-queue SCSI on local SSD devices on images with Compute Engine Windows driver version 1.2.
WINDOWS. Tag Windows Server custom boot images as Windows images.MULTI_IP_SUBNET. Configure interfaces with a netmask other than/32. For more information about multiple network interfaces and how they work, see Multiple network interfaces overview and examples.UEFI_COMPATIBLE. Boot with UEFI firmware and the following Shielded VM features:- Secure Boot: disabled by default
- Virtual Trusted Platform Module (vTPM): enabled by default
- Integrity monitoring: enabled by default
GVNIC. Support higher network bandwidths of up to 50 Gbps to 100 Gbps speeds. For more information, see Using Google Virtual NIC.IDPF. Support Intel Infrastructure Data Path Function (IDPF) network interfaces.SEV_CAPABLEorSEV_SNP_CAPABLE. Use these tags if you want to use your image on a Confidential VM instance with AMD Secure Encrypted Virtualization (SEV) or AMD Secure Encrypted Virtualization-Secure Nested Paging (SEV-SNP) support. To check if your kernel supports AMD SEV or AMD SEV-SNP, see Linux kernel details.SEV_LIVE_MIGRATABLE_V2. Use this tag if you want to use your image on a Confidential VM instance that supports live migration on AMD SEV. To check if your kernel supports live migration, see Linux kernel details.TDX_CAPABLE. Use this tag if you want to use your image on a Confidential VM instance with Intel Trust Domain Extensions (TDX) support. To check if your kernel supports Intel TDX, see Linux kernel details.
LOCATION: Optional: region or multi-region inwhich to store the image
For example, specifyus to store the imagein theus multi-region, orus-central1 to store it in theus-central1 region. If you don't make a selection,Compute Engine stores the image in the multi-region closest toyour image's source location.
REST
Use theimages().insert methodwith theguestOsFeatures flag to create a new custom image from anexisting custom image.
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/images{ "name": "IMAGE_NAME", "sourceImage": "(projects/IMAGE_PROJECT)/global/images/SOURCE_IMAGE", ("storageLocations": "LOCATION",) "guestOsFeatures": [ { "type": "FEATURES" } ]}Replace the following:
PROJECT_ID: the ID of the project in which tocreate the new imageIMAGE_NAME: a name for the new imageIMAGE_PROJECT: Optional: the project containingthe source imageUse this parameter to copy an image from anotherproject.
SOURCE_IMAGE: the image to base the new image onLOCATION: Optional: a region or multi-region inwhich to store the imageFor example, specify
usto store the image intheusmulti-region, orus-central1to store it in theus-central1region. If you don't make a selection, Compute Engine stores theimage in the multi-region closest to your image's source location.FEATURES: guest OS tags to enable features for VMsthat you create from imagesTo add multiple values, use commas to separate values. Set to one ormore of the following values:
VIRTIO_SCSI_MULTIQUEUE. Use on local SSD devices as an alternative to NVMe. For more information about images that support SCSI, seeChoosing an interface.For Linux images, you can enable multi-queue SCSI on local SSD devices on images with kernel versions 3.17 or later. For Windows images, you can enable multi-queue SCSI on local SSD devices on images with Compute Engine Windows driver version 1.2.
WINDOWS. Tag Windows Server custom boot images as Windows images.MULTI_IP_SUBNET. Configure interfaces with a netmask other than/32. For more information about multiple network interfaces and how they work, see Multiple network interfaces overview and examples.UEFI_COMPATIBLE. Boot with UEFI firmware and the following Shielded VM features:- Secure Boot: disabled by default
- Virtual Trusted Platform Module (vTPM): enabled by default
- Integrity monitoring: enabled by default
GVNIC. Support higher network bandwidths of up to 50 Gbps to 100 Gbps speeds. For more information, see Using Google Virtual NIC.IDPF. Support Intel Infrastructure Data Path Function (IDPF) network interfaces.SEV_CAPABLEorSEV_SNP_CAPABLE. Use these tags if you want to use your image on a Confidential VM instance with AMD Secure Encrypted Virtualization (SEV) or AMD Secure Encrypted Virtualization-Secure Nested Paging (SEV-SNP) support. To check if your kernel supports AMD SEV or AMD SEV-SNP, see Linux kernel details.SEV_LIVE_MIGRATABLE_V2. Use this tag if you want to use your image on a Confidential VM instance that supports live migration on AMD SEV. To check if your kernel supports live migration, see Linux kernel details.TDX_CAPABLE. Use this tag if you want to use your image on a Confidential VM instance with Intel Trust Domain Extensions (TDX) support. To check if your kernel supports Intel TDX, see Linux kernel details.
Avoid sensitive information in UEFI variables
Unified Extensible Firmware Interface (UEFI) variables are key-value pair variablesused by the UEFI firmware during boot time to boot the operating system of a VM.Unlike physical machines, where the variables are stored on a hardware chip,Compute Engine virtualizes storage of these variables. As such, inmany operating systems, all applications and users can reach these variables andaccess this information.
Because of this reason, Google strongly recommends that you don't write or storesensitive or personal identifiable information such as passwords or private keysto UEFI variables.
Considerations for Arm images
Google offers theA4X, C4A, and Tau T2Amachine series, which run on Arm CPU platforms. You can start a VM with one ofthese machine series and then use that source VM to create an Arm image. Theprocess for creating a custom Arm image is identical to creating an x86 image.
To help your users differentiate between Arm and x86 images, Arm images willhave anarchitecture field set toARM64. Possible values for thisfield are:
ARCHITECTURE_UNSPECIFIEDX86_64ARM64
Image users can then filter on this field to find x86 or Arm-based images.
What's next
- Share your private imagewith other projects.
- Learn how toimport disks, images, and VM instances.
- Learn how toexport an image to Cloud Storage.
- Learn how tostart a VM from a custom image.
- Learn how toset the image version in an image family.
- Learn how todeprecate a custom image.
- Learn how todelete a custom image.
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.