Consumir reservas


En este documento, se explica cómo usar Compute Engine para hacer lo siguiente:

  • Consume instancias de máquina virtual (VM) reservadas.

  • Verifica el consumo de reservas.

  • Visualiza los informes de uso de reservas.

Para obtener más información sobre el consumo de reservas en otros productos de Google Cloud que usan VMs, consulta la documentación de reservas de los siguientes productos:

Antes de comenzar

  • Revisa los requisitos y las y las restricciones para las reservas.
  • Si aún no lo hiciste, configura la autenticación. La autenticación es el proceso mediante el cual se verifica tu identidad para acceder a los servicios y las API de Google Cloud. Para ejecutar código o muestras desde un entorno de desarrollo local, puedes autenticarte en Compute Engine seleccionando una de las siguientes opciones:

    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. Go

      Para usar las muestras de Go de esta página en un entorno de desarrollo local, instala e inicializa gcloud CLI y, luego, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

      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.

      Para obtener más información, consulta Set up authentication for a local development environment.

      Java

      Para usar las muestras de Java de esta página en un entorno de desarrollo local, instala e inicializa gcloud CLI y, luego, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

      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.

      Para obtener más información, consulta Set up authentication for a local development environment.

      Node.js

      Para usar las muestras de Node.js de esta página en un entorno de desarrollo local, instala e inicializa gcloud CLI y, luego, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

      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.

      Para obtener más información, consulta Set up authentication for a local development environment.

      Python

      Para usar las muestras de Python de esta página en un entorno de desarrollo local, instala e inicializa gcloud CLI y, luego, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.

      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.

      Para obtener más información, consulta Set up authentication for a local development environment.

      REST

      Para usar las muestras de la API de REST en esta página en un entorno de desarrollo local, debes usar las credenciales que proporcionas a la CLI de gcloud.

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

        gcloud init

      Si deseas obtener más información, consulta Autentica para usar REST en la documentación de autenticación de Google Cloud.

Roles obligatorios

Para obtener los permisos que necesitas y consumir las reservas, pídele al administrador que te otorgue el rol de IAM Administrador de instancias de Compute (v1) (roles/compute.instanceAdmin.v1) en el proyecto. Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.

Este rol predefinido contiene los permisos necesarios para consumir reservas. Para ver los permisos exactos que son necesarios, expande la sección Permisos requeridos:

Permisos necesarios

Se requieren los siguientes permisos para consumir las reservas:

  • Para crear reservas, haz lo siguiente: compute.reservations.create en el proyecto.
  • Para crear VMs, sigue estos pasos:
    • compute.instances.create en el proyecto
    • Para usar una imagen personalizada con el fin de crear la VM, sigue estos pasos: compute.images.useReadOnly en la imagen
    • Si deseas usar una instantánea para crear la VM, sigue estos pasos: compute.snapshots.useReadOnly en la instantánea
    • Para usar una plantilla de instancias a fin de crear la VM, haz lo siguiente: compute.instanceTemplates.useReadOnly en la plantilla de instancias
    • Para asignar una red heredada a la VM: compute.networks.use en el proyecto
    • Si deseas especificar una dirección IP estática para la VM; compute.addresses.use en el proyecto
    • Para asignar una dirección IP externa a la VM cuando se usa una red y punto heredado; compute.networks.useExternalIp en el proyecto
    • A fin de especificar una subred para la VM: compute.subnetworks.use en el proyecto o en la subred elegida
    • Para asignar una dirección IP externa a la VM cuando se usa una red de VPC, compute.subnetworks.useExternalIp en el proyecto o en la subred elegida
    • A fin de configurar los metadatos de la instancia de VM para la VM y los puntos, sigue estos pasos: compute.instances.setMetadata en el proyecto
    • A fin de configurar etiquetas para la VM y los puntos; compute.instances.setTags en la VM
    • Si deseas configurar etiquetas para la VM, haz lo siguiente: compute.instances.setLabels en la VM
    • A fin de configurar una cuenta de servicio para que la VM la usecompute.instances.setServiceAccount en la VM
    • Si deseas crear un disco nuevo para la VM: compute.disks.create en el proyecto
    • Para conectar un disco existente en modo de solo lectura o de lectura y escritura, haz lo siguiente: compute.disks.use en el disco
    • Para conectar un disco existente en modo de solo lectura y dos puntos, sigue estos pasos: compute.disks.useReadOnly en el disco
  • Para crear plantillas de instancias, usa compute.instanceTemplates.create en el proyecto.

También puedes obtener estos permisos con roles personalizados o con otros roles predefinidos.

Consume las VMs reservadas

Cuando creas una instancia de máquina virtual (VM), la instancia comienza a consumir una reserva solo si las propiedades de la VM y la reserva coinciden. Además, debes establecer la propiedad de afinidad de la reserva de la VM en una de las siguientes opciones:

  • Consume cualquier reserva que coincida: la VM puede consumir automáticamente cualquier reserva con propiedades coincidentes (predeterminado).

    Esta opción es útil si creas y borras muchas VMs y deseas usar las reservas siempre que sea posible. En esta situación, se puede crear una VM sin importar si sus propiedades coinciden con una reserva o no. Si coinciden, la VM comienza a consumir la reserva según el orden de consumo de la reserva.

  • Consume una reserva específica: la VM puede consumir solo una reserva específica. La reserva no se puede consumir automáticamente.

    Esta opción es útil cuando, por ejemplo, deseas mantener una cierta cantidad como respaldo para eventos especiales. En esta situación, se puede crear una VM solo si sus propiedades y las propiedades de la reserva específica coinciden.

  • No puede consumir ninguna reserva: la VM no puede consumir ninguna reserva.

    Esta opción es útil cuando, por ejemplo, creas una VM temporal que no deseas que consuma recursos reservados.

Consume las VMs de cualquier reserva que coincida

En este modelo de consumo, las VMs nuevas y existentes consumen una reserva automáticamente si sus propiedades coinciden con las propiedades de la VM especificadas en la reserva.

Cuando se usa este modelo de consumo, las VMs del proyecto actual consumen todas las reservas de un solo proyecto antes de consumir cualquier reserva compartida. Para obtener más información sobre cómo se consumen las instancias automáticamente, consulta el orden de consumo.

Cuando creas una reserva, este es el modelo de consumo predeterminado, siempre que no uses la opción o marca que indica que se necesitan reservas específicas.

Console

  1. Para crear una reserva con recursos que puedan usar las instancias de VM con una propiedad de afinidad de reserva configurada para consumir cualquier reserva (opción predeterminada), sigue estos pasos:

    1. Selecciona el tipo de reserva que deseas crear:

      • Para crear una reserva independiente, haz lo siguiente:

        1. En la consola de Google Cloud, ve a la página Reservas.

          Ir a Reservas

        2. En la pestaña Reserva según demanda (predeterminada), haz clic en Crear reserva.

          Se abrirá la página Crear una reserva.

      • Para crear una reserva vinculada a un compromiso, haz lo siguiente:

        1. En la consola de Google Cloud, ve a la página Descuentos por compromiso de uso.

          Ir a Descuentos por compromiso de uso

          Se abrirá la página Lista de compromisos.

        2. Haz clic en Compromiso de compra.

          Se abrirá la página Comprar un descuento por compromiso de uso.

        3. Especifica las propiedades del compromiso. Luego, en la sección Reservas, haz clic en Agregar un elemento.

          Aparecerá la sección Agregar una reserva nueva.

          Para obtener más información sobre cómo adquirir un compromiso con una reserva vinculada, consulta Adquiere compromisos con reservas adjuntas.

    2. En el campo Nombre, ingresa el nombre de tu reserva. En este ejemplo, ingresa reservation-01.

    3. Elige la región y zona en la que deseas reservar los recursos. En este ejemplo, selecciona us-central1 como región y us-central1-a como zona.

    4. Elige tu Tipo de recurso compartido preferido:

      • A fin de crear una reserva para un solo proyecto, selecciona Local.
      • Para crear una reserva compartida entre varios proyectos, elige Compartido. Para compartir esta reserva con otros proyectos, haz clic en Agregar proyectos y selecciona los proyectos deseados de la organización del proyecto actual.
    5. En la sección Usar con instancia de VM, selecciona Usar reserva de forma automática para que cualquier instancia de VM coincidente pueda usar esta reserva de manera automática.

    6. En el campo Cantidad de instancias de VMs, escribe la cantidad de VMs que deseas reservar. En este ejemplo, ingresa 2.

    7. Especifica los recursos que deseas reservar para cada instancia de VM:

      • Si deseas reservar VM que coincidan con una plantilla de instancias existente, selecciona Usar plantilla de instancias y selecciona una plantilla de instancias de la lista.
      • De lo contrario, selecciona Especificar tipo de máquina y especifica lo siguiente:
        1. En los campos Familia de máquinas, Serie y Tipo de máquina, selecciona una familia de máquinas, series y tipos de máquinas.
        2. Especifica una plataforma de CPU mínima o GPU (opcional):
          1. Para expandir la sección Plataforma de CPU y GPU, haz clic en la flecha de expansión .
          2. Opcional: Para especificar una plataforma de CPU mínima, selecciona una opción en la lista Formulario de CPU.
          3. Opcional: Para agregar GPU, haz clic en Agregar GPU. Luego, en los campos Tipo de GPU y Cantidad de GPU, elige el tipo y la cantidad de GPU para cada VM.
        3. Opcional: Agrega SSD locales:
          1. En el campo Cantidad de discos, elige la cantidad de SSD locales para cada VM.
          2. En el campo Tipo de interfaz, selecciona la interfaz para las SSD locales.

      Para este ejemplo, selecciona Especificar tipo de máquina. Luego, selecciona el tipo de máquina n2-standard-32 para la familia de máquinas General-purpose y la serie N2. Luego, selecciona la plataforma de CPU mínima Intel Cascade Lake.

    8. Termina de crear la reserva:

      • Si quieres crear una reserva independiente, haz clic en Crear.

      • Si quieres crear una reserva vinculada a un compromiso, ejecuta este comando:

        1. Para terminar de especificar las propiedades de esta reserva, haz clic en Listo.
        2. Para terminar de crear el compromiso y las reservas adjuntas, haz clic en Comprar.
  2. En el mismo proyecto o en el que se comparte la reserva, crea una instancia de VM que se dirija a cualquier reserva abierta.

    Asegúrate de que las propiedades de la VM coincidan con las propiedades de la VM en reservation-01, incluida la zona, el tipo de máquina (familia de máquinas, CPU virtuales y memoria), la plataforma de CPU mínima, la cantidad y el tipo de GPU, y la interfaz y el tamaño del SSD local.

    Para obtener más información sobre cómo crear una VM, consulta Crea y, luego, inicia una VM

    1. En la consola de Google Cloud, ve a la página Crear una instancia.

      Ir a Crear una instancia

      Se abrirá la página Crea una instancia.

    2. Especifica un nombre para la VM.

    3. En las siguientes secciones, selecciona una configuración que coincida con exactitud con todas las propiedades de tu reserva, incluidas las propiedades opcionales. Para este ejemplo, debes hacer coincidir las siguientes propiedades de instancia de VM con reservation-01:

      • Región: us-central1
      • Zona: us-central1-a
      • Tipo de máquina: n2-standard-32
      • Plataforma de CPU mínima: Intel Cascade Lake
      • GPU: Ninguna
      • SSD locales: Ninguno
    4. Expande la sección Opciones avanzadas y, luego, la sección Administración. En la lista Reservas, haz clic en Usar la reserva creada de forma automática.

    5. Para crear la VM, haz clic en Crear.

gcloud

  1. Crea una reserva abierta llamada reservation-01.

    gcloud compute reservations create reservation-01 \
        --vm-count=2 \
        --machine-type=n2-standard-32 \
        --min-cpu-platform="Intel Cascade Lake" \
        --zone=us-central1-a
    
  2. Crea una instancia de VM que se dirija a cualquier reserva abierta y que coincida con las propiedades de la instancia en reservation-01, incluida la zona, el tipo de máquina (familia de máquinas, CPU virtuales y memoria), la plataforma de CPU mínima, la cantidad y el tipo de GPU, y la cantidad y la interfaz del SSD local.

    gcloud compute instances create instance-1 \
        --machine-type=n2-standard-32 \
        --min-cpu-platform="Intel Cascade Lake" \
        --zone=us-central1-a \
        --reservation-affinity=any
    

Go

import (
	"context"
	"fmt"
	"io"

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

// consumeAnyReservation creates instance, consuming any available reservation
func consumeAnyReservation(w io.Writer, projectID, zone, instanceName, sourceTemplate string) error {
	// projectID := "your_project_id"
	// zone := "us-west3-a"
	// instanceName := "your_instance_name"
	// sourceTemplate: existing template path. Following formats are allowed:
	//  	- projects/{project_id}/global/instanceTemplates/{template_name}
	//  	- projects/{project_id}/regions/{region}/instanceTemplates/{template_name}
	//  	- https://www.googleapis.com/compute/v1/projects/{project_id}/global/instanceTemplates/instanceTemplate
	//  	- https://www.googleapis.com/compute/v1/projects/{project_id}/regions/{region}/instanceTemplates/instanceTemplate

	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,
		SourceInstanceTemplate: proto.String(sourceTemplate),
		InstanceResource: &computepb.Instance{
			Name: proto.String(instanceName),
			// specifies that any matching reservation should be consumed
			ReservationAffinity: &computepb.ReservationAffinity{
				ConsumeReservationType: proto.String("ANY_RESERVATION"),
			},
		},
	}

	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 from reservation\n")

	return nil
}

Java

import static com.google.cloud.compute.v1.ReservationAffinity.ConsumeReservationType.ANY_RESERVATION;

import com.google.api.gax.longrunning.OperationFuture;
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.InstancesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.ReservationAffinity;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ConsumeAnyMatchingReservation {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";
    // Zone where the VM instance will be created.
    String zone = "us-central1-a";
    // Name of the VM instance you want to query.
    String instanceName = "YOUR_INSTANCE_NAME";
    // machineType: machine type of the VM being created.
    // *   For a list of machine types, see https://cloud.google.com/compute/docs/machine-types
    String machineTypeName = "n1-standard-4";
    // sourceImage: path to the operating system image to mount.
    // *   For details about images you can mount, see https://cloud.google.com/compute/docs/images
    String sourceImage = "projects/debian-cloud/global/images/family/debian-11";
    // diskSizeGb: storage size of the boot disk to attach to the instance.
    long diskSizeGb = 10L;
    // networkName: network interface to associate with the instance.
    String networkName = "default";
    // Minimum CPU platform of the instances.
    String minCpuPlatform = "Intel Skylake";

    createInstanceAsync(projectId, zone, instanceName, machineTypeName, sourceImage,
        diskSizeGb, networkName, minCpuPlatform);
  }

  // Create a virtual machine targeted with the reserveAffinity field.
  // In this consumption model, existing and new VMs automatically consume a reservation
  // if their properties match the VM properties specified in the reservation.
  public static Instance createInstanceAsync(String projectId, String zone,
      String instanceName, String machineTypeName, String sourceImage,
      long diskSizeGb, String networkName, String minCpuPlatform)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    String machineType = String.format("zones/%s/machineTypes/%s", zone, machineTypeName);
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (InstancesClient instancesClient = InstancesClient.create()) {
      AttachedDisk disk =
          AttachedDisk.newBuilder()
              .setBoot(true)
              .setAutoDelete(true)
              .setType(AttachedDisk.Type.PERSISTENT.toString())
              .setDeviceName("disk-1")
              .setInitializeParams(
                  AttachedDiskInitializeParams.newBuilder()
                      .setSourceImage(sourceImage)
                      .setDiskSizeGb(diskSizeGb)
                      .build())
              .build();

      NetworkInterface networkInterface = NetworkInterface.newBuilder()
          .setName(networkName)
          .build();

      ReservationAffinity reservationAffinity =
          ReservationAffinity.newBuilder()
              .setConsumeReservationType(ANY_RESERVATION.toString())
              .build();

      Instance instanceResource =
          Instance.newBuilder()
              .setName(instanceName)
              .setMachineType(machineType)
              .addDisks(disk)
              .addNetworkInterfaces(networkInterface)
              .setMinCpuPlatform(minCpuPlatform)
              .setReservationAffinity(reservationAffinity)
              .build();

      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(projectId)
          .setZone(zone)
          .setInstanceResource(instanceResource)
          .build();

      OperationFuture<Operation, Operation> operation = instancesClient.insertAsync(
          insertInstanceRequest);

      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        return null;
      }
      return instancesClient.get(projectId, zone, instanceName);
    }
  }
}

Node.js

// Import the Compute library
const computeLib = require('@google-cloud/compute');
const compute = computeLib.protos.google.cloud.compute.v1;

// Instantiate a reservationsClient
const instancesClient = new computeLib.InstancesClient();
// Instantiate a zoneOperationsClient
const zoneOperationsClient = new computeLib.ZoneOperationsClient();

/**
 * TODO(developer): Update/uncomment these variables before running the sample.
 */
// The ID of the project where you want to create instance.
const projectId = await instancesClient.getProjectId();
// The zone in which to create instance.
const zone = 'us-central1-a';
// The name of the instance to create.
// const instanceName = 'instance-01';
// Machine type to use for VM.
const machineType = 'n1-standard-4';

// Create instance to consume reservation if their properties match the VM properties
async function callCreateInstanceToConsumeAnyReservation() {
  // Describe the size and source image of the boot disk to attach to the instance.
  const disk = new compute.Disk({
    boot: true,
    autoDelete: true,
    type: 'PERSISTENT',
    initializeParams: {
      diskSizeGb: '10',
      sourceImage: 'projects/debian-cloud/global/images/family/debian-12',
    },
  });

  //  Define networkInterface
  const networkInterface = new compute.NetworkInterface({
    name: 'global/networks/default',
  });

  // Define reservationAffinity
  const reservationAffinity = new compute.ReservationAffinity({
    consumeReservationType: 'ANY_RESERVATION',
  });

  // Create an instance
  const instance = new compute.Instance({
    name: instanceName,
    machineType: `zones/${zone}/machineTypes/${machineType}`,
    minCpuPlatform: 'Intel Skylake',
    disks: [disk],
    networkInterfaces: [networkInterface],
    reservationAffinity,
  });

  const [response] = await instancesClient.insert({
    project: projectId,
    instanceResource: instance,
    zone,
  });

  let operation = response.latestResponse;

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

  console.log(`Instance ${instanceName} created.`);
}

await callCreateInstanceToConsumeAnyReservation();

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 consume_any_project_reservation(
    project_id: str,
    zone: str,
    reservation_name: str,
    instance_name: str,
    machine_type: str = "n1-standard-1",
    min_cpu_platform: str = "Intel Ivy Bridge",
) -> compute_v1.Instance:
    """
    Creates a specific reservation in a single project and launches a VM
    that consumes the newly created reservation.
    Args:
        project_id (str): The ID of the Google Cloud project.
        zone (str): The zone to create the reservation.
        reservation_name (str): The name of the reservation to create.
        instance_name (str): The name of the instance to create.
        machine_type (str): The machine type for the instance.
        min_cpu_platform (str): The minimum CPU platform for the instance.
    """
    instance_properties = (
        compute_v1.AllocationSpecificSKUAllocationReservedInstanceProperties(
            machine_type=machine_type,
            min_cpu_platform=min_cpu_platform,
        )
    )

    reservation = compute_v1.Reservation(
        name=reservation_name,
        specific_reservation=compute_v1.AllocationSpecificSKUReservation(
            count=3,
            instance_properties=instance_properties,
        ),
    )

    # Create a reservation client
    client = compute_v1.ReservationsClient()
    operation = client.insert(
        project=project_id,
        zone=zone,
        reservation_resource=reservation,
    )
    wait_for_extended_operation(operation, "Reservation creation")

    instance = compute_v1.Instance()
    instance.name = instance_name
    instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
    instance.min_cpu_platform = min_cpu_platform
    instance.zone = zone

    # Set the reservation affinity to target any matching reservation
    instance.reservation_affinity = compute_v1.ReservationAffinity(
        consume_reservation_type="ANY_RESERVATION",  # Type of reservation to consume
    )
    # Define the disks for the instance
    instance.disks = [
        compute_v1.AttachedDisk(
            boot=True,  # Indicates that this is a boot disk
            auto_delete=True,  # The disk will be deleted when the instance is deleted
            initialize_params=compute_v1.AttachedDiskInitializeParams(
                source_image="projects/debian-cloud/global/images/family/debian-11",
                disk_size_gb=10,
            ),
        )
    ]
    instance.network_interfaces = [
        compute_v1.NetworkInterface(
            network="global/networks/default",  # The network to use
            access_configs=[
                compute_v1.AccessConfig(
                    name="External NAT",  # Name of the access configuration
                    type="ONE_TO_ONE_NAT",  # Type of access configuration
                )
            ],
        )
    ]
    # Create a request to insert the instance
    request = compute_v1.InsertInstanceRequest()
    request.zone = zone
    request.project = project_id
    request.instance_resource = instance

    vm_client = compute_v1.InstancesClient()
    operation = vm_client.insert(request)
    wait_for_extended_operation(operation, "instance creation")
    print(f"Instance {instance_name} that targets any open reservation created.")

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

REST

  1. Cree una reserva abierta llamada reservation-01.

    POST https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/reservations
    
    {
      "name": "reservation-01",
      "specificReservation": {
        "count": "2",
        "instanceProperties": {
          "machineType": "n2-standard-32",
          "minCpuPlatform": "Intel Cascade Lake",
        }
      }
    }
    
  2. Crea una instancia de VM que se dirija a cualquier reserva abierta y que coincida con las propiedades de la instancia en reservation-01, incluida la zona, el tipo de máquina (familia de máquinas, CPU virtuales y memoria), la plataforma de CPU mínima, la cantidad y el tipo de GPU, y la cantidad y la interfaz del SSD local.

    POST https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances
    
    {
      "name": "instance-1",
      "machineType": "zones/us-central1-a/machineTypes/n2-standard-32",
      "minCpuPlatform": "Intel Cascade Lake",
      "disks": [
        {
          "boot": true,
          "initializeParams": {
            "sourceImage": "projects/debian-cloud/global/images/family/debian-12"
          }
        }
      ],
      "networkInterfaces": [
        {
          "network": "global/networks/default"
        }
      ],
      "reservationAffinity": {
        "consumeReservationType": "ANY_RESERVATION"
      }
    }
    

Consume las VMs de una reserva específica

En este modelo de consumo, solo las instancias nuevas que se dirigen a una reserva específica por nombre consumen esa reserva, y la reserva no se consume de forma automática.

Cuando crees la reserva, especifica que las instancias son necesarias para orientar la reserva específica mediante uno de los siguientes métodos:

  • En la consola de Google Cloud, selecciona la casilla de verificación Seleccionar reserva específica.
  • En la CLI de gcloud, incluye la marca --require-specific-reservation.
  • En la API de Compute Engine, establece el campo specificReservationRequired en true.
  • En Terraform, establece el campo specific_reservation_required en true.

Luego, crea VMs que se orienten a esa reserva de forma específica. Solo puedes crear una VM que se oriente a una reserva específica si las propiedades de la VM y las propiedades de la reserva coinciden. De lo contrario, la creación de la VMfalla.

Si usas una plantilla de instancia para crear VM en un grupo de instancias administrado regional, crea reservas idénticas con el mismo nombre en cada zona aplicable. Luego, organiza las reservas por nombre en la plantilla de instancia del grupo.

Por ejemplo, crea una reserva específica llamada reservation-02 y, luego, crea una VM coincidente que se dirija a esa reserva y que coincida con sus propiedades de la VM.

Según el tipo de VM que quieras consumir, sigue los pasos que se indican en Consume una reserva específica de un solo proyecto o Consume una reserva compartida específica.

Consume una reserva específica de un solo proyecto

Para consumir una reserva específica de un solo proyecto, selecciona una de las siguientes opciones:

Console

  1. Para crear una reserva con recursos que solo puedan usar las instancias de VM que se dirigen a la reserva de forma específica por nombre, sigue estos pasos:

    1. Selecciona una de las opciones siguientes:

      • Para crear una reserva independiente, haz lo siguiente:

        1. En la consola de Google Cloud, ve a la página Reservas.

          Ir a Reservas

        2. En la pestaña Reservas según demanda (predeterminada), haz clic en Crear reserva.

          Se abrirá la página Crear una reserva.

      • Para crear una reserva vinculada a un compromiso, haz lo siguiente:

        1. En la consola de Google Cloud, ve a la página Descuentos por compromiso de uso.

          Ir a Descuentos por compromiso de uso

        2. Haz clic en Compromiso de compra.

          Se abrirá la página Comprar un descuento por compromiso de uso.

        3. Especifica las propiedades del compromiso. Luego, en la sección Reservas, haz clic en Agregar un elemento.

          Aparecerá la sección Agregar una reserva nueva.

          Para obtener más información sobre cómo adquirir un compromiso con una reserva vinculada, consulta Adquiere compromisos con reservas adjuntas.

    2. En el campo Nombre, ingresa el nombre de tu reserva. En este ejemplo, ingresa reservation-02.

    3. Elige la región y zona en la que deseas reservar los recursos. En este ejemplo, selecciona us-central1 como región y us-central1-a como zona.

    4. Para especificar que tu reserva será una de un solo proyecto, selecciona Local como el Tipo de recurso compartido.

    5. En la sección Usar con instancia de VM, selecciona Seleccionar reserva específica para que solo las instancias de VM que se dirigen a esta reserva de forma específica por nombre puedan usarla.

    6. En el campo Cantidad de instancias de VMs, escribe la cantidad de VMs que deseas reservar. En este ejemplo, ingresa 10.

    7. Especifica los recursos que deseas reservar para cada instancia de VM:

      • Si deseas reservar VM que coincidan con una plantilla de instancias existente, selecciona Usar plantilla de instancias y selecciona una plantilla de instancias de la lista.
      • De lo contrario, selecciona Especificar tipo de máquina y especifica lo siguiente:
        1. En los campos Familia de máquinas, Serie y Tipo de máquina, selecciona una familia de máquinas, series y tipos de máquinas.
        2. Especifica una plataforma de CPU mínima o GPU (opcional):
          1. Para expandir la sección Plataforma de CPU y GPU, haz clic en la flecha de expansión .
          2. Opcional: Para especificar una plataforma de CPU mínima, selecciona una opción en la lista Formulario de CPU.
          3. Opcional: Para agregar GPU, haz clic en Agregar GPU. Luego, en los campos Tipo de GPU y Cantidad de GPU, elige el tipo y la cantidad de GPU para cada VM.
        3. Opcional: Agrega SSD locales:
          1. En el campo Cantidad de discos, elige la cantidad de SSD locales para cada VM.
          2. En el campo Tipo de interfaz, selecciona la interfaz para las SSD locales.

      Para este ejemplo, selecciona Especificar tipo de máquina. Luego, selecciona el tipo de máquina n2-standard-32 para la familia de máquinas General-purpose y la serie N2. Luego, selecciona la plataforma de CPU mínima Intel Cascade Lake.

    8. Termina de crear la reserva:

      • Si quieres crear una reserva independiente, haz clic en Crear.

      • Si quieres crear una reserva vinculada a un compromiso, ejecuta este comando:

        1. Para terminar de especificar las propiedades de esta reserva, haz clic en Listo.
        2. Para terminar de crear el compromiso y las reservas adjuntas, haz clic en Comprar.
  2. En el mismo proyecto, crea una instancia de VM que se dirija a esa reserva específica por nombre.

    Asegúrate de que las propiedades de la VM coincidan con las propiedades de la VM de esa reserva específica, incluida la zona, el tipo de máquina (familia de máquinas, CPU virtuales y memoria), la plataforma de CPU mínima, la cantidad y el tipo de GPU y el tamaño y la interfaz SSD local.

    Para obtener más información sobre cómo crear una VM, consulta Crea y, luego, inicia una VM.

    1. En la consola de Google Cloud, ve a la página Crear una instancia.

      Ir a Crear una instancia

    2. En el campo Nombre, ingresa un nombre para la VM.

    3. En las siguientes secciones, selecciona una configuración que coincida con exactitud con todas las propiedades de tu reserva, incluidas las propiedades opcionales. Para este ejemplo, debes hacer coincidir las siguientes propiedades de instancia de VM con reservation-02:

      • Región: us-central1
      • Zona: us-central1-a
      • Tipo de máquina: n2-standard-32
      • Plataforma de CPU mínima: Intel Cascade Lake
      • GPU: Ninguna
      • SSD locales: Ninguno
    4. Expande la sección Opciones avanzadas y sigue estos pasos:

      1. Expande la sección Administración.

      2. En la sección Reservas, en la lista Política de la aplicación, selecciona Seleccionar reserva específica.

      3. Selecciona la reserva con las propiedades de VM coincidentes que deseas que consume tu VM. Para este ejemplo, selecciona reservation-02.

    5. Para crear la VM, haz clic en Crear.

gcloud

  1. Crea una reserva llamada reservation-02 con la marca --require-specific-reservation. Estos recursos reservados solo los pueden usar las instancias que se dirigen a esta reserva de forma específica por nombre.

    gcloud compute reservations create reservation-02 \
        --machine-type=n2-standard-32 \
        --min-cpu-platform="Intel Cascade Lake" \
        --vm-count=10 \
        --zone=us-central1-a \
        --require-specific-reservation
    
  2. Crea una instancia de VM que se dirija a reservation-02 por nombre mediante las marcas --reservation-affinity y --reservation.

    Asegúrate de que las propiedades de la VM coincidan con las propiedades de la VM de la reserva, incluida la zona, el tipo de máquina (familia de máquinas, CPU virtuales y memoria), la plataforma de CPU mínima, la cantidad y el tipo de GPU y la interfaz y SSD locales SSD. tamaño.

    gcloud compute instances create instance-2 \
        --machine-type=n2-standard-32 \
        --min-cpu-platform="Intel Cascade Lake" \
        --zone=us-central1-a \
        --reservation-affinity=specific \
        --reservation=reservation-02
    

Go

import (
	"context"
	"fmt"
	"io"

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

// consumeSpecificReservation creates instance, consuming specific reservation
// Note: respective reservation should have SpecificReservationRequired: true
func consumeSpecificReservation(w io.Writer, projectID, zone, instanceName, reservationName string) error {
	// projectID := "your_project_id"
	// zone := "us-west3-a"
	// reservationName := "your_reservation_name"
	// instanceName := "your_instance_name"

	ctx := context.Background()
	machineType := fmt.Sprintf("zones/%s/machineTypes/%s", zone, "n2-standard-32")
	sourceImage := "projects/debian-cloud/global/images/family/debian-12"

	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{
			Disks: []*computepb.AttachedDisk{
				{
					InitializeParams: &computepb.AttachedDiskInitializeParams{
						DiskSizeGb:  proto.Int64(10),
						SourceImage: proto.String(sourceImage),
					},
					AutoDelete: proto.Bool(true),
					Boot:       proto.Bool(true),
					Type:       proto.String(computepb.AttachedDisk_PERSISTENT.String()),
				},
			},
			MachineType:    proto.String(machineType),
			MinCpuPlatform: proto.String("Intel Cascade Lake"),
			Name:           proto.String(instanceName),
			NetworkInterfaces: []*computepb.NetworkInterface{
				{
					Name: proto.String("global/networks/default"),
				},
			},
			// specifies particular reservation, which should be consumed
			ReservationAffinity: &computepb.ReservationAffinity{
				ConsumeReservationType: proto.String("SPECIFIC_RESERVATION"),
				Key:                    proto.String("compute.googleapis.com/reservation-name"),
				Values:                 []string{reservationName},
			},
		},
	}

	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 from reservation\n")

	return nil
}

Java

import static com.google.cloud.compute.v1.ReservationAffinity.ConsumeReservationType.SPECIFIC_RESERVATION;

import com.google.api.gax.longrunning.OperationFuture;
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.InstancesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.ReservationAffinity;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ConsumeSingleProjectReservation {
  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the zone where the reservation is located.
    String zone = "us-central1-a";
    // Name of the reservation you want to query.
    String reservationName = "YOUR_RESERVATION_NAME";
    // Name of the VM instance you want to query.
    String instanceName = "YOUR_INSTANCE_NAME";
    // machineType: machine type of the VM being created.
    // *   For a list of machine types, see https://cloud.google.com/compute/docs/machine-types
    String machineTypeName = "n1-standard-4";
    // sourceImage: path to the operating system image to mount.
    // *   For details about images you can mount, see https://cloud.google.com/compute/docs/images
    String sourceImage = "projects/debian-cloud/global/images/family/debian-11";
    // diskSizeGb: storage size of the boot disk to attach to the instance.
    long diskSizeGb = 10L;
    // networkName: network interface to associate with the instance.
    String networkName = "default";
    // Minimum CPU platform of the instances.
    String minCpuPlatform = "Intel Skylake";

    createInstanceAsync(projectId, zone, instanceName, reservationName, machineTypeName,
        sourceImage, diskSizeGb, networkName, minCpuPlatform);
  }

  // Create a virtual machine targeted with the reserveAffinity field.
  // Ensure that the VM's properties match the reservation's VM properties.
  public static Instance createInstanceAsync(String projectId, String zone, String instanceName,
      String reservationName, String machineTypeName, String sourceImage, long diskSizeGb,
      String networkName, String minCpuPlatform)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    String machineType = String.format("zones/%s/machineTypes/%s", zone, machineTypeName);
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (InstancesClient instancesClient = InstancesClient.create()) {
      AttachedDisk disk =
          AttachedDisk.newBuilder()
              .setBoot(true)
              .setAutoDelete(true)
              .setType(AttachedDisk.Type.PERSISTENT.toString())
              .setDeviceName("disk-1")
              .setInitializeParams(
                  AttachedDiskInitializeParams.newBuilder()
                      .setSourceImage(sourceImage)
                      .setDiskSizeGb(diskSizeGb)
                      .build())
              .build();

      NetworkInterface networkInterface = NetworkInterface.newBuilder()
          .setName(networkName)
          .build();

      ReservationAffinity reservationAffinity =
          ReservationAffinity.newBuilder()
              .setConsumeReservationType(SPECIFIC_RESERVATION.toString())
              .setKey("compute.googleapis.com/reservation-name")
              // Set specific reservation
              .addValues(reservationName)
              .build();

      Instance instanceResource =
          Instance.newBuilder()
              .setName(instanceName)
              .setMachineType(machineType)
              .addDisks(disk)
              .addNetworkInterfaces(networkInterface)
              .setMinCpuPlatform(minCpuPlatform)
              .setReservationAffinity(reservationAffinity)
              .build();

      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(projectId)
          .setZone(zone)
          .setInstanceResource(instanceResource)
          .build();

      OperationFuture<Operation, Operation> operation = instancesClient.insertAsync(
          insertInstanceRequest);
      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        return null;
      }
      return instancesClient.get(projectId, zone, instanceName);
    }
  }
}

Node.js

// Import the Compute library
const computeLib = require('@google-cloud/compute');
const compute = computeLib.protos.google.cloud.compute.v1;

// Instantiate a reservationsClient
const instancesClient = new computeLib.InstancesClient();
// Instantiate a zoneOperationsClient
const zoneOperationsClient = new computeLib.ZoneOperationsClient();

/**
 * TODO(developer): Update/uncomment these variables before running the sample.
 */
// The ID of the project where you want to create instance.
const projectId = await instancesClient.getProjectId();
// The zone in which to create instance.
const zone = 'us-central1-a';
// The name of the instance to create.
// const instanceName = 'instance-01';
// The name of the reservation to consume.
// Ensure that the specificReservationRequired field in reservation properties is set to true.
// const reservationName = 'reservation-01';
// Machine type to use for VM.
const machineType = 'n1-standard-4';

// Create instance to consume a specific single-project reservation
async function callCreateInstanceToConsumeSingleProjectReservation() {
  // Describe the size and source image of the boot disk to attach to the instance.
  // Ensure that the VM's properties match the reservation's VM properties,
  // including the zone, machine type (machine family, vCPUs, and memory),
  // minimum CPU platform, GPU amount and type, and local SSD interface and size
  const disk = new compute.Disk({
    boot: true,
    autoDelete: true,
    type: 'PERSISTENT',
    initializeParams: {
      diskSizeGb: '10',
      sourceImage: 'projects/debian-cloud/global/images/family/debian-12',
    },
  });

  //  Define networkInterface
  const networkInterface = new compute.NetworkInterface({
    name: 'global/networks/default',
  });

  // Define reservationAffinity
  const reservationAffinity = new compute.ReservationAffinity({
    consumeReservationType: 'SPECIFIC_RESERVATION',
    key: 'compute.googleapis.com/reservation-name',
    values: [reservationName],
  });

  // Create an instance
  const instance = new compute.Instance({
    name: instanceName,
    machineType: `zones/${zone}/machineTypes/${machineType}`,
    minCpuPlatform: 'Intel Skylake',
    disks: [disk],
    networkInterfaces: [networkInterface],
    reservationAffinity,
  });

  const [response] = await instancesClient.insert({
    project: projectId,
    instanceResource: instance,
    zone,
  });

  let operation = response.latestResponse;

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

  console.log(`Instance ${instanceName} created.`);
}

await callCreateInstanceToConsumeSingleProjectReservation();

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 consume_specific_single_project_reservation(
    project_id: str,
    zone: str,
    reservation_name: str,
    instance_name: str,
    machine_type: str = "n1-standard-1",
    min_cpu_platform: str = "Intel Ivy Bridge",
) -> compute_v1.Instance:
    """
    Creates a specific reservation in a single project and launches a VM
    that consumes the newly created reservation.
    Args:
        project_id (str): The ID of the Google Cloud project.
        zone (str): The zone to create the reservation.
        reservation_name (str): The name of the reservation to create.
        instance_name (str): The name of the instance to create.
        machine_type (str): The machine type for the instance.
        min_cpu_platform (str): The minimum CPU platform for the instance.
    """
    instance_properties = (
        compute_v1.AllocationSpecificSKUAllocationReservedInstanceProperties(
            machine_type=machine_type,
            min_cpu_platform=min_cpu_platform,
        )
    )

    reservation = compute_v1.Reservation(
        name=reservation_name,
        specific_reservation=compute_v1.AllocationSpecificSKUReservation(
            count=3,
            instance_properties=instance_properties,
        ),
        # Only VMs that target the reservation by name can consume from this reservation
        specific_reservation_required=True,
    )

    # Create a reservation client
    client = compute_v1.ReservationsClient()
    operation = client.insert(
        project=project_id,
        zone=zone,
        reservation_resource=reservation,
    )
    wait_for_extended_operation(operation, "Reservation creation")

    instance = compute_v1.Instance()
    instance.name = instance_name
    instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
    instance.min_cpu_platform = min_cpu_platform
    instance.zone = zone

    # Set the reservation affinity to target the specific reservation
    instance.reservation_affinity = compute_v1.ReservationAffinity(
        consume_reservation_type="SPECIFIC_RESERVATION",  # Type of reservation to consume
        key="compute.googleapis.com/reservation-name",  # Key for the reservation
        values=[reservation_name],  # Reservation name to consume
    )
    # Define the disks for the instance
    instance.disks = [
        compute_v1.AttachedDisk(
            boot=True,  # Indicates that this is a boot disk
            auto_delete=True,  # The disk will be deleted when the instance is deleted
            initialize_params=compute_v1.AttachedDiskInitializeParams(
                source_image="projects/debian-cloud/global/images/family/debian-11",
                disk_size_gb=10,
            ),
        )
    ]
    instance.network_interfaces = [
        compute_v1.NetworkInterface(
            network="global/networks/default",  # The network to use
            access_configs=[
                compute_v1.AccessConfig(
                    name="External NAT",  # Name of the access configuration
                    type="ONE_TO_ONE_NAT",  # Type of access configuration
                )
            ],
        )
    ]
    # Create a request to insert the instance
    request = compute_v1.InsertInstanceRequest()
    request.zone = zone
    request.project = project_id
    request.instance_resource = instance

    vm_client = compute_v1.InstancesClient()
    operation = vm_client.insert(request)
    wait_for_extended_operation(operation, "instance creation")
    print(f"Instance {instance_name} with specific reservation created successfully.")

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

REST

  1. Crea una reserva llamada reservation-02 con el campo specificReservationRequired configurado como true.

    POST https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/reservations
    
    {
      "name":"reservation-02",
      "specificReservation":{
        "count":"10",
        "instanceProperties":{
          "machineType":"n2-standard-32",
          "minCpuPlatform": "Intel Cascade Lake",
        }
      },
      "specificReservationRequired": true
    }
    
  2. Crea una instancia de VM que se dirija a reservation-02 por nombre mediante el campo reservationAffinity.

    Asegúrate de que las propiedades de la VM coincidan con las propiedades de la VM de la reserva, incluida la zona, el tipo de máquina (familia de máquinas, CPU virtuales y memoria), la plataforma de CPU mínima, la cantidad y el tipo de GPU y la interfaz y SSD locales SSD. tamaño.

    POST https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances
    
    {
      "name": "instance-2",
      "machineType": "zones/us-central1-a/machineTypes/n2-standard-32",
      "minCpuPlatform": "Intel Cascade Lake",
      "disks": [
        {
          "boot": true,
          "initializeParams": {
            "sourceImage": "projects/debian-clouid/global/images/family/debian-12"
          }
        }
      ],
      "networkInterfaces": [
        {
          "network": "global/networks/default"
        }
      ],
      "reservationAffinity": {
        "consumeReservationType": "SPECIFIC_RESERVATION",
        "key": "compute.googleapis.com/reservation-name",
        "values": [
          "reservation-02"
        ]
      }
    }
    

Consume una reserva compartida específica

Para consumir una reserva compartida específica, selecciona una de las siguientes opciones:

Console

  1. Para crear una reserva compartida con recursos que solo puedan usar las instancias de VM que se dirigen a esta reserva de forma específica por nombre, sigue estos pasos:

    1. Selecciona una de las opciones siguientes:

      • Para crear una reserva independiente, haz lo siguiente:

        1. En la consola de Google Cloud, ve a la página Reservas.

          Ir a Reservas

        2. En la pestaña Reservas según demanda (predeterminada), haz clic en Crear reserva.

          Se abrirá la página Crear una reserva.

      • Para crear una reserva vinculada a un compromiso, haz lo siguiente:

        1. En la consola de Google Cloud, ve a la página Descuentos por compromiso de uso.

          Ir a Descuentos por compromiso de uso

        2. Haz clic en Compromiso de compra.

          Se abrirá la página Comprar un descuento por compromiso de uso.

        3. Especifica las propiedades del compromiso. Luego, en la sección Reservas, haz clic en Agregar un elemento.

          Aparecerá la sección Agregar una reserva nueva.

          Para obtener más información sobre cómo adquirir un compromiso con una reserva vinculada, consulta Adquiere compromisos con reservas adjuntas.

    2. En el campo Nombre, ingresa el nombre de tu reserva. En este ejemplo, ingresa reservation-02.

    3. Elige la región y zona en la que deseas reservar los recursos. En este ejemplo, selecciona us-central1 como región y us-central1-a como zona.

    4. Para especificar que tu reserva es una reserva compartida, selecciona Compartido como el Tipo de recurso compartido.

    5. Haz clic en Agregar proyectos y selecciona los proyectos de la organización actual del proyecto con el que deseas compartir la reserva.

    6. En la sección Usar con instancia de VM, selecciona Seleccionar reserva específica para que solo las instancias de VM que se dirigen a esta reserva de forma específica por nombre puedan usarla.

    7. En el campo Cantidad de instancias de VMs, escribe la cantidad de VMs que deseas reservar. En este ejemplo, ingresa 10.

    8. Especifica los recursos que deseas reservar para cada instancia de VM:

      • Si deseas reservar VM que coincidan con una plantilla de instancias existente, selecciona Usar plantilla de instancias y selecciona una plantilla de instancias de la lista.
      • De lo contrario, selecciona Especificar tipo de máquina y especifica lo siguiente:
        1. En los campos Familia de máquinas, Serie y Tipo de máquina, selecciona una familia de máquinas, series y tipos de máquinas.
        2. Especifica una plataforma de CPU mínima o GPU (opcional):
          1. Para expandir la sección Plataforma de CPU y GPU, haz clic en la flecha de expansión .
          2. Opcional: Para especificar una plataforma de CPU mínima, selecciona una opción en la lista Formulario de CPU.
          3. Opcional: Para agregar GPU, haz clic en Agregar GPU. Luego, en los campos Tipo de GPU y Cantidad de GPU, elige el tipo y la cantidad de GPU para cada VM.
        3. Opcional: Agrega SSD locales:
          1. En el campo Cantidad de discos, elige la cantidad de SSD locales para cada VM.
          2. En el campo Tipo de interfaz, selecciona la interfaz para las SSD locales.

      Para este ejemplo, selecciona Especificar tipo de máquina. Luego, selecciona el tipo de máquina n2-standard-32 para la familia de máquinas General-purpose y la serie N2. Luego, selecciona la plataforma de CPU mínima Intel Cascade Lake. 1. Termina de crear la reserva:

      • Si quieres crear una reserva independiente, haz clic en Crear.

      • Si quieres crear una reserva vinculada a un compromiso, ejecuta este comando:

        1. Para terminar de especificar las propiedades de esta reserva, haz clic en Listo.
        2. Para terminar de crear el compromiso y las reservas adjuntas, haz clic en Comprar.
  2. En el mismo proyecto o en el que se comparte la reserva, crea una instancia de VM que se dirija a esa reserva específica por nombre.

    Asegúrate de que las propiedades de la VM coincidan con las propiedades de la VM de esa reserva específica, incluida la zona, el tipo de máquina (familia de máquinas, CPU virtuales y memoria), la plataforma de CPU mínima, la cantidad y el tipo de GPU y el tamaño y la interfaz SSD local.

    1. En la consola de Google Cloud, ve a la página Crear una instancia.

      Ir a Crear una instancia

      Se abrirá la página Crea una instancia.

    2. Especifica un Nombre para la VM.

    3. En las siguientes secciones, selecciona una configuración que coincida con exactitud con todas las propiedades de tu reserva, incluidas las propiedades opcionales. Para este ejemplo, debes hacer coincidir las siguientes propiedades de instancia de VM con reservation-02:

      • Región: us-central1
      • Zona: us-central1-a
      • Tipo de máquina: n2-standard-32
      • Plataforma de CPU mínima: Intel Cascade Lake
      • GPU: Ninguna
      • SSD locales: Ninguno
    4. Expande la sección Opciones avanzadas y, luego, la sección Administración. En la lista Reservas, selecciona Seleccionar reserva específica y, luego, haz lo siguiente:

      1. Selecciona un Proyecto de reserva que tenga reservas compartidas con tu proyecto actual. En este ejemplo, selecciona el proyecto que usaste para crear reservation-02.
      2. Selecciona el Nombre de reserva de la reserva compartida que deseas que consuma esta instancia de VM. Para este ejemplo, selecciona reservation-02.
    5. Para crear la VM, haz clic en Crear.

gcloud

  1. Crea una reserva llamada reservation-02 con la marca --require-specific-reservation. Estos recursos reservados solo los pueden usar las instancias que se dirigen a esta reserva de forma específica por nombre.

    gcloud compute reservations create reservation-02 \
        --machine-type=n2-standard-32 \
        --min-cpu-platform="Intel Cascade Lake" \
        --vm-count=10 \
        --zone=us-central1-a \
        --project=my-owner-project \
        --share-setting=projects \
        --share-with=project-1,project-2 \
        --require-specific-reservation
    
  2. Crea una instancia de VM que se dirija a reservation-02 por nombre mediante las marcas --reservation-affinity y --reservation. Para consumir esta reserva desde cualquier proyecto de consumidor con el que se comparta esta reserva, también debes especificar el proyecto que creó la reserva, my-owner-project.

    Asegúrate de que las propiedades de la VM coincidan con las propiedades de la VM de la reserva, incluida la zona, el tipo de máquina (familia de máquinas, CPU virtuales y memoria), la plataforma de CPU mínima, la cantidad y el tipo de GPU y la interfaz y SSD locales SSD. tamaño.

    gcloud compute instances create instance-2 \
        --machine-type=n2-standard-32 \
        --min-cpu-platform="Intel Cascade Lake" \
        --zone=us-central1-a \
        --reservation-affinity=specific \
        --reservation=projects/my-owner-project/reservations/reservation-02
    

Go

import (
	"context"
	"fmt"
	"io"

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

// consumeSpecificSharedReservation consumes specific shared reservation in particular zone
func consumeSpecificSharedReservation(w io.Writer, client InstanceClientInterface, projectID, baseProjectId, zone, instanceName, reservationName string) error {
	// client, err := compute.NewInstancesRESTClient(ctx)
	// projectID := "your_project_id". Project where reservation is created.
	// baseProjectId := "shared_project_id". Project where instance will be consumed and created.
	// zone := "us-west3-a"
	// reservationName := "your_reservation_name"
	// instanceName := "your_instance_name"

	ctx := context.Background()
	machineType := fmt.Sprintf("zones/%s/machineTypes/%s", zone, "n2-standard-32")
	sourceImage := "projects/debian-cloud/global/images/family/debian-12"
	sharedReservation := fmt.Sprintf("projects/%s/reservations/%s", baseProjectId, reservationName)

	req := &computepb.InsertInstanceRequest{
		Project: projectID,
		Zone:    zone,
		InstanceResource: &computepb.Instance{
			Disks: []*computepb.AttachedDisk{
				{
					InitializeParams: &computepb.AttachedDiskInitializeParams{
						DiskSizeGb:  proto.Int64(10),
						SourceImage: proto.String(sourceImage),
					},
					AutoDelete: proto.Bool(true),
					Boot:       proto.Bool(true),
					Type:       proto.String(computepb.AttachedDisk_PERSISTENT.String()),
				},
			},
			MachineType:    proto.String(machineType),
			MinCpuPlatform: proto.String("Intel Cascade Lake"),
			Name:           proto.String(instanceName),
			NetworkInterfaces: []*computepb.NetworkInterface{
				{
					Name: proto.String("global/networks/default"),
				},
			},
			// specifies particular reservation, which should be consumed
			ReservationAffinity: &computepb.ReservationAffinity{
				ConsumeReservationType: proto.String("SPECIFIC_RESERVATION"),
				Key:                    proto.String("compute.googleapis.com/reservation-name"),
				Values:                 []string{sharedReservation},
			},
		},
	}

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

	if op != nil {
		if err = op.Wait(ctx); err != nil {
			return fmt.Errorf("unable to wait for the operation: %w", err)
		}
	}
	fmt.Fprintf(w, "Instance created from shared reservation\n")

	return nil
}

Java

import static com.google.cloud.compute.v1.ReservationAffinity.ConsumeReservationType.SPECIFIC_RESERVATION;

import com.google.api.gax.longrunning.OperationFuture;
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.InstancesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.ReservationAffinity;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ConsumeSpecificSharedReservation {
  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the zone the reservation is located.
    String zone = "us-central1-a";
    // Name of the reservation you want to query.
    String reservationName = "YOUR_RESERVATION_NAME";
    // Name of the VM instance you want to query.
    String instanceName = "YOUR_INSTANCE_NAME";
    // machineType: machine type of the VM being created.
    // *   For a list of machine types, see https://cloud.google.com/compute/docs/machine-types
    String machineTypeName = "n1-standard-4";
    // sourceImage: path to the operating system image to mount.
    // *   For details about images you can mount, see https://cloud.google.com/compute/docs/images
    String sourceImage = "projects/debian-cloud/global/images/family/debian-11";
    // diskSizeGb: storage size of the boot disk to attach to the instance.
    long diskSizeGb = 10L;
    // networkName: network interface to associate with the instance.
    String networkName = "default";
    // Minimum CPU platform of the instances.
    String minCpuPlatform = "Intel Skylake";

    createInstanceAsync(projectId, zone, instanceName, reservationName, machineTypeName,
        sourceImage, diskSizeGb, networkName, minCpuPlatform);
  }

  // Create a virtual machine targeted with the reserveAffinity field.
  // Ensure that the VM's properties match the reservation's VM properties.
  public static Instance createInstanceAsync(String projectId, String zone, String instanceName,
      String reservationName, String machineTypeName, String sourceImage, long diskSizeGb,
      String networkName, String minCpuPlatform)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    String machineType = String.format("zones/%s/machineTypes/%s", zone, machineTypeName);
    // To consume this reservation from any consumer projects that this reservation is shared with,
    // you must also specify the owner project of the reservation - the path to the reservation.
    String reservationPath =
        String.format("projects/%s/reservations/%s", projectId, reservationName);
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (InstancesClient instancesClient = InstancesClient.create()) {
      AttachedDisk disk =
          AttachedDisk.newBuilder()
              .setBoot(true)
              .setAutoDelete(true)
              .setType(AttachedDisk.Type.PERSISTENT.toString())
              .setDeviceName("disk-1")
              .setInitializeParams(
                  AttachedDiskInitializeParams.newBuilder()
                      .setSourceImage(sourceImage)
                      .setDiskSizeGb(diskSizeGb)
                      .build())
              .build();

      NetworkInterface networkInterface = NetworkInterface.newBuilder()
          .setName(networkName)
          .build();

      ReservationAffinity reservationAffinity =
          ReservationAffinity.newBuilder()
              .setConsumeReservationType(SPECIFIC_RESERVATION.toString())
              .setKey("compute.googleapis.com/reservation-name")
              // Set specific reservation
              .addValues(reservationPath)
              .build();

      Instance instanceResource =
          Instance.newBuilder()
              .setName(instanceName)
              .setMachineType(machineType)
              .addDisks(disk)
              .addNetworkInterfaces(networkInterface)
              .setMinCpuPlatform(minCpuPlatform)
              .setReservationAffinity(reservationAffinity)
              .build();

      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(projectId)
          .setZone(zone)
          .setInstanceResource(instanceResource)
          .build();

      OperationFuture<Operation, Operation> operation = instancesClient.insertAsync(
          insertInstanceRequest);
      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        return null;
      }
      return instancesClient.get(projectId, zone, instanceName);
    }
  }
}

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 consume_specific_shared_project_reservation(
    owner_project_id: str,
    shared_project_id: str,
    zone: str,
    reservation_name: str,
    instance_name: str,
    machine_type: str = "n1-standard-1",
    min_cpu_platform: str = "Intel Ivy Bridge",
) -> compute_v1.Instance:
    """
    Creates a specific reservation in a single project and launches a VM
    that consumes the newly created reservation.
    Args:
        owner_project_id (str): The ID of the Google Cloud project.
        shared_project_id: The ID of the owner project of the reservation in the same zone.
        zone (str): The zone to create the reservation.
        reservation_name (str): The name of the reservation to create.
        instance_name (str): The name of the instance to create.
        machine_type (str): The machine type for the instance.
        min_cpu_platform (str): The minimum CPU platform for the instance.
    """
    instance_properties = (
        compute_v1.AllocationSpecificSKUAllocationReservedInstanceProperties(
            machine_type=machine_type,
            min_cpu_platform=min_cpu_platform,
        )
    )

    reservation = compute_v1.Reservation(
        name=reservation_name,
        specific_reservation=compute_v1.AllocationSpecificSKUReservation(
            count=3,
            instance_properties=instance_properties,
        ),
        # Only VMs that target the reservation by name can consume from this reservation
        specific_reservation_required=True,
        share_settings=compute_v1.ShareSettings(
            share_type="SPECIFIC_PROJECTS",
            project_map={
                shared_project_id: compute_v1.ShareSettingsProjectConfig(
                    project_id=shared_project_id
                )
            },
        ),
    )

    # Create a reservation client
    client = compute_v1.ReservationsClient()
    operation = client.insert(
        project=owner_project_id,
        zone=zone,
        reservation_resource=reservation,
    )
    wait_for_extended_operation(operation, "Reservation creation")

    instance = compute_v1.Instance()
    instance.name = instance_name
    instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
    instance.min_cpu_platform = min_cpu_platform
    instance.zone = zone

    # Set the reservation affinity to target the specific reservation
    instance.reservation_affinity = compute_v1.ReservationAffinity(
        consume_reservation_type="SPECIFIC_RESERVATION",  # Type of reservation to consume
        key="compute.googleapis.com/reservation-name",
        # To consume this reservation from any consumer projects, specify the owner project of the reservation
        values=[f"projects/{owner_project_id}/reservations/{reservation_name}"],
    )
    # Define the disks for the instance
    instance.disks = [
        compute_v1.AttachedDisk(
            boot=True,  # Indicates that this is a boot disk
            auto_delete=True,  # The disk will be deleted when the instance is deleted
            initialize_params=compute_v1.AttachedDiskInitializeParams(
                source_image="projects/debian-cloud/global/images/family/debian-11",
                disk_size_gb=10,
            ),
        )
    ]
    instance.network_interfaces = [
        compute_v1.NetworkInterface(
            network="global/networks/default",  # The network to use
            access_configs=[
                compute_v1.AccessConfig(
                    name="External NAT",  # Name of the access configuration
                    type="ONE_TO_ONE_NAT",  # Type of access configuration
                )
            ],
        )
    ]
    # Create a request to insert the instance
    request = compute_v1.InsertInstanceRequest()
    request.zone = zone
    # The instance will be created in the shared project
    request.project = shared_project_id
    request.instance_resource = instance

    vm_client = compute_v1.InstancesClient()
    operation = vm_client.insert(request)
    wait_for_extended_operation(operation, "instance creation")
    print(f"Instance {instance_name} from project {owner_project_id} created.")
    # The instance is created in the shared project, so we return it from there.
    return vm_client.get(project=shared_project_id, zone=zone, instance=instance_name)

REST

  1. Crea una reserva llamada reservation-02 con el campo specificReservationRequired configurado como true.

    POST https://compute.googleapis.com/compute/v1/projects/my-owner-project/zones/us-central1-a/reservations
    
    {
      "name":"reservation-02",
      "specificReservation":{
        "count":"10",
        "instanceProperties":{
          "machineType":"n2-standard-32",
          "minCpuPlatform": "Intel Cascade Lake"
        }
      },
      "shareSettings": {
        "shareType": "SPECIFIC_PROJECTS",
        "projectMap": {
          "project-1": {
            "projectId": "project-1"
          },
          "project-2": {
            "projectId": "project-2"
          }
        }
      },
      "specificReservationRequired": true
    }
    
  2. Crea una instancia de VM que se dirija a reservation-02 por nombre mediante el campo reservationAffinity. Para consumir esta reserva desde cualquier proyecto de consumidor con el que se comparta esta reserva, también debes especificar el proyecto de propietario de la reserva, my-owner-project.

    Asegúrate de que las propiedades de la VM coincidan con las propiedades de la VM de la reserva, incluida la zona, el tipo de máquina (familia de máquinas, CPU virtuales y memoria), la plataforma de CPU mínima, la cantidad y el tipo de GPU y la interfaz y SSD locales SSD. tamaño.

    POST https://compute.googleapis.com/compute/v1/projects/project-2/zones/us-central1-a/instances
    
    {
      "name": "instance-2",
      "machineType": "zones/us-central1-a/machineTypes/n2-standard-32",
      "minCpuPlatform": "Intel Cascade Lake",
      "disks": [
        {
          "boot": true,
          "initializeParams": {
            "sourceImage": "projects/debian-clouid/global/images/family/debian-12"
          }
        }
      ],
      "networkInterfaces": [
        {
          "network": "global/networks/default"
        }
      ],
      "reservationAffinity": {
        "consumeReservationType": "SPECIFIC_RESERVATION",
        "key": "compute.googleapis.com/reservation-name",
        "values": [
          "projects/my-owner-project/reservations/reservation-02"
        ]
      }
    }
    

Crea VMs sin consumir reservas

Si creas una reserva consumida automáticamente, cualquier VM en ejecución con propiedades coincidentes en tu proyecto puede consumir la reserva. Para evitar que una o más de tus VMs consuman la reserva, haz lo siguiente:

  • Configura la propiedad de afinidad de la reserva de las VMs para que no consuman ninguna reserva de forma explícita, como se describe en esta sección.

  • Asegúrate de que tus VMs no coincidan con las propiedades de la VM de la reserva.

Para crear VMs que no consuman reservas de forma explícita, selecciona uno de los siguientes métodos:

Crea una VM para que no consuma reservas

Para crear una VM que no consuma reservas de forma explícita, selecciona una de las siguientes opciones:

Console

  1. En la consola de Google Cloud, ve a la página Crea una instancia.

    Ir a Crear una instancia

  2. En el campo Nombre, ingresa un nombre para la VM.

  3. En las listas Región y Zona, selecciona la región y la zona en las que deseas crear la VM.

  4. En la sección Configuración de máquina, especifica el tipo de máquina que se usará para la VM.

  5. Expande la sección Opciones avanzadas y sigue estos pasos:

    1. Expande la sección Administración.

    2. En la sección Reservas, en la lista Política de aplicaciones, selecciona No usar.

  6. Haz clic en Crear.

gcloud

Para crear una VM que no consuma reservas de forma explícita, usa el comando gcloud compute instances create con la marca --reservation-affinity=none.

gcloud compute instances create VM_NAME \
    --machine-type=MACHINE_TYPE \
    --reservation-affinity=none \
    --zone=ZONE

Reemplaza lo siguiente:

  • VM_NAME: el nombre de la VM.

  • MACHINE_TYPE: Es el tipo de máquina que se usará para la VM.

  • ZONE: la zona en la que se creará la VM.

Go

import (
	"context"
	"fmt"
	"io"

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

// createInstanceNotConsumeReservation creates VM, without consuming reservation
func createInstanceNotConsumeReservation(w io.Writer, projectID, zone, instanceName string) error {
	ctx := context.Background()
	machineType := fmt.Sprintf("zones/%s/machineTypes/%s", zone, "n2-standard-32")
	sourceImage := "projects/debian-cloud/global/images/family/debian-12"

	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{
			Disks: []*computepb.AttachedDisk{
				{
					InitializeParams: &computepb.AttachedDiskInitializeParams{
						DiskSizeGb:  proto.Int64(10),
						SourceImage: proto.String(sourceImage),
					},
					AutoDelete: proto.Bool(true),
					Boot:       proto.Bool(true),
					Type:       proto.String(computepb.AttachedDisk_PERSISTENT.String()),
				},
			},
			MachineType:    proto.String(machineType),
			MinCpuPlatform: proto.String("Intel Cascade Lake"),
			Name:           proto.String(instanceName),
			NetworkInterfaces: []*computepb.NetworkInterface{
				{
					Name: proto.String("global/networks/default"),
				},
			},
			ReservationAffinity: &computepb.ReservationAffinity{
				ConsumeReservationType: proto.String("NO_RESERVATION"),
			},
		},
	}

	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 static com.google.cloud.compute.v1.ReservationAffinity.ConsumeReservationType.NO_RESERVATION;

import com.google.api.gax.longrunning.OperationFuture;
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.InstancesClient;
import com.google.cloud.compute.v1.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.ReservationAffinity;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateInstanceWithoutConsumingReservation {
  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the zone you want to use.
    String zone = "us-central1-a";
    // Name of the VM instance you want to query.
    String instanceName = "YOUR_INSTANCE_NAME";
    // machineType: machine type of the VM being created.
    // *   This value uses the format zones/{zone}/machineTypes/{type_name}.
    // *   For a list of machine types, see https://cloud.google.com/compute/docs/machine-types
    String machineTypeName = "n1-standard-1";
    // sourceImage: path to the operating system image to mount.
    // *   For details about images you can mount, see https://cloud.google.com/compute/docs/images
    String sourceImage = "projects/debian-cloud/global/images/family/debian-11";
    // diskSizeGb: storage size of the boot disk to attach to the instance.
    long diskSizeGb = 10L;
    // networkName: network interface to associate with the instance.
    String networkName = "default";

    createInstanceWithoutConsumingReservationAsync(projectId, zone, instanceName,
        machineTypeName, sourceImage, diskSizeGb, networkName);
  }

  // Create a virtual machine that explicitly doesn't consume reservations
  public static Instance createInstanceWithoutConsumingReservationAsync(
      String project, String zone, String instanceName,
      String machineTypeName, String sourceImage, long diskSizeGb, String networkName)
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    String machineType = String.format("zones/%s/machineTypes/%s", zone, machineTypeName);

    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (InstancesClient instancesClient = InstancesClient.create()) {
      AttachedDisk disk =
          AttachedDisk.newBuilder()
              .setBoot(true)
              .setAutoDelete(true)
              .setType(AttachedDisk.Type.PERSISTENT.toString())
              .setDeviceName("disk-1")
              .setInitializeParams(
                  AttachedDiskInitializeParams.newBuilder()
                      .setSourceImage(sourceImage)
                      .setDiskSizeGb(diskSizeGb)
                      .build())
              .build();

      NetworkInterface networkInterface = NetworkInterface.newBuilder()
          .setName(networkName)
          .build();

      ReservationAffinity reservationAffinity =
          ReservationAffinity.newBuilder()
              .setConsumeReservationType(NO_RESERVATION.toString())
              .build();

      Instance instanceResource =
          Instance.newBuilder()
              .setName(instanceName)
              .setMachineType(machineType)
              .addDisks(disk)
              .addNetworkInterfaces(networkInterface)
              .setReservationAffinity(reservationAffinity)
              .build();

      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstanceResource(instanceResource)
          .build();

      OperationFuture<Operation, Operation> operation = instancesClient.insertAsync(
          insertInstanceRequest);

      // Wait for the operation to complete.
      Operation response = operation.get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        return null;
      }
      return instancesClient.get(project, zone, instanceName);
    }
  }
}

Node.js

// Import the Compute library
const computeLib = require('@google-cloud/compute');
const compute = computeLib.protos.google.cloud.compute.v1;

// Instantiate a reservationsClient
const instancesClient = new computeLib.InstancesClient();
// Instantiate a zoneOperationsClient
const zoneOperationsClient = new computeLib.ZoneOperationsClient();

/**
 * TODO(developer): Update/uncomment these variables before running the sample.
 */
// The ID of the project where you want to create instance.
const projectId = await instancesClient.getProjectId();
// The zone in which to create instance.
const zone = 'us-central1-a';
// The name of the instance to create.
// const instanceName = 'instance-01';
// Machine type to use for VM.
const machineType = 'n1-standard-4';

// Create a VM that explicitly doesn't consume reservations
async function callCreateInstanceToNotConsumeReservation() {
  // Describe the size and source image of the boot disk to attach to the instance.
  const disk = new compute.Disk({
    boot: true,
    autoDelete: true,
    type: 'PERSISTENT',
    initializeParams: {
      diskSizeGb: '10',
      sourceImage: 'projects/debian-cloud/global/images/family/debian-12',
    },
  });

  //  Define networkInterface
  const networkInterface = new compute.NetworkInterface({
    name: 'global/networks/default',
  });

  // Define reservationAffinity
  const reservationAffinity = new compute.ReservationAffinity({
    consumeReservationType: 'NO_RESERVATION',
  });

  // Create an instance
  const instance = new compute.Instance({
    name: instanceName,
    machineType: `zones/${zone}/machineTypes/${machineType}`,
    minCpuPlatform: 'Intel Skylake',
    disks: [disk],
    networkInterfaces: [networkInterface],
    reservationAffinity,
  });

  const [response] = await instancesClient.insert({
    project: projectId,
    instanceResource: instance,
    zone,
  });

  let operation = response.latestResponse;

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

  console.log(`Instance ${instanceName} created.`);
}

await callCreateInstanceToNotConsumeReservation();

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_vm_not_consume_reservation(
    project_id: str, zone: str, instance_name: str, machine_type: str = "n2-standard-2"
) -> compute_v1.Instance:
    """Creates a VM that explicitly doesn't consume reservations
    Args:
        project_id (str): The ID of the Google Cloud project.
        zone (str): The zone where the VM will be created.
        instance_name (str): The name of the instance to create.
        machine_type (str, optional): The machine type for the instance.
    Returns:
        compute_v1.Instance: The created instance.
    """
    instance = compute_v1.Instance()
    instance.name = instance_name
    instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
    instance.zone = zone

    instance.disks = [
        compute_v1.AttachedDisk(
            boot=True,  # Indicates that this is a boot disk
            auto_delete=True,  # The disk will be deleted when the instance is deleted
            initialize_params=compute_v1.AttachedDiskInitializeParams(
                source_image="projects/debian-cloud/global/images/family/debian-11",
                disk_size_gb=10,
            ),
        )
    ]

    instance.network_interfaces = [
        compute_v1.NetworkInterface(
            network="global/networks/default",  # The network to use
            access_configs=[
                compute_v1.AccessConfig(
                    name="External NAT",  # Name of the access configuration
                    type="ONE_TO_ONE_NAT",  # Type of access configuration
                )
            ],
        )
    ]

    # Set the reservation affinity to not consume any reservation
    instance.reservation_affinity = compute_v1.ReservationAffinity(
        consume_reservation_type="NO_RESERVATION",  # Prevents the instance from consuming reservations
    )

    # Create a request to insert the instance
    request = compute_v1.InsertInstanceRequest()
    request.zone = zone
    request.project = project_id
    request.instance_resource = instance

    vm_client = compute_v1.InstancesClient()
    operation = vm_client.insert(request)
    wait_for_extended_operation(operation, "Instance creation")

    print(f"Creating the {instance_name} instance in {zone}...")

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

REST

Para crear una VM que no consuma reservas de forma explícita, realiza una solicitud POST al método instances.insert. En el cuerpo de la solicitud, incluye el campo consumeReservationType configurado como NO_RESERVATION.

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances

{
  "name": "VM_NAME",
  "machineType": "zones/ZONE/machineTypes/MACHINE_TYPE",
  "disks": [
    {
      "boot": true,
      "initializeParams": {
        "sourceImage": "projects/IMAGE_PROJECT/global/images/IMAGE"
      }
    }
  ],
  "networkInterfaces": [
    {
      "network": "global/networks/default"
    }
  ],
  "reservationAffinity": {
    "consumeReservationType": "NO_RESERVATION"
  }
}

Reemplaza lo siguiente:

  • PROJECT_ID: Es el ID del proyecto en el que se creará la VM.

  • ZONE: la zona en la que se creará la VM.

  • VM_NAME: el nombre de la VM.

  • MACHINE_TYPE: Es el tipo de máquina que se usará para la VM.

  • IMAGE_PROJECT: el proyecto de imagen que contiene la imagen del SO; por ejemplo, debian-cloud. Para obtener más información sobre los proyectos de imágenes compatibles, consulta Imágenes públicas.

  • IMAGE: especifica una de las siguientes opciones:

    • una versión específica de la imagen de SO; por ejemplo, debian-12-bookworm-v20240617.

    • Una familia de imágenes, que debe tener el formato family/IMAGE_FAMILY. Esto especifica la imagen de SO no obsoleta más reciente. Por ejemplo, si especificas family/debian-12, se usa la versión más reciente de la familia de imágenes de Debian 12. Para obtener más información sobre el uso de las familias de imágenes, consulta Prácticas recomendadas para las familias de imágenes.

Para obtener más información sobre cómo crear una VM, consulta Crea y, luego, inicia una instancia de Compute Engine.

Crea una plantilla de instancias para que no consuma reservas

Para crear una plantilla de instancias que cree VMs que no consuman reservas de forma explícita, selecciona una de las siguientes opciones:

Console

  1. En la consola de Google Cloud, ve a la página Crea una plantilla de instancias.

    Ir a Crea una plantilla de instancias.

  2. En el campo Nombre, ingresa un nombre para la plantilla de instancias.

  3. En la sección Ubicación, especifica si deseas crear una plantilla de instancias regional (predeterminada) o global.

  4. En la sección Configuración de la máquina, especifica el tipo de máquina que se usará para las VMs creadas con la plantilla.

  5. Expande la sección Opciones avanzadas y sigue estos pasos:

    1. Expande la sección Administración.

    2. En la sección Reservas, en la lista Política de aplicaciones, selecciona No usar.

  6. Haz clic en Crear.

gcloud

Para crear una plantilla de instancias que cree VMs que no consuman reservas de forma explícita, usa el comando gcloud compute instances-templates create con la marca --reservation-affinity=none.

Por ejemplo, para crear una plantilla de instancias global que cree VMs que no consuman reservas de forma explícita, ejecuta el siguiente comando:

gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
    --machine-type=MACHINE_TYPE \
    --reservation-affinity=none

Reemplaza lo siguiente:

  • INSTANCE_TEMPLATE_NAME: el nombre de la plantilla de instancias.

  • MACHINE_TYPE: El tipo de máquina que se usará para las VMs creadas con la plantilla de instancias.

Go

import (
	"context"
	"fmt"
	"io"

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

// createInstanceNotConsumeReservation creates a new instance template, which won't consume reservations
func createTemplateNotConsumeReservation(w io.Writer, projectID, templateName string) error {
	// projectID := "your_project_id"
	// templateName := "your_template_name"

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

	req := &computepb.InsertInstanceTemplateRequest{
		Project: projectID,
		InstanceTemplateResource: &computepb.InstanceTemplate{
			Name: proto.String(templateName),
			Properties: &computepb.InstanceProperties{
				// The template describes the size and source image of the boot disk
				// to attach to the instance.
				Disks: []*computepb.AttachedDisk{
					{
						InitializeParams: &computepb.AttachedDiskInitializeParams{
							DiskSizeGb:  proto.Int64(250),
							SourceImage: proto.String("projects/debian-cloud/global/images/family/debian-11"),
						},
						AutoDelete: proto.Bool(true),
						Boot:       proto.Bool(true),
					},
				},
				MachineType: proto.String("e2-standard-4"),
				// The template connects the instance to the `default` network,
				// without specifying a subnetwork.
				NetworkInterfaces: []*computepb.NetworkInterface{
					{
						Name: proto.String("global/networks/default"),
						// The template lets the instance use an external IP address.
						AccessConfigs: []*computepb.AccessConfig{
							{
								Name:        proto.String("External NAT"),
								Type:        proto.String(computepb.AccessConfig_ONE_TO_ONE_NAT.String()),
								NetworkTier: proto.String(computepb.AccessConfig_PREMIUM.String()),
							},
						},
					},
				},
				ReservationAffinity: &computepb.ReservationAffinity{
					ConsumeReservationType: proto.String("NO_RESERVATION"),
				},
			},
		},
	}

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

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

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

	return nil
}

Java

import static com.google.cloud.compute.v1.ReservationAffinity.ConsumeReservationType.NO_RESERVATION;

import com.google.cloud.compute.v1.AccessConfig;
import com.google.cloud.compute.v1.AttachedDisk;
import com.google.cloud.compute.v1.AttachedDiskInitializeParams;
import com.google.cloud.compute.v1.InsertInstanceTemplateRequest;
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.NetworkInterface;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.ReservationAffinity;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateTemplateWithoutConsumingReservation {
  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample.
    // Project ID or project number of the Cloud project you want to use.
    String projectId = "YOUR_PROJECT_ID";
    // Name of the template you want to query.
    String templateName = "YOUR_INSTANCE_TEMPLATE_NAME";
    String machineType = "e2-standard-4";
    String sourceImage = "projects/debian-cloud/global/images/family/debian-11";

    createTemplateWithoutConsumingReservationAsync(
        projectId, templateName, machineType, sourceImage);
  }


  // Create a template that explicitly doesn't consume any reservations.
  public static InstanceTemplate createTemplateWithoutConsumingReservationAsync(
      String projectId, String templateName, String machineType, String sourceImage)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests.
    try (InstanceTemplatesClient instanceTemplatesClient = InstanceTemplatesClient.create()) {
      AttachedDisk attachedDisk = AttachedDisk.newBuilder()
          .setInitializeParams(AttachedDiskInitializeParams.newBuilder()
              .setSourceImage(sourceImage)
              .setDiskType("pd-balanced")
              .setDiskSizeGb(250)
              .build())
          .setAutoDelete(true)
          .setBoot(true)
          .build();

      NetworkInterface networkInterface = NetworkInterface.newBuilder()
          .setName("global/networks/default")
          .addAccessConfigs(AccessConfig.newBuilder()
              .setName("External NAT")
              .setType(AccessConfig.Type.ONE_TO_ONE_NAT.toString())
              .setNetworkTier(AccessConfig.NetworkTier.PREMIUM.toString())
              .build())
          .build();

      ReservationAffinity reservationAffinity =
          ReservationAffinity.newBuilder()
              .setConsumeReservationType(NO_RESERVATION.toString())
              .build();

      InstanceProperties instanceProperties = InstanceProperties.newBuilder()
          .addDisks(attachedDisk)
          .setMachineType(machineType)
          .setReservationAffinity(reservationAffinity)
          .addNetworkInterfaces(networkInterface)
          .build();

      InsertInstanceTemplateRequest insertInstanceTemplateRequest = InsertInstanceTemplateRequest
          .newBuilder()
          .setProject(projectId)
          .setInstanceTemplateResource(InstanceTemplate.newBuilder()
              .setName(templateName)
              .setProperties(instanceProperties)
              .build())
          .build();

      Operation response = instanceTemplatesClient.insertAsync(insertInstanceTemplateRequest)
          .get(3, TimeUnit.MINUTES);

      if (response.hasError()) {
        return null;
      }
      return instanceTemplatesClient.get(projectId, templateName);
    }
  }
}

Node.js

// Import the Compute library
const computeLib = require('@google-cloud/compute');
const compute = computeLib.protos.google.cloud.compute.v1;

// Instantiate an instanceTemplatesClient
const instanceTemplatesClient = new computeLib.InstanceTemplatesClient();
// Instantiate a globalOperationsClient
const globalOperationsClient = new computeLib.GlobalOperationsClient();

/**
 * TODO(developer): Update/uncomment these variables before running the sample.
 */
// The ID of the project where you want to create template.
const projectId = await instanceTemplatesClient.getProjectId();
// The name of the template to create.
// const templateName = 'instance-01';

// Create an instance template that creates VMs that don't explicitly consume reservations
async function callCreateTemplateToNotConsumeReservation() {
  // Define the boot disk for the instance template
  const disk = new compute.AttachedDisk({
    initializeParams: new compute.AttachedDiskInitializeParams({
      sourceImage:
        'projects/debian-cloud/global/images/debian-12-bookworm-v20240815',
      diskSizeGb: '100',
      diskType: 'pd-balanced',
    }),
    autoDelete: true,
    boot: true,
    type: 'PERSISTENT',
  });

  // Define the network interface for the instance template
  const network = new compute.NetworkInterface({
    network: `projects/${projectId}/global/networks/default`,
  });

  // Define reservationAffinity
  const reservationAffinity = new compute.ReservationAffinity({
    consumeReservationType: 'NO_RESERVATION',
  });

  // Define instance template
  const instanceTemplate = new compute.InstanceTemplate({
    name: templateName,
    properties: {
      disks: [disk],
      machineType: 'e2-medium',
      // The template connects the instance to the `default` network,
      // without specifying a subnetwork.
      networkInterfaces: [network],
      reservationAffinity,
    },
  });

  const [response] = await instanceTemplatesClient.insert({
    project: projectId,
    instanceTemplateResource: instanceTemplate,
  });

  let operation = response.latestResponse;

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

  console.log(`Template ${templateName} created.`);
}

await callCreateTemplateToNotConsumeReservation();

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_template_not_consume_reservation(
    project_id: str,
    template_name: str,
    machine_type: str = "n1-standard-1",
) -> compute_v1.InstanceTemplate:
    """
    Creates an instance template that creates VMs that don't explicitly consume reservations

    Args:
        project_id: project ID or project number of the Cloud project you use.
        template_name: name of the new template to create.
        machine_type: machine type for the instance.
    Returns:
        InstanceTemplate object that represents the new instance template.
    """

    template = compute_v1.InstanceTemplate()
    template.name = template_name
    template.properties.machine_type = machine_type
    # The template describes the size and source image of the boot disk
    # to attach to the instance.
    template.properties.disks = [
        compute_v1.AttachedDisk(
            boot=True,
            auto_delete=True,  # The disk will be deleted when the instance is deleted
            initialize_params=compute_v1.AttachedDiskInitializeParams(
                source_image="projects/debian-cloud/global/images/family/debian-11",
                disk_size_gb=10,
            ),
        )
    ]
    # The template connects the instance to the `default` network,
    template.properties.network_interfaces = [
        compute_v1.NetworkInterface(
            network="global/networks/default",
            access_configs=[
                compute_v1.AccessConfig(
                    name="External NAT",
                    type="ONE_TO_ONE_NAT",
                )
            ],
        )
    ]
    # The template doesn't explicitly consume reservations
    template.properties.reservation_affinity = compute_v1.ReservationAffinity(
        consume_reservation_type="NO_RESERVATION"
    )

    template_client = compute_v1.InstanceTemplatesClient()
    operation = template_client.insert(
        project=project_id, instance_template_resource=template
    )

    wait_for_extended_operation(operation, "instance template creation")

    return template_client.get(project=project_id, instance_template=template_name)

REST

Para crear una plantilla de instancias que cree VMs que no consuman reservas de forma explícita, realiza una solicitud POST a uno de los siguientes métodos:

En el cuerpo de la solicitud, incluye el campo consumeReservationType y configúralo como NO_RESERVATION.

Por ejemplo, para crear una plantilla de instancias global que cree VMs que no consuman reservas de forma explícita, realiza una solicitud de la siguiente manera:

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/InstanceTemplates

{
  "name": "INSTANCE_TEMPLATE_NAME",
  "properties": {
    "machineType": "MACHINE_TYPE",
    "disks": [
      {
        "boot": true,
        "initializeParams": {
          "sourceImage": "projects/IMAGE_PROJECT/global/images/IMAGE"
        }
      }
    ],
    "networkInterfaces": [
      {
        "network": "global/networks/default"
      }
    ],
    "reservationAffinity": {
      "consumeReservationType": "NO_RESERVATION"
    }
  }
}

Reemplaza lo siguiente:

  • PROJECT_ID: el ID del proyecto en el que se creará la plantilla de instancias.

  • INSTANCE_TEMPLATE_NAME: el nombre de la plantilla de instancias.

  • MACHINE_TYPE: El tipo de máquina que se usará para las VMs creadas con la plantilla de instancias.

  • IMAGE_PROJECT: el proyecto de imagen que contiene la imagen del SO; por ejemplo, debian-cloud. Para obtener más información sobre los proyectos de imágenes compatibles, consulta Imágenes públicas.

  • IMAGE: especifica una de las siguientes opciones:

    • una versión específica de la imagen de SO; por ejemplo, debian-12-bookworm-v20240617.

    • Una familia de imágenes, que debe tener el formato family/IMAGE_FAMILY. Esto especifica la imagen de SO no obsoleta más reciente. Por ejemplo, si especificas family/debian-12, se usa la versión más reciente de la familia de imágenes de Debian 12. Para obtener más información sobre el uso de las familias de imágenes, consulta Prácticas recomendadas para las familias de imágenes.

Para obtener más información sobre cómo crear plantillas de instancias, consulta Crea plantillas de instancias.

Prueba que las propiedades de la VM coincidan con una reserva

Para probar si las VMs pueden consumir automáticamente una reserva, puedes crear una copia de la reserva como una reserva específica y, luego, ver si una VM que planeas crear puede consumir esa reserva. Si puedes crear la VM de forma correcta, verificaste que la VM pueda consumir de forma correcta la reserva coincidente. De lo contrario, la creación de la VM falla porque las propiedades no coinciden o no hay recursos reservados disponibles. Después de realizar las pruebas, puedes realizar una o más de las siguientes acciones:

Verifica el consumo de reservas

Para asegurarte de que tus VMs consuman tus reservas de manera eficaz, puedes verificar su consumo con los siguientes métodos:

  • Consulta los detalles de la reserva

    Si la cantidad de VMs que consumen una reserva aumenta en 1 después de crear o actualizar una VM, es probable que tu acción haya hecho que la VM comience a consumir la reserva. Esta es la forma más rápida de comprobar si se está consumiendo una reserva. Sin embargo, es posible que no funcione bien para verificar qué VM exacta consume la reserva.

  • Crea la VM para que se oriente a una reserva específica

    Si puedes crear correctamente una VM que se oriente a una reserva específica, entonces la VM consume la reserva. Este es el método más confiable para verificar que una VM específica consume una reserva y que las propiedades de la VM coinciden con las de la reserva.

  • Supervisa el consumo de reservas

    Con Cloud Monitoring, puedes acceder y ver la información asociada con el consumo de las reservas que se crearon en tu proyecto. La supervisión actualiza los datos de consumo de reservas al menos una vez cada 30 minutos. Este método es útil para verificar la tendencia de consumo de una o más reservas en un proyecto, así como para recibir notificaciones de reservas con poco o sin uso.

  • Consulta el uso histórico de tus reservas

    Con el Planificador de capacidad (versión preliminar), puedes acceder a los datos históricos de uso de tus reservas y consultarlos desde su creación hasta su eliminación. El Planificador de capacidad actualiza los datos de consumo de reservas cada 24 horas. Este método es útil para verificar el consumo anterior de tus reservas en un proyecto, una carpeta o una organización, así como ayudarte a planificar las necesidades de capacidad futuras.

Si ves que una VM no consume una reserva después de verificar que la afinidad de reserva de la VM puede consumirla, la reserva no se consume por completo y las propiedades de la VM y la reserva coinciden, consulta Disponibilidad de recursos.

Visualiza los informes de uso de reserva

Para exportar informes detallados del uso de Compute Engine a un bucket de Cloud Storage, usa la característica de exportación de uso. Para obtener instrucciones, consulta Visualiza informes de uso.

El informe de uso muestra lo siguiente:

  • Recursos reservados que están en uso. Estas entradas se muestran como recursos normales de CPU virtuales, memoria, GPU y SSD locales.
  • Recursos reservados que no están en uso. Estas entradas tienen nombres de SKU y URI de recursos de reserva normales.
  • El total de recursos reservados. Estas entradas tienen nombres de SKU de reserva y URI de recursos de reserva. No existen costos asociados con estas entradas. Usa estas entradas para calcular cuántas de tus reservas están en uso.
Medida Formato MeasurementId Formato Resource URI
Recursos reservados que están en uso com.google.cloud/services/compute-engine/SKU_NAME https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/RESOURCE_TYPE/RESOURCE_NAME.

Por ejemplo, https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central1-a/instances/my-instance
Recursos reservados que no están en uso com.google.cloud/services/compute-engine/SKU_NAME https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations/RESERVATION_NAME

Por ejemplo, https://compute.googleapis.com/compute/v1/projects/my-project/zones/europe-west1-b/reservations/my-reservation
Total de recursos reservados com.google.cloud/services/compute-engine/ReservationSKU_NAME https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/reservations/RESERVATION_NAME

Por ejemplo, https://compute.googleapis.com/compute/v1/projects/my-project/zones/europe-west1-b/reservations/my-reservation

Por ejemplo, en el siguiente fragmento de un informe de uso para una reserva denominada my-reservation, se muestra lo siguiente:

  • En la fila 1, se muestra la memoria RAM reservada que está en uso. El ResourceId de la fila muestra que una VM llamada my-instance usa esta RAM.
  • En la fila 2, se muestra la memoria RAM reservada que no está en uso. El ResourceId de la fila muestra que my-reservation mantiene esta RAM reservada, que aún no la usa ninguna instancia.
  • En la fila 3, se muestra el total de RAM reservada de la reserva.
Report Date,MeasurementId,Quantity,Unit,Resource URI,ResourceId,Location
2019-06-06,com.google.cloud/services/compute-engine/VmimageN2StandardRam,166970074857472,byte-seconds,https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central2-a/instances/my-instance,1775485842510981624,us-central2-a
2019-06-06,com.google.cloud/services/compute-engine/VmimageN2StandardRam,166970074857472,byte-seconds,https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central2-a/reservations/my-reservation,7.58809E+17,us-central2-a
2019-06-06,com.google.cloud/services/compute-engine/ReservationN2StandardRam,333940149714944,byte-seconds,https://compute.googleapis.com/compute/v1/projects/my-project/zones/us-central2-a/reservations/my-reservation,7.58809E+17,us-central2-a
...

Solucionar problemas

Obtén más información sobre cómo solucionar problemas con el consumo de reservas.

¿Qué sigue?