Creare una VM da un modello di istanza


Questa pagina spiega come utilizzare un modello di istanza per creare un'istanza VM. Un modello di istanza è una risorsa API che definisce le proprietà delle istanze VM. In un modello di istanza puoi definire proprietà come il tipo di macchina, l'immagine del sistema operativo, le configurazioni dei disco permanente, i metadati, gli script di avvio e così via, per poi utilizzare il modello di istanza per creare singole istanze VM o gruppi di istanze gestite.

Quando crei un'istanza VM da un modello di istanza, il comportamento predefinito è creare un'istanza VM identica alle proprietà specificate nel modello, ad eccezione del nome dell'istanza VM e della zona in cui verrà eseguita l'istanza. In alternativa, se vuoi modificare determinate proprietà del modello di istanza per utilizzi specifici, puoi anche sostituire facoltativamente alcuni campi durante la creazione dell'istanza.

Questo documento presuppone che tu abbia un modello di istanza pronto per l'uso. Se non hai un modello di istanza, segui le istruzioni per crearne uno nuovo.

Prima di iniziare

  • Leggi la documentazione del modello di istanza.
  • Crea un modello di istanza.
  • Se non l'hai ancora fatto, configura l'autenticazione. L'autenticazione è la procedura mediante la quale la tua identità viene verificata per l'accesso alle API e ai servizi Google Cloud. Per eseguire codice o esempi da un ambiente di sviluppo locale, puoi autenticarti su Compute Engine selezionando una delle seguenti opzioni:

    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

    1. Install the Google Cloud CLI, then initialize it by running the following command:

      gcloud init
    2. Set a default region and zone.
    3. Vai

      Per utilizzare gli Go esempi in questa pagina in un ambiente di sviluppo locale, installa e inizializza l'interfaccia alla gcloud CLI, quindi configura le Credenziali predefinite dell'applicazione con le tue credenziali utente.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      Per ulteriori informazioni, consulta Set up authentication for a local development environment.

      Java

      Per utilizzare gli Java esempi in questa pagina in un ambiente di sviluppo locale, installa e inizializza l'interfaccia alla gcloud CLI, quindi configura le Credenziali predefinite dell'applicazione con le tue credenziali utente.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      Per ulteriori informazioni, consulta Set up authentication for a local development environment.

      Node.js

      Per utilizzare gli Node.js esempi in questa pagina in un ambiente di sviluppo locale, installa e inizializza l'interfaccia alla gcloud CLI, quindi configura le Credenziali predefinite dell'applicazione con le tue credenziali utente.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      Per ulteriori informazioni, consulta Set up authentication for a local development environment.

      Python

      Per utilizzare gli Python esempi in questa pagina in un ambiente di sviluppo locale, installa e inizializza l'interfaccia alla gcloud CLI, quindi configura le Credenziali predefinite dell'applicazione con le tue credenziali utente.

      1. Install the Google Cloud CLI.
      2. To initialize the gcloud CLI, run the following command:

        gcloud init
      3. If you're using a local shell, then create local authentication credentials for your user account:

        gcloud auth application-default login

        You don't need to do this if you're using Cloud Shell.

      Per ulteriori informazioni, consulta Set up authentication for a local development environment.

      REST

      Per utilizzare gli esempi dell'API REST in questa pagina in un ambiente di sviluppo locale, utilizza le credenziali fornite a gcloud CLI.

        Install the Google Cloud CLI, then initialize it by running the following command:

        gcloud init

      Per ulteriori informazioni, consulta Eseguire l'autenticazione per l'utilizzo di REST nella documentazione sull'autenticazione di Google Cloud.

Creare un'istanza VM da un modello di istanza

Puoi utilizzare un modello di istanza regionale o globale per creare un'istanza VM. Per creare un'istanza esattamente come descritto nel modello di istanza, segui queste istruzioni.

Console

  1. Nella console Google Cloud, vai alla pagina Crea un'istanza.

    Vai a Crea un'istanza

  2. Fai clic su Nuova istanza VM da modello.

  3. Seleziona il modello e fai clic su Continua.

  4. Specifica un nome per la VM ed esegui ulteriori personalizzazioni, se necessario.

  5. Fai clic su Crea.

    Per ulteriori dettagli sulla configurazione, consulta Creare un'istanza VM da un'immagine.

gcloud

Per creare una VM da un modello di istanza regionale o globale, utilizza lo stesso comando gcloud compute instances create che utilizzeresti per creare un'istanza normale, ma aggiungi il --source-instance-template flag:

gcloud compute instances create VM_NAME \
    --source-instance-template INSTANCE_TEMPLATE_NAME

Sostituisci quanto segue:

  • VM_NAME: il nome dell'istanza.
  • INSTANCE_TEMPLATE_NAME: il nome del modello di istanza da utilizzare. Per un modello di istanza regionale, devi specificare l'URL completo o parziale del modello. Un esempio di URL completo è https://www.googleapis.com/compute/v1/projects/example-project/regions/us-central1/instanceTemplates/example-regional-instance-template, mentre un URL parziale è projects/example-project/regions/us-central1/instanceTemplates/example-regional-instance-template.

Ad esempio:

gcloud compute instances create example-instance \
    --source-instance-template my-instance-template

Vai

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// createInstanceFromTemplate creates a Compute Engine VM instance from an instance template.
func createInstanceFromTemplate(w io.Writer, projectID, zone, instanceName, instanceTemplateUrl string) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"
	// instanceTemplateUrl := "global/instanceTemplates/your_instance_template"

	ctx := context.Background()
	instancesClient, err := compute.NewInstancesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstancesRESTClient: %w", err)
	}
	defer instancesClient.Close()

	req := &computepb.InsertInstanceRequest{
		Project: projectID,
		Zone:    zone,
		InstanceResource: &computepb.Instance{
			Name: proto.String(instanceName),
		},
		SourceInstanceTemplate: &instanceTemplateUrl,
	}

	op, err := instancesClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create instance: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Instance created\n")

	return nil
}

Java


import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.InsertInstanceRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstanceProperties;
import com.google.cloud.compute.v1.InstanceTemplate;
import com.google.cloud.compute.v1.InstanceTemplatesClient;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateInstanceFromTemplate {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /*  TODO(developer): Replace these variables before running the sample.
        projectId - ID or number of the project you want to use.
        zone - Name of the zone you want to check, for example: us-west3-b
        instanceName - Name of the new instance.
        instanceTemplateURL - URL of the instance template using for creating the new instance.
        It can be a full or partial URL.
        Examples:
        - https://www.googleapis.com/compute/v1/projects/project/global/instanceTemplates/example-instance-template
        - projects/project/global/instanceTemplates/example-instance-template
        - global/instanceTemplates/example-instance-template
     */
    String projectId = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";
    String instanceTemplateUrl = "instance-template-url";
    createInstanceFromTemplate(projectId, zone, instanceName, instanceTemplateUrl);
  }

  // Create a new instance from template in the specified project and zone.
  public static void createInstanceFromTemplate(String projectId, String zone, String instanceName,
      String instanceTemplateName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {

    try (InstancesClient instancesClient = InstancesClient.create();
        InstanceTemplatesClient instanceTemplatesClient = InstanceTemplatesClient.create()) {

      InstanceTemplate instanceTemplate = instanceTemplatesClient.get(projectId,
          instanceTemplateName);

      // Adjust diskType field of the instance template to use the URL formatting 
      // required by instances.insert.diskType
      // For instance template, there is only a name, not URL.
      List<AttachedDisk> reformattedAttachedDisks = new ArrayList<>();
      for (AttachedDisk disk : instanceTemplate.getProperties().getDisksList()) {
        disk = AttachedDisk.newBuilder(disk)
            .setInitializeParams(AttachedDiskInitializeParams
                .newBuilder(disk.getInitializeParams())
                .setDiskType(
                    String.format(
                        "zones/%s/diskTypes/%s", zone, disk.getInitializeParams().getDiskType()))
                .build())
            .build();

        reformattedAttachedDisks.add(disk);
      }

      // Clear existing disks and set the reformatted disks in the instance template.
      instanceTemplate = InstanceTemplate
          .newBuilder(instanceTemplate)
          .setProperties(InstanceProperties
              .newBuilder(instanceTemplate.getProperties())
              .clearDisks()
              .addAllDisks(reformattedAttachedDisks)
              .build())
          .build();

      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(projectId)
          .setZone(zone)
          .setInstanceResource(Instance.newBuilder().setName(instanceName).build())
          .setSourceInstanceTemplate(instanceTemplate.getSelfLink()).build();

      Operation response = instancesClient.insertAsync(insertInstanceRequest)
          .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Instance creation from template failed ! ! " + response);
        return;
      }
      System.out
          .printf("Instance creation from template: Operation Status %s: %s ", instanceName,
              response.getStatus());
    }
  }
}

Node.js

/**
 * 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 instanceTemplateUrl = 'YOUR_INSTANCE_TEMPLATE_URL'

const compute = require('@google-cloud/compute');

// Create a new instance from template in the specified project and zone.
async function createInstanceFromTemplate() {
  const instancesClient = new compute.InstancesClient();

  console.log(
    `Creating the ${instanceName} instance in ${zone} from template ${instanceTemplateUrl}...`
  );

  const [response] = await instancesClient.insert({
    project: projectId,
    zone,
    instanceResource: {
      name: instanceName,
    },
    sourceInstanceTemplate: instanceTemplateUrl,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
      zone: operation.zone.split('/').pop(),
    });
  }

  console.log('Instance created.');
}

createInstanceFromTemplate();

Python

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def create_instance_from_template(
    project_id: str, zone: str, instance_name: str, instance_template_url: str
) -> compute_v1.Instance:
    """
    Creates a Compute Engine VM instance from an instance template.

    Args:
        project_id: ID or number of the project you want to use.
        zone: Name of the zone you want to check, for example: us-west3-b
        instance_name: Name of the new instance.
        instance_template_url: URL of the instance template used for creating the new instance.
            It can be a full or partial URL.
            Examples:
            - https://www.googleapis.com/compute/v1/projects/project/global/instanceTemplates/example-instance-template
            - projects/project/global/instanceTemplates/example-instance-template
            - global/instanceTemplates/example-instance-template

    Returns:
        Instance object.
    """
    instance_client = compute_v1.InstancesClient()

    instance_insert_request = compute_v1.InsertInstanceRequest()
    instance_insert_request.project = project_id
    instance_insert_request.zone = zone
    instance_insert_request.source_instance_template = instance_template_url
    instance_insert_request.instance_resource.name = instance_name

    operation = instance_client.insert(instance_insert_request)
    wait_for_extended_operation(operation, "instance creation")

    return instance_client.get(project=project_id, zone=zone, instance=instance_name)

REST

Per creare una VM da un modello di istanza regionale o globale, crea una richiesta normale per creare un'istanza, ma includi il parametro di query sourceInstanceTemplate seguito da un percorso qualificato a un modello di istanza.

POST https://compute.googleapis.com/compute/v1/projects/
PROJECT_ID/zones/ZONE/
instances?sourceInstanceTemplate=INSTANCE_TEMPLATE_NAME

Nel corpo della richiesta, fornisci un name per l'istanza VM:

{ "name": "example-instance" }

Ad esempio, il seguente snippet include un percorso completo al modello: https://compute.googleapis.com/compute/v1/projects/myproject/global/instanceTemplates/example-instance-template.

POST https://compute.googleapis.com/
compute/v1/projects/myproject/zones/us-central1-a/instances?sourceInstanceTemplate=
https://compute.googleapis.com/compute/v1/projects/myproject/global/
instanceTemplates/example-instance-template
{ "name": "example-instance" }

Crea un'istanza VM da un modello di istanza con sostituzioni

Quando utilizzi un modello di istanza per avviare un'istanza VM, il comportamento predefinito è creare un'istanza VM esattamente come descritto nel modello, ad eccezione del nome e della zona dell'istanza.

Se vuoi creare un'istanza principalmente in base a un modello di istanza, ma con alcune modifiche, puoi utilizzare il comportamento di override. Per utilizzare il comportamento di override, devi passare gli attributi da sostituire per il modello di istanza esistente durante la creazione dell'istanza.

gcloud

Utilizzando l'interfaccia a riga di comando gcloud, invia una richiesta per creare un'istanza con il flag --source-instance-template e sostituisci qualsiasi proprietà che ti interessa con il flag gcloud appropriato. Per visualizzare un elenco degli indicatori applicabili, consulta il riferimento gcloud.

Ad esempio, fornisci i seguenti flag per sostituire il tipo di macchina, i metadati, il sistema operativo, il disco di avvio Persistent Disk e un disco secondario di un modello di istanza:

gcloud compute instances create example-instance \
    --source-instance-template example-instance --machine-type e2-standard-2 \
    --image-family debian-9 --image-project debian-cloud \
    --metadata bread=butter --disk=boot=no,name=my-override-disk

Vai

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"

	"google.golang.org/protobuf/proto"
)

// createInstanceFromTemplate creates a Compute Engine VM instance from an instance template, but overrides the disk and machine type options in the template.
func createInstanceFromTemplateWithOverrides(w io.Writer, projectID, zone, instanceName, instanceTemplateName, machineType, newDiskSourceImage string) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"
	// instanceTemplateName := "your_instance_template_name"
	// machineType := "n1-standard-2"
	// newDiskSourceImage := "projects/debian-cloud/global/images/family/debian-12"

	ctx := context.Background()
	instancesClient, err := compute.NewInstancesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstancesRESTClient: %w", err)
	}
	defer instancesClient.Close()

	intanceTemplatesClient, err := compute.NewInstanceTemplatesRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstanceTemplatesRESTClient: %w", err)
	}
	defer intanceTemplatesClient.Close()

	// Retrieve an instance template by name.
	reqGetTemplate := &computepb.GetInstanceTemplateRequest{
		Project:          projectID,
		InstanceTemplate: instanceTemplateName,
	}

	instanceTemplate, err := intanceTemplatesClient.Get(ctx, reqGetTemplate)
	if err != nil {
		return fmt.Errorf("unable to get intance template: %w", err)
	}

	for _, disk := range instanceTemplate.Properties.Disks {
		diskType := disk.InitializeParams.GetDiskType()
		if diskType != "" {
			disk.InitializeParams.DiskType = proto.String(fmt.Sprintf(`zones/%s/diskTypes/%s`, zone, diskType))
		}
	}

	reqInsertInstance := &computepb.InsertInstanceRequest{
		Project: projectID,
		Zone:    zone,
		InstanceResource: &computepb.Instance{
			Name:        proto.String(instanceName),
			MachineType: proto.String(fmt.Sprintf(`zones/%s/machineTypes/%s`, zone, machineType)),
			Disks: append(
				// If you override a repeated field, all repeated values
				// for that property are replaced with the
				// corresponding values provided in the request.
				// When adding a new disk to existing disks,
				// insert all existing disks as well.
				instanceTemplate.Properties.Disks,
				&computepb.AttachedDisk{
					InitializeParams: &computepb.AttachedDiskInitializeParams{
						DiskSizeGb:  proto.Int64(10),
						SourceImage: &newDiskSourceImage,
					},
					AutoDelete: proto.Bool(true),
					Boot:       proto.Bool(false),
					Type:       proto.String(computepb.AttachedDisk_PERSISTENT.String()),
				},
			),
		},
		SourceInstanceTemplate: instanceTemplate.SelfLink,
	}

	op, err := instancesClient.Insert(ctx, reqInsertInstance)
	if err != nil {
		return fmt.Errorf("unable to create instance: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", err)
	}

	fmt.Fprintf(w, "Instance created\n")

	return nil
}

Java


import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.InsertInstanceRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.InstanceTemplate;
import com.google.cloud.compute.v1.InstanceTemplatesClient;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateInstanceFromTemplateWithOverrides {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /* TODO(developer): Replace these variables before running the sample.
     * projectId - ID or number of the project you want to use.
     * zone - Name of the zone you want to check, for example: us-west3-b
     * instanceName - Name of the new instance.
     * instanceTemplateName - Name of the instance template to use when creating the new instance.
     * machineType - Machine type you want to set in following format:
     *    "zones/{zone}/machineTypes/{type_name}". For example:
     *    "zones/europe-west3-c/machineTypes/f1-micro"
     *    You can find the list of available machine types using:
     *    https://cloud.google.com/sdk/gcloud/reference/compute/machine-types/list
     * newDiskSourceImage - Path the the disk image you want to use for your new
     *    disk. This can be one of the public images
     *    (like "projects/debian-cloud/global/images/family/debian-11")
     *    or a private image you have access to.
     *    You can check the list of available public images using the doc:
     *    http://cloud.google.com/compute/docs/images
     */
    String projectId = "your-project-id";
    String zone = "zone-name";
    String instanceName = "instance-name";
    String instanceTemplateName = "instance-template-name";

    createInstanceFromTemplateWithOverrides(projectId, zone, instanceName, instanceTemplateName);
  }

  // Creates a Compute Engine VM instance from an instance template,
  // but overrides the disk and machine type options in the template.
  public static void createInstanceFromTemplateWithOverrides(String projectId, String zone,
      String instanceName, String instanceTemplateName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {

    try (InstancesClient instancesClient = InstancesClient.create();
        InstanceTemplatesClient instanceTemplatesClient = InstanceTemplatesClient.create()) {

      String machineType = "n1-standard-1";
      String newDiskSourceImage = "projects/debian-cloud/global/images/family/debian-11";

      // Retrieve an instance template.
      InstanceTemplate instanceTemplate = instanceTemplatesClient
          .get(projectId, instanceTemplateName);

      // Adjust diskType field of the instance template to use the URL formatting 
      // required by instances.insert.diskType
      // For instance template, there is only a name, not URL.
      List<AttachedDisk> reformattedAttachedDisks = new ArrayList<>();
      for (AttachedDisk disk : instanceTemplate.getProperties().getDisksList()) {
        disk = AttachedDisk.newBuilder(disk)
            .setInitializeParams(AttachedDiskInitializeParams
                .newBuilder(disk.getInitializeParams())
                .setDiskType(
                    String.format(
                        "zones/%s/diskTypes/%s", zone, disk.getInitializeParams().getDiskType()))
                .build())
            .build();

        reformattedAttachedDisks.add(disk);
      }

      AttachedDisk newdisk = AttachedDisk.newBuilder()
          .setInitializeParams(AttachedDiskInitializeParams.newBuilder()
              .setDiskSizeGb(10)
              .setSourceImage(newDiskSourceImage).build())
          .setAutoDelete(true)
          .setBoot(false)
          .setType(AttachedDisk.Type.PERSISTENT.toString()).build();

      Instance instance = Instance.newBuilder()
          .setName(instanceName)
          .setMachineType(String.format("zones/%s/machineTypes/%s", zone, machineType))
          // If you override a repeated field, all repeated values
          // for that property are replaced with the
          // corresponding values provided in the request.
          // When adding a new disk to existing disks,
          // insert all existing disks as well.
          .addAllDisks(reformattedAttachedDisks)
          .addDisks(newdisk)
          .build();

      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(projectId)
          .setZone(zone)
          .setInstanceResource(instance)
          .setSourceInstanceTemplate(instanceTemplate.getSelfLink()).build();

      Operation response = instancesClient.insertAsync(insertInstanceRequest)
          .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        System.out.println("Instance creation from template with overrides failed ! ! " + response);
        return;
      }
      System.out
          .printf("Instance creation from template with overrides: Operation Status %s: %s ",
              instanceName, response.getStatus());
    }

  }
}

Node.js

/**
 * 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 instanceTemplateName = 'YOUR_INSTANCE_TEMPLATE_NAME';
// const machineType = 'n1-standard-1';
// const newDiskSourceImage = 'projects/debian-cloud/global/images/family/debian-11';

const compute = require('@google-cloud/compute');

// Creates a new instance in the specified project and zone using a selected template,
// but overrides the disk and machine type options in the template.
async function createInstanceFromTemplateWithOverrides() {
  const instancesClient = new compute.InstancesClient();
  const instanceTemplatesClient = new compute.InstanceTemplatesClient();

  console.log(
    `Creating the ${instanceName} instance in ${zone} from template ${instanceTemplateName}...`
  );

  // Retrieve an instance template by name.
  const [instanceTemplate] = await instanceTemplatesClient.get({
    project: projectId,
    instanceTemplate: instanceTemplateName,
  });

  // Adjust diskType field of the instance template to use the URL formatting required by instances.insert.diskType
  // For instance template, there is only a name, not URL.
  for (const disk of instanceTemplate.properties.disks) {
    if (disk.initializeParams.diskType) {
      disk.initializeParams.diskType = `zones/${zone}/diskTypes/${disk.initializeParams.diskType}`;
    }
  }

  const [response] = await instancesClient.insert({
    project: projectId,
    zone,
    instanceResource: {
      name: instanceName,
      machineType: `zones/${zone}/machineTypes/${machineType}`,
      disks: [
        // If you override a repeated field, all repeated values
        // for that property are replaced with the
        // corresponding values provided in the request.
        // When adding a new disk to existing disks,
        // insert all existing disks as well.
        ...instanceTemplate.properties.disks,
        {
          initializeParams: {
            diskSizeGb: '10',
            sourceImage: newDiskSourceImage,
          },
          autoDelete: true,
          boot: false,
          type: 'PERSISTENT',
        },
      ],
    },
    sourceInstanceTemplate: instanceTemplate.selfLink,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
      zone: operation.zone.split('/').pop(),
    });
  }

  console.log('Instance created.');
}

createInstanceFromTemplateWithOverrides();

Python

from __future__ import annotations

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1


def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    Waits for the extended (long-running) operation to complete.

    If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result


def create_instance_from_template_with_overrides(
    project_id: str,
    zone: str,
    instance_name: str,
    instance_template_name: str,
    machine_type: str,
    new_disk_source_image: str,
) -> compute_v1.Instance:
    """
    Creates a Compute Engine VM instance from an instance template, changing the machine type and
    adding a new disk created from a source image.

    Args:
        project_id: ID or number of the project you want to use.
        zone: Name of the zone you want to check, for example: us-west3-b
        instance_name: Name of the new instance.
        instance_template_name: Name of the instance template used for creating the new instance.
        machine_type: Machine type you want to set in following format:
            "zones/{zone}/machineTypes/{type_name}". For example:
            - "zones/europe-west3-c/machineTypes/f1-micro"
            - You can find the list of available machine types using:
              https://cloud.google.com/sdk/gcloud/reference/compute/machine-types/list
        new_disk_source_image: Path the the disk image you want to use for your new
            disk. This can be one of the public images
            (like "projects/debian-cloud/global/images/family/debian-12")
            or a private image you have access to.
            For a list of available public images, see the documentation:
            http://cloud.google.com/compute/docs/images

    Returns:
        Instance object.
    """
    instance_client = compute_v1.InstancesClient()
    instance_template_client = compute_v1.InstanceTemplatesClient()

    # Retrieve an instance template by name.
    instance_template = instance_template_client.get(
        project=project_id, instance_template=instance_template_name
    )

    # Adjust diskType field of the instance template to use the URL formatting required by instances.insert.diskType
    # For instance template, there is only a name, not URL.
    for disk in instance_template.properties.disks:
        if disk.initialize_params.disk_type:
            disk.initialize_params.disk_type = (
                f"zones/{zone}/diskTypes/{disk.initialize_params.disk_type}"
            )

    instance = compute_v1.Instance()
    instance.name = instance_name
    instance.machine_type = machine_type
    instance.disks = list(instance_template.properties.disks)

    new_disk = compute_v1.AttachedDisk()
    new_disk.initialize_params.disk_size_gb = 50
    new_disk.initialize_params.source_image = new_disk_source_image
    new_disk.auto_delete = True
    new_disk.boot = False
    new_disk.type_ = "PERSISTENT"

    instance.disks.append(new_disk)

    instance_insert_request = compute_v1.InsertInstanceRequest()
    instance_insert_request.project = project_id
    instance_insert_request.zone = zone
    instance_insert_request.instance_resource = instance
    instance_insert_request.source_instance_template = instance_template.self_link

    operation = instance_client.insert(instance_insert_request)
    wait_for_extended_operation(operation, "instance creation")

    return instance_client.get(project=project_id, zone=zone, instance=instance_name)

REST

Nell'API, utilizza il parametro di query sourceInstanceTemplate e fornisci tutti i campi da eseguire l'override nel corpo della richiesta quando crei una normale richiesta per creare un'istanza.

Il comportamento di override nell'API segue le regole di patch di unione JSON, descritte da RFC 7396.

In particolare:

  • Se sostituisci un campo di base, il campo di base corrispondente nel modello di istanza verrà sostituito con il valore del campo di base nella richiesta. I campi di base includono machineType, sourceImage, name e così via.
  • Se sostituisci un campo ripetuto, tutti i valori ripetuti per quella proprietà verranno sostituiti con i valori corrispondenti forniti nella richiesta. I campi ripetuti sono in genere proprietà di tipo list. Ad esempio, disks e networkInterfaces sono campi ripetuti.
  • Se sostituisci un nested object, l'oggetto nel modello di istanza verrà unito alla specifica dell'oggetto corrispondente nella richiesta. Tieni presente che se un oggetto nidificato si trova all'interno di un campo ripetuto, il campo viene trattato in base alle regole per i campi ripetuti. Le etichette sono un'eccezione a questa regola e vengono trattate come un campo ripetuto anche se sono di tipo object.

Ad esempio, supponiamo che tu abbia un modello di istanza con due dischi non di avvio, ma che tu voglia sostituire uno dei dischi. Nella richiesta devi fornire l'intera specificadisks, inclusi i dischi che vuoi conservare.

L'URL di questa richiesta:

POST https://compute.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/instances?
sourceInstanceTemplate=https://compute.googleapis.com/compute/v1/projects/myproject/global/instanceTemplates/example-instance-template

Il corpo della richiesta:

    {
      "disks": [
        {
          # Since you are overriding the repeated disk property, you must
          # specify a boot disk in the request, even if it is already
          # specified in the instance template
          "autoDelete": true,
          "boot": true,
          "initializeParams": {
            "sourceImage": "projects/debian-cloud/global/images/family/debian-8"
          },
          "mode": "READ_WRITE",
          "type": "PERSISTENT"
        },
        {
          # New disk you want to use
          "autoDelete": false,
          "boot": false,
          "mode": "READ_WRITE",
          "source": "zones/us-central1-f/disks/my-override-disk",
          "type": "PERSISTENT"
        },
        {
           # Assume this disk is already specified in instance template, but
           # you must specify it again since you are overriding the disks
           # property
          "autoDelete": false,
          "boot": false,
          "mode": "READ_WRITE",

          "source": "zones/us-central1-f/disks/my-other-disk-to-keep",
          "type": "PERSISTENT"
        }
      ],
      "machineType": "zones/us-central1-f/machineTypes/e2-standard-2",
      "name": "example-instance"
    }
    

Passaggi successivi