Crea una VM con un tipo personalizado de máquina

Compute Engine ofrece tipos predefinidos de máquinas que puedes usar cuando creas una instancia de VM. Un tipo predefinido de máquina tiene una cantidad predeterminada de CPU virtuales y de memoria, y tiene un precio determinado. Si los tipos predefinidos de VM no satisfacen tus necesidades, puedes crear una instancia de VM con una configuración de hardware virtualizada y personalizada. Específicamente, puedes crear una instancia de VM con una cantidad personalizada de CPU virtuales y memoria mediante el uso efectivo de un tipo personalizado de máquina. Los tipos personalizados de máquinas están disponibles para lo siguiente:

Las VM personalizadas son ideales en las siguientes situaciones:

  • Las cargas de trabajo que no son adecuadas para los tipos predefinidos de máquina
  • Las cargas de trabajo que requieren mayor procesamiento o memoria, pero no necesitan todas las actualizaciones que proporciona el próximo nivel de tipo de máquina.
  • Cargas de trabajo que tienen costos de licencia de software por CPU, en las que puedes personalizar la cantidad de CPU virtuales para evitar los costos de licencia por la capacidad de procesamiento no utilizada o para coincidir con los recuentos de licencias de software disponibles.

Antes de comenzar

  • Lee la documentación sobre las familias de máquinas.
  • Si aún no lo hiciste, configura la autenticación. La autenticación verifica tu identidad para acceder a los servicios y las APIs 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:

    Selecciona la pestaña según cómo planeas usar las muestras de esta página:

    Console

    Cuando usas la consola de Google Cloud para acceder a los servicios y las APIs de Google Cloud , no necesitas configurar la autenticación.

    gcloud

    1. Instala Google Cloud CLI. Después de instalarla, inicializa Google Cloud CLI ejecutando el siguiente comando:

      gcloud init

      Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.

  • Configura una región y una zona predeterminadas.
  • Terraform

    Para usar las muestras de Terraform 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. Instala Google Cloud CLI.

    2. Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.

    3. Si usas una shell local, crea credenciales de autenticación locales para tu cuenta de usuario:

      gcloud auth application-default login

      No es necesario que lo hagas si usas Cloud Shell.

      Si se devuelve un error de autenticación y usas un proveedor de identidad externo (IdP), confirma que accediste a gcloud CLI con tu identidad federada.

    Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

    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. Instala Google Cloud CLI.

    2. Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.

    3. Si usas una shell local, crea credenciales de autenticación locales para tu cuenta de usuario:

      gcloud auth application-default login

      No es necesario que lo hagas si usas Cloud Shell.

      Si se devuelve un error de autenticación y usas un proveedor de identidad externo (IdP), confirma que accediste a gcloud CLI con tu identidad federada.

    Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

    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. Instala Google Cloud CLI.

    2. Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.

    3. Si usas una shell local, crea credenciales de autenticación locales para tu cuenta de usuario:

      gcloud auth application-default login

      No es necesario que lo hagas si usas Cloud Shell.

      Si se devuelve un error de autenticación y usas un proveedor de identidad externo (IdP), confirma que accediste a gcloud CLI con tu identidad federada.

    Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

    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. Instala Google Cloud CLI.

    2. Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.

    3. Si usas una shell local, crea credenciales de autenticación locales para tu cuenta de usuario:

      gcloud auth application-default login

      No es necesario que lo hagas si usas Cloud Shell.

      Si se devuelve un error de autenticación y usas un proveedor de identidad externo (IdP), confirma que accediste a gcloud CLI con tu identidad federada.

    Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

    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. Instala Google Cloud CLI.

    2. Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.

    3. Si usas una shell local, crea credenciales de autenticación locales para tu cuenta de usuario:

      gcloud auth application-default login

      No es necesario que lo hagas si usas Cloud Shell.

      Si se devuelve un error de autenticación y usas un proveedor de identidad externo (IdP), confirma que accediste a gcloud CLI con tu identidad federada.

    Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.

    REST

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

      Instala Google Cloud CLI.

      Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.

    Para obtener más información, consulta Autentícate para usar REST en la documentación de autenticación de Google Cloud .

Roles obligatorios

Para obtener los permisos que necesitas para crear una VM con un tipo personalizado de máquina, pídele a tu 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 crear una VM con un tipo personalizado de máquina. Para ver los permisos exactos que son necesarios, expande la sección Permisos requeridos:

Permisos necesarios

Los siguientes permisos son necesarios para crear una VM con un tipo personalizado de máquina:

  • Para agregar memoria extendida a una VM existente, ingresa compute.instances.setMachineType en la VM.
  • Para crear una VM con un tipo personalizado de máquina, haz lo siguiente:
    • 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

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

Limitaciones

  • Si tu VM tiene discos SSD locales, no puedes cambiar la configuración de CPU virtual y memoria.
  • La memoria extendida está disponible en los tipos de máquinas personalizados N4, N4A, N4D, N2, N2D y N1. Para conocer los límites de la memoria extendida, consulta Agrega memoria extendida a un tipo de máquina.

    Los tipos de máquinas predefinidos, así como los tipos personalizados de máquinas G2 y E2, no admiten la memoria extendida.

  • Los descuentos por compromiso de uso basados en recursos no se aplican a la memoria extendida.

  • Cada tipo de máquina tiene rangos y valores específicos para las CPU virtuales y la memoria, como se muestra en la siguiente tabla:

Series de máquinas Mín. de CPUs virtuales Máx. CPU virt. CPU virtuales permitidas Memoria mínima por CPU virtual (GB) Memoria máxima por CPU virtual (GB) Tamaño del paso (MB) Memoria extendida
N4 2 80 Cualquier múltiplo de 2 2 8 256 Sí
N4D 2 96 2, 4, 8, 16, 32, 48, 64, 80, 96 0.5 8 256 Sí
N4A 1 64 Cualquiera 2 8 256 Sí
N2 2 80 Múltiplos de 2 (hasta 32) o 4 (de 32 a 80) 0.5 8 256 Sí
N2D 2 96 2, 4, 8, 16, 32, 48, 64, 80, 96 0.5 8 256 Sí
N1 1 96 1 o cualquier múltiplo de 2 0.9 (1 para 1 o 2 CPUs virtuales) 6.5 256 Sí
E2 2 32 Cualquier múltiplo de 2 0.5 8 256 No
Núcleo compartido E2 0.25 1 0.25, 0.5, 1 1 en total 8 (2 en total para micro, 4 en total para pequeña, 8 en total para mediana) 256 No

Expresa la memoria en GB o MB

Por motivos históricos, las herramientas y la documentación de Google Cloud se refieren a la memoria del tipo de máquina como megabytes (MB) y gigabytes (GB) decimales. Sin embargo, estas unidades representan gibibytes (GiB) y mebibytes (MiB) binarios, en los que 1 GB equivale a 230 bytes o 1,024 MB.

Cuando configuras la memoria para un tipo personalizado de máquina, los requisitos y las conversiones de unidades dependen de la herramienta que uses:

  • En la consola de Google Cloud , debes especificar la memoria en GB. Por ejemplo, si tu sistema necesita 1,024 MB de memoria, selecciona 1 GB en la consola de Google Cloud .
  • En la API de Compute Engine, debes proporcionar la memoria en MB como un múltiplo entero de 256 MB (o 1,024 MB para las VMs G2). Por ejemplo, si intentas aprovisionar 5 GB de memoria especificando 5,000 MB en una solicitud a la API, la API devuelve un error porque 5,000 no es un múltiplo de 256 (5 GB son 5,120 MB).
  • En Google Cloud CLI, puedes proporcionar la memoria total para una VM en GB o MB:
    • La marca --custom-memory se establece de forma predeterminada en GB si omites la unidad. Para especificar la memoria en MB, debes incluir el sufijo de unidad MB. Por ejemplo, si deseas 2,048 MB (2 GB) de memoria y especificas la marca --custom-memory=2048 sin una unidad, gcloud CLI solicita 2,048 GB de memoria en lugar de 2,048 MB.
    • Los valores sin unidades que se pasan a --custom-memory deben ser números enteros. Para expresar incrementos de 0.25 GB (256 MB), como 5.75 GB, convierte el valor en un número entero en MB (--custom-memory=5888MB) o incluye el sufijo de unidad GB (--custom-memory=5.75GB).
    • Con la marca --machine-type, debes especificar la memoria en MB como un número entero sin un sufijo de unidad, por ejemplo, --machine-type=n2-custom-2-5120.

Precios de los tipos personalizados de máquinas

Compute Engine cobra por las VMs personalizadas en función de la cantidad de CPUs virtuales y las horas de memoria que usa la VM. Este modelo de precios difiere de la forma en que Compute Engine cobra por los tipos predefinidos de máquinas. Los precios a pedido para los tipos personalizados de máquinas incluyen un recargo del 5% sobre los precios a pedido para los tipos predefinidos de máquinas.

  • Cuando usas un tipo personalizado de máquina, toda la memoria hasta la cantidad predeterminada por CPU virtual, incluida esta, se cobra según los precios de los tipos personalizados de máquinas de la familia de máquinas. Tipos personalizados de máquinas E2 y con núcleo compartido E2 comparten el mismo esquema de precios.

  • Si usas tus compromisos para ejecutar tipos personalizados de máquinas, Compute Engine cobra un recargo del 5% sobre los precios de compromiso. Compute Engine cobra este recargo por la parte y la duración de tu compromiso en la que ejecutas estas VMs que son un tipo personalizado de máquina.

Para ver la información de precios por serie de máquinas, consulta Precios de instancias de VM.

Las VM personalizadas están sujetas al mismo cargo mínimo de 1 minuto al que está sujeta cualquier otra instancia, pero los descuentos por uso continuo de los tipos personalizados de máquinas se calculan de manera diferente. Si deseas obtener más información, consulta los descuentos por uso continuo para VM personalizadas.

Precios de la memoria extendida

Compute Engine cobra un importe adicional por la memoria que supera el rango máximo para la cantidad de CPU virtuales configuradas como memoria extendida, según el precio de la memoria personalizada extendida de la familia de máquinas. El precio de la memoria extendida es más alto que el de la memoria por debajo del máximo del rango.

Los precios de la memoria extendida varían según la región. Las instancias que se ejecutan con memoria extendida están sujetas a la misma carga mínima de 1 minuto a la que está sujeta cualquier otra instancia. La memoria extendida no califica para los descuentos por compromiso de uso basados en recursos, pero sí para los descuentos por compromiso de uso flexibles de procesamiento y los descuentos por uso continuo.

Agrega memoria extendida a un tipo de máquina

Cada serie de tipos de máquinas personalizados tiene un máximo de RAM predeterminado por CPU virtual. Para algunas cargas de trabajo, es posible que este máximo predeterminado no sea suficiente memoria por CPU virtual. Por un costo adicional, puedes obtener más memoria por CPU virtual que supere el máximo predeterminado hasta el límite de la serie de máquinas, lo que se denomina memoria extendida. En la siguiente tabla, se enumeran los límites de CPU virtual y memoria extendida para cada serie de máquinas compatible:

Series de máquinas Límite de CPU virtuales Límite de memoria
N4 80 640 GB
N4D 96 768 GB
N4A 64 512 GB
N2 80 864 GB
N2D 96 768 GB
N1 96 624 GB

Para obtener proporciones de RAM a CPU virtual más altas, consulta también los tipos de máquinas con optimización de memoria.

Determina si necesitas memoria extendida

Ciertas cargas de trabajo necesitan más cantidad de memoria que la predeterminada por CPU virtual para ofrecer resultados óptimos. En esta categoría, se incluyen las cargas de trabajo que se basan en bases de datos de análisis de alto rendimiento en memoria, incluidas las bases de datos relacionales y NoSQL, como Microsoft SQL Server, MongoDB y Memcached o Redis. Las licencias basadas en CPU virtuales de los sistemas operativos y las pilas de software también hacen que seleccionar una configuración óptima de la memoria de la VM sea más difícil con los tipos de máquinas predefinidos. Con la memoria extendida, puedes agregar tanta memoria como las VMs necesiten para obtener la mejor relación entre precio y rendimiento.

Crea una VM con un tipo personalizado de máquina

Antes de crear una instancia de VM personalizada, lee las especificaciones personalizadas para crear este tipo de máquina.

Console

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

    Ir a Crear una instancia

  2. En el panel Configuración de la máquina, haz lo siguiente:

    1. Selecciona la Región y la Zona en las que deseas alojar la instancia.
    2. Selecciona la configuración de la máquina para tu instancia:
      • Para crear una VM personalizada de uso general, selecciona Uso general y, luego, en la sección Series, selecciona N4, N4A, N4D, N2, N2D, E2 o N1.
      • Para crear una VM personalizada con GPUs conectadas, selecciona GPUs y, luego, haz lo siguiente:
        1. En la lista Tipo de GPU, selecciona una GPU para la serie de máquinas que deseas usar:
          • Para las VMs G2, selecciona NVIDIA L4.
          • Para las VMs N1, selecciona NVIDIA T4, NVIDIA V100 o NVIDIA Tesla P4.
        2. En la lista Cantidad de GPU, selecciona la cantidad.
    3. En la sección Tipo de máquina, selecciona Personalizado.
    4. Para especificar la cantidad de CPU virtuales y memoria de la instancia, arrastra los controles deslizantes Núcleos y Memoria, o ingresa los valores en los campos. La consola mostrará un costo estimado para la instancia a medida que cambies la cantidad de CPU virtuales y la memoria.
  3. Opcional: Especifica otras opciones de configuración. Para obtener más información, consulta Opciones de configuración durante la creación de instancias.

  4. Para crear y, luego, iniciar la instancia, haz clic en Crear.

gcloud

Crea un tipo personalizado de máquina con el comando gcloud compute instances create y la marca --machine-type:

gcloud compute instances create INSTANCE_NAME \
    --zone=ZONE \
    --machine-type=MACHINE_SERIES-custom-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB

Reemplaza lo siguiente:

  • INSTANCE_NAME: El nombre de la instancia.
  • ZONE: la zona en la que deseas crear la instancia.
  • MACHINE_SERIES: Es la serie de máquinas en minúsculas, como n4, n4d, n4a, n2, n2d, e2 o g2. Para N1, omite MACHINE_SERIES- y comienza con custom-.
  • NUMBER_OF_VCPUS: Es la cantidad de CPU virtuales.
  • AMOUNT_OF_MEMORY_MB: la cantidad total de memoria en MB. Este valor debe ser un múltiplo entero de 256 MB (o 1,024 MB para las VMs G2).

Para crear una VM G2 con 4 CPUs virtuales y 19 GB de memoria en la zona us-central1-a, ejecuta el siguiente comando:

gcloud compute instances create example-instance \
    --zone=us-central1-a \
    --machine-type=g2-custom-4-19456 \
    --maintenance-policy=TERMINATE

Para las VMs G2, la memoria debe ser un múltiplo de 1,024 MB y estar dentro del rango de memoria admitido. Para obtener más información sobre cómo crear VMs G2, consulta Crea una instancia G2 o G4.

En el siguiente ejemplo, se crea un tipo personalizado de máquina N2 con 48 CPU virtuales y 310 GB (317,440 MB) de memoria en la zona us-central1-a:

gcloud compute instances create example-instance \
    --zone=us-central1-a \
    --machine-type=n2-custom-48-317440

Para las series de máquinas compatibles, como N4 o N2, puedes configurar la memoria extendida, que te permite especificar una cantidad de memoria mayor que la proporción máxima predeterminada de memoria a CPU virtuales. Para configurar la memoria extendida, aumenta el valor de AMOUNT_OF_MEMORY_MB y agrega -ext al nombre del tipo de máquina, por ejemplo, --machine-type=n2-custom-48-720896-ext.

Como alternativa, puedes especificar un tipo personalizado de máquina con las marcas --custom-cpu, --custom-memory y --custom-vm-type (y también incluir la marca --custom-extensions si configuras la memoria extendida):

gcloud compute instances create INSTANCE_NAME \
    --zone=ZONE \
    --custom-cpu=NUMBER_OF_VCPUS \
    --custom-memory=AMOUNT_OF_MEMORY \
    --custom-vm-type=MACHINE_SERIES

Reemplaza lo siguiente:

  • INSTANCE_NAME: El nombre de la instancia.
  • ZONE: la zona en la que deseas crear la instancia.
  • NUMBER_OF_VCPUS: Es la cantidad de CPU virtuales.
  • AMOUNT_OF_MEMORY: Es la cantidad total de memoria con un sufijo de unidad (MB o GB), o en GB si omites la unidad.
  • MACHINE_SERIES: Es la serie de máquinas en minúsculas, como n4, n4d, n4a, n2, n2d, e2 o n1.

En el siguiente ejemplo, se crea un tipo personalizado de máquina N2 con 48 CPUs virtuales y 310 GB de memoria con las marcas --custom-cpu, --custom-memory y --custom-vm-type:

gcloud compute instances create example-instance \
    --zone=us-central1-a \
    --custom-cpu=48 \
    --custom-memory=317440MB \
    --custom-vm-type=n2

Cuando uses la marca --custom-memory, especifica la cantidad total de memoria en GB o en MB. Los valores sin unidades deben ser números enteros. Para especificar incrementos de 0.25 GB (256 MB) para la memoria, convierte la memoria total en un número entero en MB (--custom-memory=5888MB) o incluye el sufijo de unidad GB (--custom-memory=5.75GB).

Para los tipos personalizados de máquinas con núcleo compartido E2, usa el comando gcloud compute instances create y, luego, incluye el tamaño de la máquina con núcleo compartido (micro, small o medium):

gcloud compute instances create INSTANCE_NAME \
    --zone=ZONE \
    --machine-type=e2-custom-SHARED_CORE_SIZE-AMOUNT_OF_MEMORY_MB

Reemplaza lo siguiente:

  • INSTANCE_NAME: El nombre de la instancia.
  • ZONE: la zona en la que deseas crear la instancia.
  • SHARED_CORE_SIZE: Es el tamaño del núcleo compartido de E2 (micro, small o medium).
  • AMOUNT_OF_MEMORY_MB: la cantidad total de memoria en MB. Este valor debe ser un múltiplo entero de 256 MB dentro del rango permitido para el tamaño con núcleo compartido.

En el siguiente ejemplo, se crea un tipo personalizado de máquina small con núcleo compartido E2 con 0.5 vCPU y 2.25 GB (2,304 MB) de memoria:

gcloud compute instances create example-instance \
    --zone=us-central1-a \
    --machine-type=e2-custom-small-2304

Terraform

Para generar el código de Terraform, puedes usar el componente Código equivalente en la consola de Google Cloud .
  1. En la consola de Google Cloud , ve a la página Instancias de VM.

    Ir a Instancias de VM

  2. Haz clic en Crear instancia.
  3. Especifica los parámetros que desees.
  4. En la parte superior o inferior de la página, haz clic en Código equivalente y, luego, en la pestaña Terraform para ver el código de Terraform.

Go

Antes de probar esta muestra, sigue las instrucciones de configuración de Go en la Guía de inicio rápido de Compute Engine: Usa las bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Go de Compute Engine.

Para autenticarte en Compute Engine, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import (
	"context"
	"fmt"
	"io"

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

func customMachineTypeURI(zone, cpuSeries string, coreCount, memory int) (string, error) {
	const (
		n1       = "custom"
		n2       = "n2-custom"
		n2d      = "n2d-custom"
		e2       = "e2-custom"
		e2Micro  = "e2-custom-micro"
		e2Small  = "e2-custom-small"
		e2Medium = "e2-custom-medium"
	)

	type typeLimit struct {
		allowedCores     []int
		minMemPerCore    int
		maxMemPerCore    int
		allowExtraMemory bool
		extraMemoryLimit int
	}

	makeRange := func(start, end, step int) []int {
		if step <= 0 || end < start {
			return []int{}
		}
		s := make([]int, 0, 1+(end-start)/step)
		for start <= end {
			s = append(s, start)
			start += step
		}
		return s
	}

	containsString := func(s []string, str string) bool {
		for _, v := range s {
			if v == str {
				return true
			}
		}

		return false
	}

	containsInt := func(nums []int, n int) bool {
		for _, v := range nums {
			if v == n {
				return true
			}
		}

		return false
	}

	var (
		cpuSeriesE2Limit = typeLimit{
			allowedCores:  makeRange(2, 33, 2),
			minMemPerCore: 512,
			maxMemPerCore: 8192,
		}
		cpuSeriesE2MicroLimit  = typeLimit{minMemPerCore: 1024, maxMemPerCore: 2048}
		cpuSeriesE2SmallLimit  = typeLimit{minMemPerCore: 2048, maxMemPerCore: 4096}
		cpuSeriesE2MeidumLimit = typeLimit{minMemPerCore: 4096, maxMemPerCore: 8192}
		cpuSeriesN2Limit       = typeLimit{
			allowedCores:  append(makeRange(2, 33, 2), makeRange(36, 129, 4)...),
			minMemPerCore: 512, maxMemPerCore: 8192,
			allowExtraMemory: true,
			extraMemoryLimit: 624 << 10,
		}
		cpuSeriesN2DLimit = typeLimit{
			allowedCores:  []int{2, 4, 8, 16, 32, 48, 64, 80, 96},
			minMemPerCore: 512, maxMemPerCore: 8192,
			allowExtraMemory: true,
			extraMemoryLimit: 768 << 10,
		}
		cpuSeriesN1Limit = typeLimit{
			allowedCores:     append([]int{1}, makeRange(2, 97, 2)...),
			minMemPerCore:    922,
			maxMemPerCore:    6656,
			allowExtraMemory: true,
			extraMemoryLimit: 624 << 10,
		}
	)

	typeLimitsMap := map[string]typeLimit{
		n1:       cpuSeriesN1Limit,
		n2:       cpuSeriesN2Limit,
		n2d:      cpuSeriesN2DLimit,
		e2:       cpuSeriesE2Limit,
		e2Micro:  cpuSeriesE2MicroLimit,
		e2Small:  cpuSeriesE2SmallLimit,
		e2Medium: cpuSeriesE2MeidumLimit,
	}

	if !containsString([]string{e2, n1, n2, n2d}, cpuSeries) {
		return "", fmt.Errorf("incorrect cpu type: %v", cpuSeries)
	}

	tl := typeLimitsMap[cpuSeries]

	// Check whether the requested parameters are allowed.
	// Find more information about limitations of custom machine types at:
	// https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types

	// Check the number of cores
	if len(tl.allowedCores) > 0 && !containsInt(tl.allowedCores, coreCount) {
		return "", fmt.Errorf(
			"invalid number of cores requested. Allowed number of cores for %v is: %v",
			cpuSeries,
			tl.allowedCores,
		)
	}

	// Memory must be a multiple of 256 MB
	if memory%256 != 0 {
		return "", fmt.Errorf("requested memory must be a multiple of 256 MB")
	}

	// Check if the requested memory isn't too little
	if memory < coreCount*tl.minMemPerCore {
		return "", fmt.Errorf(
			"requested memory is too low. Minimal memory for %v is %v MB per core",
			cpuSeries,
			tl.minMemPerCore,
		)
	}

	// Check if the requested memory isn't too much
	if memory > coreCount*tl.maxMemPerCore && !tl.allowExtraMemory {
		return "", fmt.Errorf(
			"requested memory is too large.. Maximum memory allowed for %v is %v MB per core",
			cpuSeries,
			tl.maxMemPerCore,
		)
	}
	if memory > tl.extraMemoryLimit && tl.allowExtraMemory {
		return "", fmt.Errorf(
			"requested memory is too large.. Maximum memory allowed for %v is %v MB",
			cpuSeries,
			tl.extraMemoryLimit,
		)
	}

	// Return the custom machine type in form of a string acceptable by Compute Engine API.
	if containsString([]string{e2Small, e2Micro, e2Medium}, cpuSeries) {
		return fmt.Sprintf("zones/%v/machineTypes/%v-%v", zone, cpuSeries, memory), nil
	}

	if memory > coreCount*tl.maxMemPerCore {
		return fmt.Sprintf(
			"zones/%v/machineTypes/%v-%v-%v-ext",
			zone,
			cpuSeries,
			coreCount,
			memory,
		), nil
	}

	return fmt.Sprintf("zones/%v/machineTypes/%v-%v-%v", zone, cpuSeries, coreCount, memory), nil
}

// createInstanceWithCustomMachineTypeWithHelper creates a new VM instance with a custom machine type.
func createInstanceWithCustomMachineTypeWithHelper(
	w io.Writer,
	projectID, zone, instanceName, cpuSeries string,
	coreCount, memory int,
) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"
	// cpuSeries := "e2-custom-micro" // the type of CPU you want to use"
	// coreCount := 2 // number of CPU cores you want to use.
	// memory := 256 // the amount of memory for the VM instance, in megabytes.

	machineType, err := customMachineTypeURI(zone, cpuSeries, coreCount, memory)
	if err != nil {
		return fmt.Errorf("unable to create custom machine type string: %w", err)
	}

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

	req := &computepb.InsertInstanceRequest{
		Project: projectID,
		Zone:    zone,
		InstanceResource: &computepb.Instance{
			Name: proto.String(instanceName),
			Disks: []*computepb.AttachedDisk{
				{
					InitializeParams: &computepb.AttachedDiskInitializeParams{
						DiskSizeGb: proto.Int64(10),
						SourceImage: proto.String(
							"projects/debian-cloud/global/images/family/debian-12",
						),
					},
					AutoDelete: proto.Bool(true),
					Boot:       proto.Bool(true),
				},
			},
			MachineType: proto.String(machineType),
			NetworkInterfaces: []*computepb.NetworkInterface{
				{
					Name: proto.String("global/networks/default"),
				},
			},
		},
	}

	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

Antes de probar esta muestra, sigue las instrucciones de configuración de Java en la Guía de inicio rápido de Compute Engine: Usa las bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Java de Compute Engine.

Para autenticarte en Compute Engine, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.


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.common.collect.ImmutableMap;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.IntStream;

public class CreateWithHelper {

  // This class defines the configurable parameters for a custom VM.
  static final class TypeLimits {

    int[] allowedCores;
    int minMemPerCore;
    int maxMemPerCore;
    int extraMemoryLimit;
    boolean allowExtraMemory;

    TypeLimits(int[] allowedCores, int minMemPerCore, int maxMemPerCore, boolean allowExtraMemory,
        int extraMemoryLimit) {
      this.allowedCores = allowedCores;
      this.minMemPerCore = minMemPerCore;
      this.maxMemPerCore = maxMemPerCore;
      this.allowExtraMemory = allowExtraMemory;
      this.extraMemoryLimit = extraMemoryLimit;
    }
  }

  public enum CpuSeries {
    N1("custom"),
    N2("n2-custom"),
    N2D("n2d-custom"),
    E2("e2-custom"),
    E2_MICRO("e2-custom-micro"),
    E2_SMALL("e2-custom-small"),
    E2_MEDIUM("e2-custom-medium");

    private static final Map<String, CpuSeries> ENUM_MAP;

    static {
      ENUM_MAP = init();
    }

    // Build an immutable map of String name to enum pairs.
    public static Map<String, CpuSeries> init() {
      Map<String, CpuSeries> map = new ConcurrentHashMap<>();
      for (CpuSeries instance : CpuSeries.values()) {
        map.put(instance.getCpuSeries(), instance);
      }
      return Collections.unmodifiableMap(map);
    }

    private final String cpuSeries;

    CpuSeries(String cpuSeries) {
      this.cpuSeries = cpuSeries;
    }

    public static CpuSeries get(String name) {
      return ENUM_MAP.get(name);
    }

    public String getCpuSeries() {
      return this.cpuSeries;
    }
  }

  // This enum correlates a machine type with its limits.
  // The limits for various CPU types are described in:
  // https://cloud.google.com/compute/docs/general-purpose-machines
  enum Limits {
    CPUSeries_E2(new TypeLimits(getNumsInRangeWithStep(2, 33, 2), 512, 8192, false, 0)),
    CPUSeries_E2MICRO(new TypeLimits(new int[]{}, 1024, 2048, false, 0)),
    CPUSeries_E2SMALL(new TypeLimits(new int[]{}, 2048, 4096, false, 0)),
    CPUSeries_E2MEDIUM(new TypeLimits(new int[]{}, 4096, 8192, false, 0)),
    CPUSeries_N2(
        new TypeLimits(concat(getNumsInRangeWithStep(2, 33, 2), getNumsInRangeWithStep(36, 129, 4)),
            512, 8192, true, gbToMb(624))),
    CPUSeries_N2D(
        new TypeLimits(new int[]{2, 4, 8, 16, 32, 48, 64, 80, 96}, 512, 8192, true, gbToMb(768))),
    CPUSeries_N1(
        new TypeLimits(concat(new int[]{1}, getNumsInRangeWithStep(2, 97, 2)), 922, 6656, true,
            gbToMb(624)));

    private final TypeLimits typeLimits;

    Limits(TypeLimits typeLimits) {
      this.typeLimits = typeLimits;
    }

    public TypeLimits getTypeLimits() {
      return typeLimits;
    }
  }

  static ImmutableMap<String, Limits> typeLimitsMap = ImmutableMap.<String, Limits>builder()
      .put("N1", Limits.CPUSeries_N1)
      .put("N2", Limits.CPUSeries_N2)
      .put("N2D", Limits.CPUSeries_N2D)
      .put("E2", Limits.CPUSeries_E2)
      .put("E2_MICRO", Limits.CPUSeries_E2MICRO)
      .put("E2_SMALL", Limits.CPUSeries_E2SMALL)
      .put("E2_MEDIUM", Limits.CPUSeries_E2SMALL)
      .build();

  // Returns the array of integers within the given range, incremented by the specified step.
  // start (inclusive): starting number of the range
  // stop (inclusive): ending number of the range
  // step : increment value
  static int[] getNumsInRangeWithStep(int start, int stop, int step) {
    return IntStream.range(start, stop).filter(x -> (x - start) % step == 0).toArray();
  }

  static int gbToMb(int value) {
    return value << 10;
  }

  static int[] concat(int[] a, int[] b) {
    int[] result = new int[a.length + b.length];
    System.arraycopy(a, 0, result, 0, a.length);
    System.arraycopy(b, 0, result, a.length, b.length);
    return result;
  }

  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-google-cloud-project-id";
    // Name of the zone to create the instance in. For example: "us-west3-b".
    String zone = "google-cloud-zone";
    // Name of the new virtual machine (VM) instance.
    String instanceName = "instance-name";
    String cpuSeries = "N1";
    // Number of CPU cores you want to use.
    int coreCount = 2;
    // The amount of memory for the VM instance, in megabytes.
    int memory = 256;

    createInstanceWithCustomMachineTypeWithHelper(
        projectId, zone, instanceName, cpuSeries, coreCount, memory);
  }

  // Create a VM instance with a custom machine type.
  public static void createInstanceWithCustomMachineTypeWithHelper(
      String project, String zone, String instanceName, String cpuSeries, int coreCount, int memory)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // Construct the URI string identifying the machine type.
    String machineTypeUri = customMachineTypeUri(zone, cpuSeries, coreCount, memory);

    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the `instancesClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (InstancesClient instancesClient = InstancesClient.create()) {

      AttachedDisk attachedDisk = AttachedDisk.newBuilder()
          .setInitializeParams(
              // Describe the size and source image of the boot disk to attach to the instance.
              // The list of public images available in Compute Engine can be found here:
              // https://cloud.google.com/compute/docs/images#list_of_public_images_available_on
              AttachedDiskInitializeParams.newBuilder()
                  .setSourceImage(
                      String.format("projects/%s/global/images/family/%s", "debian-cloud",
                          "debian-13"))
                  .setDiskSizeGb(10)
                  .build()
          )
          // Remember to set auto_delete to True if you want the disk to be deleted when you delete
          // your VM instance.
          .setAutoDelete(true)
          .setBoot(true)
          .build();

      // Create the Instance object with the relevant information.
      Instance instance = Instance.newBuilder()
          .setName(instanceName)
          .addDisks(attachedDisk)
          .setMachineType(machineTypeUri)
          .addNetworkInterfaces(
              NetworkInterface.newBuilder().setName("global/networks/default").build())
          .build();

      // Create the insert instance request object.
      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstanceResource(instance)
          .build();

      // Invoke the API with the request object and wait for the operation to complete.
      Operation response = instancesClient.insertAsync(insertInstanceRequest)
          .get(3, TimeUnit.MINUTES);

      // Check for errors.
      if (response.hasError()) {
        throw new Error("Instance creation failed!!" + response);
      }
      System.out.printf("Instance created : %s", instanceName);
      System.out.println("Operation Status: " + response.getStatus());
    }
  }

  public static String customMachineTypeUri(String zone, String cpuSeries, int coreCount,
      int memory) {

    if (!Arrays.asList(CpuSeries.E2.cpuSeries, CpuSeries.N1.cpuSeries, CpuSeries.N2.cpuSeries,
        CpuSeries.N2D.cpuSeries).contains(cpuSeries)) {
      throw new Error(String.format("Incorrect cpu type: %s", cpuSeries));
    }

    TypeLimits typeLimit = Objects.requireNonNull(
        typeLimitsMap.get(CpuSeries.get(cpuSeries).name())).typeLimits;

    // Perform the following checks to verify if the requested parameters are allowed.
    // Find more information about limitations of custom machine types at:
    // https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types

    // 1. Check the number of cores and if the coreCount is present in allowedCores.
    if (typeLimit.allowedCores.length > 0 && Arrays.stream(typeLimit.allowedCores)
        .noneMatch(x -> x == coreCount)) {
      throw new Error(String.format(
          "Invalid number of cores requested. "
              + "Number of cores requested for CPU %s should be one of: %s",
          cpuSeries,
          Arrays.toString(typeLimit.allowedCores)));
    }

    // 2. Memory must be a multiple of 256 MB
    if (memory % 256 != 0) {
      throw new Error("Requested memory must be a multiple of 256 MB");
    }

    // 3. Check if the requested memory isn't too little
    if (memory < coreCount * typeLimit.minMemPerCore) {
      throw new Error(
          String.format("Requested memory is too low. Minimum memory for %s is %s MB per core",
              cpuSeries, typeLimit.minMemPerCore));
    }

    // 4. Check if the requested memory isn't too much
    if (memory > coreCount * typeLimit.maxMemPerCore && !typeLimit.allowExtraMemory) {
      throw new Error(String.format(
          "Requested memory is too large.. Maximum memory allowed for %s is %s MB per core",
          cpuSeries, typeLimit.extraMemoryLimit));
    }

    // 5. Check if the requested memory isn't too large
    if (memory > typeLimit.extraMemoryLimit && typeLimit.allowExtraMemory) {
      throw new Error(
          String.format("Requested memory is too large.. Maximum memory allowed for %s is %s MB",
              cpuSeries, typeLimit.extraMemoryLimit));
    }

    // Check if the CPU Series is E2 and return the custom machine type in the form of a string
    // acceptable by Compute Engine API.
    if (Arrays.asList(CpuSeries.E2_SMALL.cpuSeries, CpuSeries.E2_MICRO.cpuSeries,
        CpuSeries.E2_MEDIUM.cpuSeries).contains(cpuSeries)) {
      return String.format("zones/%s/machineTypes/%s-%s", zone, cpuSeries, memory);
    }

    // Check if extended memory was requested and return the extended custom machine type
    // in the form of a string acceptable by Compute Engine API.
    if (memory > coreCount * typeLimit.maxMemPerCore) {
      return String.format("zones/%s/machineTypes/%s-%s-%s-ext", zone, cpuSeries, coreCount,
          memory);
    }

    // Return the custom machine type in the form of a standard string
    // acceptable by Compute Engine API.
    return String.format("zones/%s/machineTypes/%s-%s-%s", zone, cpuSeries, coreCount, memory);
  }
}

Node.js

Antes de probar esta muestra, sigue las instrucciones de configuración de Node.js en la Guía de inicio rápido de Compute Engine: Usa las bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Node.js de Compute Engine.

Para autenticarte en Compute Engine, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const zone = 'europe-central2-b';
// const instanceName = 'YOUR_INSTANCE_NAME';
// const cpuSeries = 'N1';
// const coreCount = 2
// const memory = 256

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

function range(from, to, step) {
  return [...Array(Math.floor((to - from) / step) + 1)].map(
    (_, i) => from + i * step
  );
}

class CustomMachineType {
  constructor(zone, cpuSeries, coreCount, memory) {
    this.zone = zone;
    this.cpuSeries = cpuSeries;
    this.coreCount = coreCount;
    this.memory = memory;

    this.N1 = 'custom';
    this.N2 = 'n2-custom';
    this.N2D = 'n2d-custom';
    this.E2 = 'e2-custom';
    this.E2Micro = 'e2-custom-micro';
    this.E2Small = 'e2-custom-small';
    this.E2Medium = 'e2-custom-medium';

    this.CpuSeriesE2Limit = {
      allowedCores: range(2, 33, 2),
      minMemPerCore: 512,
      maxMemPerCore: 8192,
      allowExtraMemory: false,
      extraMemoryLimit: 0,
    };

    this.CpuSeriesE2MicroLimit = {
      allowedCores: [],
      minMemPerCore: 1024,
      maxMemPerCore: 2048,
      allowExtraMemory: false,
      extraMemoryLimit: 0,
    };

    this.CpuSeriesE2SmallLimit = {
      allowedCores: [],
      minMemPerCore: 2048,
      maxMemPerCore: 4096,
      allowExtraMemory: false,
      extraMemoryLimit: 0,
    };

    this.CpuSeriesE2MediumLimit = {
      allowedCores: [],
      minMemPerCore: 4096,
      maxMemPerCore: 8192,
      allowExtraMemory: false,
      extraMemoryLimit: 0,
    };

    this.CpuSeriesN2Limit = {
      allowedCores: [...range(2, 33, 2), ...range(36, 129, 4)],
      minMemPerCore: 512,
      maxMemPerCore: 8192,
      allowExtraMemory: true,
      extraMemoryLimit: 624 << 10,
    };

    this.CpuSeriesN2DLimit = {
      allowedCores: [2, 4, 8, 16, 32, 48, 64, 80, 96],
      minMemPerCore: 512,
      maxMemPerCore: 8192,
      allowExtraMemory: true,
      extraMemoryLimit: 768 << 10,
    };

    this.CpuSeriesN1Limit = {
      allowedCores: [1, range(2, 97, 2)],
      minMemPerCore: 922,
      maxMemPerCore: 6656,
      allowExtraMemory: true,
      extraMemoryLimit: 624 << 10,
    };

    this.TYPE_LIMITS = {
      [this.N1]: this.CpuSeriesN1Limit,
      [this.N2]: this.CpuSeriesN2Limit,
      [this.N2D]: this.CpuSeriesN2DLimit,
      [this.E2]: this.CpuSeriesE2Limit,
      [this.E2Micro]: this.CpuSeriesE2MicroLimit,
      [this.E2Small]: this.CpuSeriesE2SmallLimit,
      [this.E2Medium]: this.CpuSeriesE2MediumLimit,
    };

    if (![this.E2, this.N1, this.N2, this.N2D].includes(cpuSeries)) {
      throw new Error(`Incorrect CPU type: ${this.cpuSeries}`);
    }

    this.typeLimit = this.TYPE_LIMITS[this.cpuSeries];

    // Check whether the requested parameters are allowed.
    // Find more information about limitations of custom machine types at:
    // https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types

    // Check the number of cores
    if (
      this.typeLimit.allowedCores.length > 0 &&
      !this.typeLimit.allowedCores.includes(coreCount)
    ) {
      throw new Error(
        `Invalid number of cores requested. Allowed number of cores for ${this.cpuSeries} is: ${this.typeLimit.allowedCores}`
      );
    }

    // Memory must be a multiple of 256 MB
    if (this.memory % 256 !== 0) {
      throw new Error('Requested memory must be a multiple of 256 MB');
    }

    // Check if the requested memory isn't too little
    if (this.memory < this.coreCount * this.typeLimit.minMemPerCore) {
      throw new Error(
        `Requested memory is too low. Minimal memory for ${this.cpuSeries} is ${this.typeLimit.minMemPerCore} MB per core`
      );
    }

    // Check if the requested memory isn't too much
    if (
      this.memory > this.coreCount * this.typeLimit.maxMemPerCore &&
      !this.typeLimit.allowExtraMemory
    ) {
      throw new Error(
        `Requested memory is too large.. Maximum memory allowed for ${this.cpuSeries} is ${this.typeLimit.maxMemPerCore} MB per core`
      );
    }

    if (
      this.memory > this.typeLimit.extraMemoryLimit &&
      this.typeLimit.allowExtraMemory
    ) {
      throw new Error(
        `Requested memory is too large.. Maximum memory allowed for ${this.cpuSeries} is ${this.typeLimit.extraMemoryLimit} MB`
      );
    }
  }

  // Returns the custom machine type in form of a string acceptable by Compute Engine API.
  getMachineTypeURI() {
    if (
      [this.E2Small, this.E2Micro, this.E2Medium].includes(this.cpuSeries)
    ) {
      return `zones/${this.zone}/machineTypes/${this.cpuSeries}-${this.memory}`;
    }

    if (this.memory > this.coreCount * this.typeLimit.maxMemPerCore) {
      return `zones/${this.zone}/machineTypes/${this.cpuSeries}-${this.coreCount}-${this.memory}-ext`;
    }

    return `zones/${zone}/machineTypes/${this.cpuSeries}-${this.coreCount}-${this.memory}`;
  }
}

async function createInstanceWithCustomMachineTypeWithHelper() {
  const instancesClient = new compute.InstancesClient();

  const machineType = new CustomMachineType(
    zone,
    cpuSeries,
    coreCount,
    memory
  ).getMachineTypeURI();

  const [response] = await instancesClient.insert({
    instanceResource: {
      name: instanceName,
      disks: [
        {
          initializeParams: {
            diskSizeGb: '64',
            sourceImage:
              'projects/debian-cloud/global/images/family/debian-11/',
          },
          autoDelete: true,
          boot: true,
        },
      ],
      machineType,
      networkInterfaces: [
        {
          name: 'global/networks/default',
        },
      ],
    },
    project: projectId,
    zone,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

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

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

createInstanceWithCustomMachineTypeWithHelper();

Python

Antes de probar esta muestra, sigue las instrucciones de configuración de Python en la Guía de inicio rápido de Compute Engine: Usa las bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Python de Compute Engine.

Para autenticarte en Compute Engine, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

from __future__ import annotations

from collections import namedtuple
from enum import Enum
from enum import unique
import re
import sys
from typing import Any
import warnings

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


def gb_to_mb(value: int) -> int:
    return value << 10


class CustomMachineType:
    """
    Allows to create custom machine types to be used with the VM instances.
    """

    @unique
    class CPUSeries(Enum):
        N1 = "custom"
        N2 = "n2-custom"
        N2D = "n2d-custom"
        E2 = "e2-custom"
        E2_MICRO = "e2-custom-micro"
        E2_SMALL = "e2-custom-small"
        E2_MEDIUM = "e2-custom-medium"

    TypeLimits = namedtuple(
        "TypeLimits",
        [
            "allowed_cores",
            "min_mem_per_core",
            "max_mem_per_core",
            "allow_extra_memory",
            "extra_memory_limit",
        ],
    )

    # The limits for various CPU types are described on:
    # https://cloud.google.com/compute/docs/general-purpose-machines
    LIMITS = {
        CPUSeries.E2: TypeLimits(frozenset(range(2, 33, 2)), 512, 8192, False, 0),
        CPUSeries.E2_MICRO: TypeLimits(frozenset(), 1024, 2048, False, 0),
        CPUSeries.E2_SMALL: TypeLimits(frozenset(), 2048, 4096, False, 0),
        CPUSeries.E2_MEDIUM: TypeLimits(frozenset(), 4096, 8192, False, 0),
        CPUSeries.N2: TypeLimits(
            frozenset(range(2, 33, 2)).union(set(range(36, 129, 4))),
            512,
            8192,
            True,
            gb_to_mb(624),
        ),
        CPUSeries.N2D: TypeLimits(
            frozenset({2, 4, 8, 16, 32, 48, 64, 80, 96}), 512, 8192, True, gb_to_mb(768)
        ),
        CPUSeries.N1: TypeLimits(
            frozenset({1}.union(range(2, 97, 2))), 922, 6656, True, gb_to_mb(624)
        ),
    }

    def __init__(
        self, zone: str, cpu_series: CPUSeries, memory_mb: int, core_count: int = 0
    ):
        self.zone = zone
        self.cpu_series = cpu_series
        self.limits = self.LIMITS[self.cpu_series]
        # Shared machine types (e2-small, e2-medium and e2-micro) always have
        # 2 vCPUs: https://cloud.google.com/compute/docs/general-purpose-machines#e2_limitations
        self.core_count = 2 if self.is_shared() else core_count
        self.memory_mb = memory_mb
        self._checked = False
        self._check_parameters()
        self.extra_memory_used = self._check_extra_memory()

    def is_shared(self):
        return self.cpu_series in (
            CustomMachineType.CPUSeries.E2_SMALL,
            CustomMachineType.CPUSeries.E2_MICRO,
            CustomMachineType.CPUSeries.E2_MEDIUM,
        )

    def _check_extra_memory(self) -> bool:
        if self._checked:
            return self.memory_mb > self.core_count * self.limits.max_mem_per_core
        else:
            raise RuntimeError(
                "You need to call _check_parameters() before calling _check_extra_memory()"
            )

    def _check_parameters(self):
        """
        Check whether the requested parameters are allowed. Find more information about limitations of custom machine
        types at: https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types
        """
        # Check the number of cores
        if (
            self.limits.allowed_cores
            and self.core_count not in self.limits.allowed_cores
        ):
            raise RuntimeError(
                f"Invalid number of cores requested. Allowed number of cores for {self.cpu_series.name} is: {sorted(self.limits.allowed_cores)}"
            )

        # Memory must be a multiple of 256 MB
        if self.memory_mb % 256 != 0:
            raise RuntimeError("Requested memory must be a multiple of 256 MB.")

        # Check if the requested memory isn't too little
        if self.memory_mb < self.core_count * self.limits.min_mem_per_core:
            raise RuntimeError(
                f"Requested memory is too low. Minimal memory for {self.cpu_series.name} is {self.limits.min_mem_per_core} MB per core."
            )

        # Check if the requested memory isn't too much
        if self.memory_mb > self.core_count * self.limits.max_mem_per_core:
            if self.limits.allow_extra_memory:
                if self.memory_mb > self.limits.extra_memory_limit:
                    raise RuntimeError(
                        f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.extra_memory_limit} MB."
                    )
            else:
                raise RuntimeError(
                    f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.max_mem_per_core} MB per core."
                )

        self._checked = True

    def __str__(self) -> str:
        """
        Return the custom machine type in form of a string acceptable by Compute Engine API.
        """
        if self.cpu_series in {
            self.CPUSeries.E2_SMALL,
            self.CPUSeries.E2_MICRO,
            self.CPUSeries.E2_MEDIUM,
        }:
            return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.memory_mb}"

        if self.extra_memory_used:
            return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}-ext"

        return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}"

    def short_type_str(self) -> str:
        """
        Return machine type in a format without the zone. For example, n2-custom-0-10240.
        This format is used to create instance templates.
        """
        return str(self).rsplit("/", maxsplit=1)[1]

    @classmethod
    def from_str(cls, machine_type: str):
        """
        Construct a new object from a string. The string needs to be a valid custom machine type like:
         - https://www.googleapis.com/compute/v1/projects/diregapic-mestiv/zones/us-central1-b/machineTypes/e2-custom-4-8192
         - zones/us-central1-b/machineTypes/e2-custom-4-8192
         - e2-custom-4-8192 (in this case, the zone parameter will not be set)
        """
        zone = None
        if machine_type.startswith("http"):
            machine_type = machine_type[machine_type.find("zones/") :]

        if machine_type.startswith("zones/"):
            _, zone, _, machine_type = machine_type.split("/")

        extra_mem = machine_type.endswith("-ext")

        if machine_type.startswith("custom"):
            cpu = cls.CPUSeries.N1
            _, cores, memory = machine_type.rsplit("-", maxsplit=2)
        else:
            if extra_mem:
                cpu_series, _, cores, memory, _ = machine_type.split("-")
            else:
                cpu_series, _, cores, memory = machine_type.split("-")
            if cpu_series == "n2":
                cpu = cls.CPUSeries.N2
            elif cpu_series == "n2d":
                cpu = cls.CPUSeries.N2D
            elif cpu_series == "e2":
                cpu = cls.CPUSeries.E2
                if cores == "micro":
                    cpu = cls.CPUSeries.E2_MICRO
                    cores = 2
                elif cores == "small":
                    cpu = cls.CPUSeries.E2_SMALL
                    cores = 2
                elif cores == "medium":
                    cpu = cls.CPUSeries.E2_MEDIUM
                    cores = 2
            else:
                raise RuntimeError("Unknown CPU series.")

        cores = int(cores)
        memory = int(memory)

        return cls(zone, cpu, memory, cores)


def get_image_from_family(project: str, family: str) -> compute_v1.Image:
    """
    Retrieve the newest image that is part of a given family in a project.

    Args:
        project: project ID or project number of the Cloud project you want to get image from.
        family: name of the image family you want to get image from.

    Returns:
        An Image object.
    """
    image_client = compute_v1.ImagesClient()
    # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
    newest_image = image_client.get_from_family(project=project, family=family)
    return newest_image


def disk_from_image(
    disk_type: str,
    disk_size_gb: int,
    boot: bool,
    source_image: str,
    auto_delete: bool = True,
) -> compute_v1.AttachedDisk:
    """
    Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
    source for the new disk.

    Args:
         disk_type: the type of disk you want to create. This value uses the following format:
            "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
            For example: "zones/us-west3-b/diskTypes/pd-ssd"
        disk_size_gb: size of the new disk in gigabytes
        boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
        source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
            of the publicly available images or an image from one of your projects.
            This value uses the following format: "projects/{project_name}/global/images/{image_name}"
        auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it

    Returns:
        AttachedDisk object configured to be created using the specified image.
    """
    boot_disk = compute_v1.AttachedDisk()
    initialize_params = compute_v1.AttachedDiskInitializeParams()
    initialize_params.source_image = source_image
    initialize_params.disk_size_gb = disk_size_gb
    initialize_params.disk_type = disk_type
    boot_disk.initialize_params = initialize_params
    # Remember to set auto_delete to True if you want the disk to be deleted when you delete
    # your VM instance.
    boot_disk.auto_delete = auto_delete
    boot_disk.boot = boot
    return boot_disk


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(
    project_id: str,
    zone: str,
    instance_name: str,
    disks: list[compute_v1.AttachedDisk],
    machine_type: str = "n1-standard-1",
    network_link: str = "global/networks/default",
    subnetwork_link: str = None,
    internal_ip: str = None,
    external_access: bool = False,
    external_ipv4: str = None,
    accelerators: list[compute_v1.AcceleratorConfig] = None,
    preemptible: bool = False,
    spot: bool = False,
    instance_termination_action: str = "STOP",
    custom_hostname: str = None,
    delete_protection: bool = False,
) -> compute_v1.Instance:
    """
    Send an instance creation request to the Compute Engine API and wait for it to complete.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone to create the instance in. For example: "us-west3-b"
        instance_name: name of the new virtual machine (VM) instance.
        disks: a list of compute_v1.AttachedDisk objects describing the disks
            you want to attach to your new instance.
        machine_type: machine type of the VM being created. This value uses the
            following format: "zones/{zone}/machineTypes/{type_name}".
            For example: "zones/europe-west3-c/machineTypes/f1-micro"
        network_link: name of the network you want the new instance to use.
            For example: "global/networks/default" represents the network
            named "default", which is created automatically for each project.
        subnetwork_link: name of the subnetwork you want the new instance to use.
            This value uses the following format:
            "regions/{region}/subnetworks/{subnetwork_name}"
        internal_ip: internal IP address you want to assign to the new instance.
            By default, a free address from the pool of available internal IP addresses of
            used subnet will be used.
        external_access: boolean flag indicating if the instance should have an external IPv4
            address assigned.
        external_ipv4: external IPv4 address to be assigned to this instance. If you specify
            an external IP address, it must live in the same region as the zone of the instance.
            This setting requires `external_access` to be set to True to work.
        accelerators: a list of AcceleratorConfig objects describing the accelerators that will
            be attached to the new instance.
        preemptible: boolean value indicating if the new instance should be preemptible
            or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
        spot: boolean value indicating if the new instance should be a Spot VM or not.
        instance_termination_action: What action should be taken once a Spot VM is terminated.
            Possible values: "STOP", "DELETE"
        custom_hostname: Custom hostname of the new VM instance.
            Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
        delete_protection: boolean value indicating if the new virtual machine should be
            protected against deletion or not.
    Returns:
        Instance object.
    """
    instance_client = compute_v1.InstancesClient()

    # Use the network interface provided in the network_link argument.
    network_interface = compute_v1.NetworkInterface()
    network_interface.network = network_link
    if subnetwork_link:
        network_interface.subnetwork = subnetwork_link

    if internal_ip:
        network_interface.network_i_p = internal_ip

    if external_access:
        access = compute_v1.AccessConfig()
        access.type_ = compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.name
        access.name = "External NAT"
        access.network_tier = access.NetworkTier.PREMIUM.name
        if external_ipv4:
            access.nat_i_p = external_ipv4
        network_interface.access_configs = [access]

    # Collect information into the Instance object.
    instance = compute_v1.Instance()
    instance.network_interfaces = [network_interface]
    instance.name = instance_name
    instance.disks = disks
    if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
        instance.machine_type = machine_type
    else:
        instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"

    instance.scheduling = compute_v1.Scheduling()
    if accelerators:
        instance.guest_accelerators = accelerators
        instance.scheduling.on_host_maintenance = (
            compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name
        )

    if preemptible:
        # Set the preemptible setting
        warnings.warn(
            "Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning
        )
        instance.scheduling = compute_v1.Scheduling()
        instance.scheduling.preemptible = True

    if spot:
        # Set the Spot VM setting
        instance.scheduling.provisioning_model = (
            compute_v1.Scheduling.ProvisioningModel.SPOT.name
        )
        instance.scheduling.instance_termination_action = instance_termination_action

    if custom_hostname is not None:
        # Set the custom hostname for the instance
        instance.hostname = custom_hostname

    if delete_protection:
        # Set the delete protection bit
        instance.deletion_protection = True

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

    # Wait for the create operation to complete.
    print(f"Creating the {instance_name} instance in {zone}...")

    operation = instance_client.insert(request=request)

    wait_for_extended_operation(operation, "instance creation")

    print(f"Instance {instance_name} created.")
    return instance_client.get(project=project_id, zone=zone, instance=instance_name)


def create_custom_instance(
    project_id: str,
    zone: str,
    instance_name: str,
    cpu_series: CustomMachineType.CPUSeries,
    core_count: int,
    memory: int,
) -> compute_v1.Instance:
    """
    Create a new VM instance with a custom machine type.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone to create the instance in. For example: "us-west3-b"
        instance_name: name of the new virtual machine (VM) instance.
        cpu_series: the type of CPU you want to use. Select one value from the CustomMachineType.CPUSeries enum.
            For example: CustomMachineType.CPUSeries.N2
        core_count: number of CPU cores you want to use.
        memory: the amount of memory for the VM instance, in megabytes.

    Return:
        Instance object.
    """
    assert cpu_series in (
        CustomMachineType.CPUSeries.E2,
        CustomMachineType.CPUSeries.N1,
        CustomMachineType.CPUSeries.N2,
        CustomMachineType.CPUSeries.N2D,
    )
    custom_type = CustomMachineType(zone, cpu_series, memory, core_count)

    newest_debian = get_image_from_family(project="debian-cloud", family="debian-12")
    disk_type = f"zones/{zone}/diskTypes/pd-standard"
    disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]

    return create_instance(project_id, zone, instance_name, disks, str(custom_type))

REST

Para crear una instancia con un tipo personalizado de máquina, llama al método instances.insert y especifica los valores machineType personalizados con la memoria en MB:

  • Para la serie de máquinas N1, omite el prefijo de la serie y comienza con custom-.
  • Para los tipos de máquinas de núcleo compartido E2, reemplaza el recuento de CPU virtuales por micro, small o medium.
  • Para habilitar la memoria extendida, agrega -ext a la cadena del tipo de máquina.

En el siguiente ejemplo, se crea un tipo personalizado de máquina N2 con 16 CPUs virtuales y 105 GB (107,520 MB) de memoria:

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

{
  "name": "example-instance",
  "machineType": "zones/ZONE/machineTypes/n2-custom-16-107520",
  "disks": [
    {
      "boot": true,
      "initializeParams": {
        "diskSizeGb": "10",
        "sourceImage": "projects/debian-cloud/global/images/family/debian-13"
      }
    }
  ],
  "networkInterfaces": [
    {
      "network": "global/networks/default"
    }
  ]
}

Reemplaza lo siguiente:

  • PROJECT_ID: Es el ID del proyecto en el que deseas crear la instancia.
  • ZONE: la zona en la que deseas crear la instancia.

De manera similar, puedes crear VMs Spot y grupos de instancias administrados (MIG) con tipos personalizados de máquinas.

Agrega memoria extendida durante la creación de la instancia

Para crear una instancia de VM con memoria extendida, haz lo siguiente:

Console

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

    Ir a Crear una instancia

  2. En el panel Configuración de la máquina, haz lo siguiente:

    1. Selecciona la región y la zona en las que deseas alojar la VM.
    2. Selecciona la configuración de la máquina para tu instancia:
      • Para crear una VM personalizada de uso general, selecciona Uso general y, luego, en la sección Serie, selecciona N4, N4D, N4A, N2, N2D o N1.
      • Para crear una VM personalizada N1 con GPUs conectadas, selecciona GPUs y, luego, haz lo siguiente:
        1. En la lista Tipo de GPU, selecciona NVIDIA T4, NVIDIA V100 o NVIDIA Tesla P4.
        2. En la lista Cantidad de GPU, selecciona la cantidad.
    3. En la sección Tipo de máquina, selecciona Personalizado.
    4. Para especificar la cantidad de CPU virtuales, arrastra el control deslizante Núcleos o ingresa el valor en el campo.
    5. Para agregar memoria extendida, selecciona Extender memoria. Para especificar la cantidad de memoria del tipo de máquina, arrastra el control deslizante Memoria o ingresa el valor en el campo. La consola mostrará un costo estimado para la VM a medida que edites la cantidad de CPU virtuales y la memoria.
  3. Opcional: Especifica otras opciones de configuración. Para obtener más información, consulta Opciones de configuración durante la creación de instancias.

  4. Para crear y, también, iniciar la VM, haz clic en Crear.

gcloud

Crea un tipo personalizado de máquina con memoria extendida con el comando gcloud compute instances create con la marca --machine-type y el sufijo -ext:

gcloud compute instances create INSTANCE_NAME \
    --zone=ZONE \
    --machine-type=MACHINE_SERIES-custom-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB-ext

Reemplaza lo siguiente:

  • INSTANCE_NAME: El nombre de la instancia.
  • ZONE: la zona en la que deseas crear la instancia.
  • MACHINE_SERIES: Es la serie de máquinas en minúsculas que admite la memoria extendida, como n4, n4d, n4a, n2 o n2d. Para N1, omite MACHINE_SERIES- y comienza con custom-.
  • NUMBER_OF_VCPUS: Es la cantidad de CPU virtuales.
  • AMOUNT_OF_MEMORY_MB: la cantidad total de memoria en MB. Este valor debe ser un múltiplo entero de 256 MB.

En el siguiente ejemplo, se crea un tipo personalizado de máquina N2 con 2 CPUs virtuales y 20 GB (20,480 MB) de memoria extendida en la zona us-central1-a:

gcloud compute instances create example-instance \
    --zone=us-central1-a \
    --machine-type=n2-custom-2-20480-ext

Go

Antes de probar esta muestra, sigue las instrucciones de configuración de Go en la Guía de inicio rápido de Compute Engine: Usa las bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Go de Compute Engine.

Para autenticarte en Compute Engine, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import (
	"context"
	"fmt"
	"io"

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

// createInstanceWithExtraMemWithoutHelper сreates new VM instances with extra memory
// without using a CustomMachineType struct.
func createInstanceWithExtraMemWithoutHelper(
	w io.Writer,
	projectID, zone, instanceName, cpuSeries string,
	coreCount, memory int,
) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"
	// cpuSeries := "N1"
	// coreCount := 2 // number of CPU cores you want to use.
	// memory := 256 // the amount of memory for the VM instance, in megabytes.

	// The coreCount and memory values are not validated anywhere and can be rejected by the API.

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

	mt := fmt.Sprintf("zones/%s/machineTypes/%v-%v-%v-ext", zone, cpuSeries, coreCount, memory)
	inst := &computepb.Instance{
		Name: proto.String(instanceName),
		Disks: []*computepb.AttachedDisk{
			{
				InitializeParams: &computepb.AttachedDiskInitializeParams{
					DiskSizeGb: proto.Int64(10),
					SourceImage: proto.String(
						"projects/debian-cloud/global/images/family/debian-12",
					),
				},
				AutoDelete: proto.Bool(true),
				Boot:       proto.Bool(true),
			},
		},
		MachineType: proto.String(mt),
		NetworkInterfaces: []*computepb.NetworkInterface{
			{
				Name: proto.String("global/networks/default"),
			},
		},
	}

	req := &computepb.InsertInstanceRequest{
		Project:          projectID,
		Zone:             zone,
		InstanceResource: inst,
	}

	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

Antes de probar esta muestra, sigue las instrucciones de configuración de Java en la Guía de inicio rápido de Compute Engine: Usa las bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Java de Compute Engine.

Para autenticarte en Compute Engine, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.


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 java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ExtraMemoryWithoutHelper {

  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-google-cloud-project-id";
    // Name of the zone to create the instance in. For example: "us-west3-b".
    String zone = "google-cloud-zone";
    // Name of the new virtual machine (VM) instance.
    String instanceName = "instance-name";
    String cpuSeries = "N1";
    // Number of CPU cores you want to use.
    int coreCount = 2;
    // The amount of memory for the VM instance, in megabytes.
    int memory = 256;

    createInstanceWithExtraMemoryWithoutHelper(projectId, zone, instanceName, cpuSeries, coreCount,
        memory);
  }

  // Create VM instances with extra memory without using a CustomMachineType class and
  // return the created Instance.
  public static void createInstanceWithExtraMemoryWithoutHelper(
      String project, String zone, String instanceName, String cpuSeries, int coreCount, int memory)
      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. After completing all of your requests, call
    // the `instancesClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (InstancesClient instancesClient = InstancesClient.create()) {

      // The coreCount and memory values are not validated anywhere and can be rejected by the API.
      String machineType = String.format("zones/%s/machineTypes/%s-%s-%s-ext", zone, cpuSeries,
          coreCount, memory);

      AttachedDisk attachedDisk = AttachedDisk.newBuilder()
          .setInitializeParams(
              // Describe the size and source image of the boot disk to attach to the instance.
              // The list of public images available in Compute Engine can be found here:
              // https://cloud.google.com/compute/docs/images#list_of_public_images_available_on
              AttachedDiskInitializeParams.newBuilder()
                  .setSourceImage(
                      String.format("projects/%s/global/images/family/%s", "debian-cloud",
                          "debian-13"))
                  .setDiskSizeGb(10)
                  .build()
          )
          // Remember to set auto_delete to True if you want the disk to be deleted when you delete
          // your VM instance.
          .setAutoDelete(true)
          .setBoot(true)
          .build();

      // Create the Instance object with the relevant information.
      Instance instance = Instance.newBuilder()
          .setName(instanceName)
          .addDisks(attachedDisk)
          .setMachineType(machineType)
          .addNetworkInterfaces(
              NetworkInterface.newBuilder().setName("global/networks/default").build())
          .build();

      // Create the insert instance request object.
      InsertInstanceRequest insertInstanceRequest = InsertInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstanceResource(instance)
          .build();

      // Invoke the API with the request object and wait for the operation to complete.
      Operation response = instancesClient.insertAsync(insertInstanceRequest)
          .get(3, TimeUnit.MINUTES);

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

Node.js

Antes de probar esta muestra, sigue las instrucciones de configuración de Node.js en la Guía de inicio rápido de Compute Engine: Usa las bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Node.js de Compute Engine.

Para autenticarte en Compute Engine, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const zone = 'europe-central2-b';
// const instanceName = 'YOUR_INSTANCE_NAME';
// const cpuSeries = 'N1';
// const coreCount = 2
// const memory = 256

// The coreCount and memory values are not validated anywhere and can be rejected by the API.

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

async function createInstanceWithExtraMemWithoutHelper() {
  const instancesClient = new compute.InstancesClient();

  const machineType = `zones/${zone}/machineTypes/${cpuSeries}-${coreCount}-${memory}-ext`;

  const [response] = await instancesClient.insert({
    instanceResource: {
      name: instanceName,
      disks: [
        {
          initializeParams: {
            diskSizeGb: '64',
            sourceImage:
              'projects/debian-cloud/global/images/family/debian-11/',
          },
          autoDelete: true,
          boot: true,
        },
      ],
      machineType,
      networkInterfaces: [
        {
          name: 'global/networks/default',
        },
      ],
    },
    project: projectId,
    zone,
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

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

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

createInstanceWithExtraMemWithoutHelper();

Python

Antes de probar esta muestra, sigue las instrucciones de configuración de Python en la Guía de inicio rápido de Compute Engine: Usa las bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Python de Compute Engine.

Para autenticarte en Compute Engine, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

from __future__ import annotations

import re
import sys
from typing import Any
import warnings

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


def get_image_from_family(project: str, family: str) -> compute_v1.Image:
    """
    Retrieve the newest image that is part of a given family in a project.

    Args:
        project: project ID or project number of the Cloud project you want to get image from.
        family: name of the image family you want to get image from.

    Returns:
        An Image object.
    """
    image_client = compute_v1.ImagesClient()
    # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
    newest_image = image_client.get_from_family(project=project, family=family)
    return newest_image


def disk_from_image(
    disk_type: str,
    disk_size_gb: int,
    boot: bool,
    source_image: str,
    auto_delete: bool = True,
) -> compute_v1.AttachedDisk:
    """
    Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
    source for the new disk.

    Args:
         disk_type: the type of disk you want to create. This value uses the following format:
            "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
            For example: "zones/us-west3-b/diskTypes/pd-ssd"
        disk_size_gb: size of the new disk in gigabytes
        boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
        source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
            of the publicly available images or an image from one of your projects.
            This value uses the following format: "projects/{project_name}/global/images/{image_name}"
        auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it

    Returns:
        AttachedDisk object configured to be created using the specified image.
    """
    boot_disk = compute_v1.AttachedDisk()
    initialize_params = compute_v1.AttachedDiskInitializeParams()
    initialize_params.source_image = source_image
    initialize_params.disk_size_gb = disk_size_gb
    initialize_params.disk_type = disk_type
    boot_disk.initialize_params = initialize_params
    # Remember to set auto_delete to True if you want the disk to be deleted when you delete
    # your VM instance.
    boot_disk.auto_delete = auto_delete
    boot_disk.boot = boot
    return boot_disk


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(
    project_id: str,
    zone: str,
    instance_name: str,
    disks: list[compute_v1.AttachedDisk],
    machine_type: str = "n1-standard-1",
    network_link: str = "global/networks/default",
    subnetwork_link: str = None,
    internal_ip: str = None,
    external_access: bool = False,
    external_ipv4: str = None,
    accelerators: list[compute_v1.AcceleratorConfig] = None,
    preemptible: bool = False,
    spot: bool = False,
    instance_termination_action: str = "STOP",
    custom_hostname: str = None,
    delete_protection: bool = False,
) -> compute_v1.Instance:
    """
    Send an instance creation request to the Compute Engine API and wait for it to complete.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone to create the instance in. For example: "us-west3-b"
        instance_name: name of the new virtual machine (VM) instance.
        disks: a list of compute_v1.AttachedDisk objects describing the disks
            you want to attach to your new instance.
        machine_type: machine type of the VM being created. This value uses the
            following format: "zones/{zone}/machineTypes/{type_name}".
            For example: "zones/europe-west3-c/machineTypes/f1-micro"
        network_link: name of the network you want the new instance to use.
            For example: "global/networks/default" represents the network
            named "default", which is created automatically for each project.
        subnetwork_link: name of the subnetwork you want the new instance to use.
            This value uses the following format:
            "regions/{region}/subnetworks/{subnetwork_name}"
        internal_ip: internal IP address you want to assign to the new instance.
            By default, a free address from the pool of available internal IP addresses of
            used subnet will be used.
        external_access: boolean flag indicating if the instance should have an external IPv4
            address assigned.
        external_ipv4: external IPv4 address to be assigned to this instance. If you specify
            an external IP address, it must live in the same region as the zone of the instance.
            This setting requires `external_access` to be set to True to work.
        accelerators: a list of AcceleratorConfig objects describing the accelerators that will
            be attached to the new instance.
        preemptible: boolean value indicating if the new instance should be preemptible
            or not. Preemptible VMs have been deprecated and you should now use Spot VMs.
        spot: boolean value indicating if the new instance should be a Spot VM or not.
        instance_termination_action: What action should be taken once a Spot VM is terminated.
            Possible values: "STOP", "DELETE"
        custom_hostname: Custom hostname of the new VM instance.
            Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
        delete_protection: boolean value indicating if the new virtual machine should be
            protected against deletion or not.
    Returns:
        Instance object.
    """
    instance_client = compute_v1.InstancesClient()

    # Use the network interface provided in the network_link argument.
    network_interface = compute_v1.NetworkInterface()
    network_interface.network = network_link
    if subnetwork_link:
        network_interface.subnetwork = subnetwork_link

    if internal_ip:
        network_interface.network_i_p = internal_ip

    if external_access:
        access = compute_v1.AccessConfig()
        access.type_ = compute_v1.AccessConfig.Type.ONE_TO_ONE_NAT.name
        access.name = "External NAT"
        access.network_tier = access.NetworkTier.PREMIUM.name
        if external_ipv4:
            access.nat_i_p = external_ipv4
        network_interface.access_configs = [access]

    # Collect information into the Instance object.
    instance = compute_v1.Instance()
    instance.network_interfaces = [network_interface]
    instance.name = instance_name
    instance.disks = disks
    if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
        instance.machine_type = machine_type
    else:
        instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"

    instance.scheduling = compute_v1.Scheduling()
    if accelerators:
        instance.guest_accelerators = accelerators
        instance.scheduling.on_host_maintenance = (
            compute_v1.Scheduling.OnHostMaintenance.TERMINATE.name
        )

    if preemptible:
        # Set the preemptible setting
        warnings.warn(
            "Preemptible VMs are being replaced by Spot VMs.", DeprecationWarning
        )
        instance.scheduling = compute_v1.Scheduling()
        instance.scheduling.preemptible = True

    if spot:
        # Set the Spot VM setting
        instance.scheduling.provisioning_model = (
            compute_v1.Scheduling.ProvisioningModel.SPOT.name
        )
        instance.scheduling.instance_termination_action = instance_termination_action

    if custom_hostname is not None:
        # Set the custom hostname for the instance
        instance.hostname = custom_hostname

    if delete_protection:
        # Set the delete protection bit
        instance.deletion_protection = True

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

    # Wait for the create operation to complete.
    print(f"Creating the {instance_name} instance in {zone}...")

    operation = instance_client.insert(request=request)

    wait_for_extended_operation(operation, "instance creation")

    print(f"Instance {instance_name} created.")
    return instance_client.get(project=project_id, zone=zone, instance=instance_name)


def create_custom_instances_extra_mem(
    project_id: str, zone: str, instance_name: str, core_count: int, memory: int
) -> list[compute_v1.Instance]:
    """
    Create 3 new VM instances with extra memory without using a CustomMachineType helper class.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone to create the instance in. For example: "us-west3-b"
        instance_name: name of the new virtual machine (VM) instance.
        core_count: number of CPU cores you want to use.
        memory: the amount of memory for the VM instance, in megabytes.

    Returns:
        List of Instance objects.
    """
    newest_debian = get_image_from_family(project="debian-cloud", family="debian-12")
    disk_type = f"zones/{zone}/diskTypes/pd-standard"
    disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
    # The core_count and memory values are not validated anywhere and can be rejected by the API.
    instances = [
        create_instance(
            project_id,
            zone,
            f"{instance_name}_n1_extra_mem",
            disks,
            f"zones/{zone}/machineTypes/custom-{core_count}-{memory}-ext",
        ),
        create_instance(
            project_id,
            zone,
            f"{instance_name}_n2_extra_mem",
            disks,
            f"zones/{zone}/machineTypes/n2-custom-{core_count}-{memory}-ext",
        ),
        create_instance(
            project_id,
            zone,
            f"{instance_name}_n2d_extra_mem",
            disks,
            f"zones/{zone}/machineTypes/n2d-custom-{core_count}-{memory}-ext",
        ),
    ]
    return instances

REST

Para crear una instancia con memoria extendida, llama al método instances.insert y agrega -ext al campo machineType para extender la memoria hasta el límite de esa serie de máquinas:

zones/ZONE/machineTypes/MACHINE_SERIES-custom-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB-ext

Reemplaza lo siguiente:

  • ZONE: la zona en la que deseas crear la instancia.
  • MACHINE_SERIES: Es la serie de máquinas en minúsculas, como n4, n4d, n4a, n2 o n2d. Para N1, omite MACHINE_SERIES- y comienza con custom-.
  • NUMBER_OF_VCPUS: Es la cantidad de CPU virtuales.
  • AMOUNT_OF_MEMORY_MB: la cantidad total de memoria en MB. Este valor debe ser un múltiplo entero de 256 MB.

Por ejemplo, lo siguiente especifica un tipo de máquina N2 con 2 CPUs virtuales y 20 GB (20,480 MB) de memoria extendida:

zones/ZONE/machineTypes/n2-custom-2-20480-ext

Agrega memoria extendida a una instancia de VM existente

Para agregar más memoria a una instancia existente que usa un tipo personalizado de máquina, primero debes detener la instancia. Después de que la instancia se detenga, completa los siguientes pasos para agregar más memoria a la VM:

Console

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

    Ir a Instancias de VM

  2. Haz clic en el nombre de la VM detenida que deseas modificar.

  3. En la parte superior de la página, haz clic en Editar.

  4. En la sección Configuración de la máquina, verifica que esté seleccionado Personalizado en Tipo de máquina.

  5. Para agregar memoria extendida, selecciona Extender memoria y, luego, especifica la cantidad de Memoria que necesitas.

  6. Haz clic en Guardar.

  7. Para reiniciar la VM, en la parte superior de la página, haz clic en Iniciar/Reanudar.

gcloud

  1. Detén la VM con el comando gcloud compute instances stop:

    gcloud compute instances stop INSTANCE_NAME \
        --zone=ZONE
    
  2. Actualiza el tipo personalizado de máquina con memoria extendida ejecutando el comando gcloud compute instances set-machine-type con las marcas --custom-cpu, --custom-memory, --custom-vm-type y --custom-extensions:

    gcloud compute instances set-machine-type INSTANCE_NAME \
        --zone=ZONE \
        --custom-cpu=NUMBER_OF_VCPUS \
        --custom-memory=AMOUNT_OF_MEMORY \
        --custom-vm-type=MACHINE_SERIES \
        --custom-extensions
    

    Como alternativa, puedes pasar la cadena de tipo personalizado de máquina completa con el sufijo -ext a la marca --machine-type:

    gcloud compute instances set-machine-type INSTANCE_NAME \
        --zone=ZONE \
        --machine-type=MACHINE_SERIES-custom-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB-ext
    

    Reemplaza lo siguiente:

    • INSTANCE_NAME: el nombre de la VM.
    • ZONE: la zona donde se ubica la VM.
    • NUMBER_OF_VCPUS: Es la cantidad de CPU virtuales.
    • AMOUNT_OF_MEMORY: Es la cantidad total de memoria con un sufijo de unidad (MB o GB), o en GB si omites la unidad.
    • AMOUNT_OF_MEMORY_MB: Es la cantidad total de memoria en MB. Este valor debe ser un múltiplo entero de 256 MB.
    • MACHINE_SERIES: Es la serie de máquinas en minúsculas que admite memoria extendida, como n4, n4d, n4a, n2, n2d o n1. Para N1 con la marca --machine-type, omite MACHINE_SERIES- y comienza con custom-.
  3. Reinicia la VM con el comando gcloud compute instances start:

    gcloud compute instances start INSTANCE_NAME \
        --zone=ZONE
    

Go

Antes de probar esta muestra, sigue las instrucciones de configuración de Go en la Guía de inicio rápido de Compute Engine: Usa las bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Go de Compute Engine.

Para autenticarte en Compute Engine, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

import (
	"context"
	"fmt"
	"io"
	"strings"

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

// modifyInstanceWithExtendedMemory sends an instance creation request
// to the Compute Engine API and waits for it to complete.
func modifyInstanceWithExtendedMemory(
	w io.Writer,
	projectID, zone, instanceName string,
	newMemory int,
) error {
	// projectID := "your_project_id"
	// zone := "europe-central2-b"
	// instanceName := "your_instance_name"
	// newMemory := 256 // the amount of memory for the VM instance, in megabytes.

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

	reqInstance := &computepb.GetInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
	}

	instance, err := instancesClient.Get(ctx, reqInstance)
	if err != nil {
		return fmt.Errorf("unable to get instance: %w", err)
	}

	containsString := func(s []string, str string) bool {
		for _, v := range s {
			if v == str {
				return true
			}
		}

		return false
	}

	if !(strings.Contains(instance.GetMachineType(), "machineTypes/n1-") ||
		strings.Contains(instance.GetMachineType(), "machineTypes/n2-") ||
		strings.Contains(instance.GetMachineType(), "machineTypes/n2d-")) {
		return fmt.Errorf("extra memory is available only for N1, N2 and N2D CPUs")
	}

	// Make sure that the machine is turned off
	if !containsString([]string{"TERMINATED", "STOPPED"}, instance.GetStatus()) {
		reqStop := &computepb.StopInstanceRequest{
			Project:  projectID,
			Zone:     zone,
			Instance: instanceName,
		}

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

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

	// Modify the machine definition, remember that extended memory
	// is available only for N1, N2 and N2D CPUs
	machineType := instance.GetMachineType()
	start := machineType[:strings.LastIndex(machineType, "-")]

	updateReq := &computepb.SetMachineTypeInstanceRequest{
		Project:  projectID,
		Zone:     zone,
		Instance: instanceName,
		InstancesSetMachineTypeRequestResource: &computepb.InstancesSetMachineTypeRequest{
			MachineType: proto.String(fmt.Sprintf("%s-%v-ext", start, newMemory)),
		},
	}
	op, err := instancesClient.SetMachineType(ctx, updateReq)
	if err != nil {
		return fmt.Errorf("unable to update 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 updated\n")

	return nil

}

Java

Antes de probar esta muestra, sigue las instrucciones de configuración de Java en la Guía de inicio rápido de Compute Engine: Usa las bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Java de Compute Engine.

Para autenticarte en Compute Engine, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.GetInstanceRequest;
import com.google.cloud.compute.v1.Instance;
import com.google.cloud.compute.v1.Instance.Status;
import com.google.cloud.compute.v1.InstancesClient;
import com.google.cloud.compute.v1.InstancesSetMachineTypeRequest;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.SetMachineTypeInstanceRequest;
import com.google.cloud.compute.v1.StopInstanceRequest;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class UpdateMemory {

  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-google-cloud-project-id";
    // Name of the zone to create the instance in. For example: "us-west3-b".
    String zone = "google-cloud-zone";
    // Name of the new virtual machine (VM) instance.
    String instanceName = "instance-name";
    // The amount of memory for the VM instance, in megabytes.
    int newMemory = 256;

    modifyInstanceWithExtendedMemory(projectId, zone, instanceName, newMemory);
  }

  // Modify an existing VM to use extended memory and return the modified Instance.
  public static void modifyInstanceWithExtendedMemory(
      String project, String zone, String instanceName, int newMemory)
      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. After completing all of your requests, call
    // the `instancesClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (InstancesClient instancesClient = InstancesClient.create()) {

      // Create the get instance request object.
      GetInstanceRequest getInstanceRequest = GetInstanceRequest.newBuilder()
          .setProject(project)
          .setZone(zone)
          .setInstance(instanceName)
          .build();

      Instance instance = instancesClient.get(getInstanceRequest);

      // Check the machine type.
      if (!(instance.getMachineType().contains("machineTypes/n1-")
          || instance.getMachineType().contains("machineTypes/n2-")
          || instance.getMachineType().contains("machineTypes/n2d-"))) {
        System.out.println("extra memory is available only for N1, N2 and N2D CPUs");
        return;
      }

      // Make sure that the machine is turned off.
      if (!(instance.getStatus().equals(Status.TERMINATED.toString())
          || instance.getStatus().equals(Status.STOPPED.toString()))) {

        StopInstanceRequest stopInstanceRequest = StopInstanceRequest.newBuilder()
            .setProject(project)
            .setZone(zone)
            .setInstance(instanceName)
            .build();

        OperationFuture<Operation, Operation> operation = instancesClient.stopAsync(
            stopInstanceRequest);
        Operation response = operation.get(3, TimeUnit.MINUTES);
        if (response.hasError()) {
          System.out.printf("Unable to stop instance %s", response.getError());
          return;
        }
      }

      // Modify the machine definition. Note that extended memory
      // is available only for N1, N2 and N2D CPUs.
      String machineType = instance.getMachineType();
      String start = machineType.substring(0, machineType.lastIndexOf("-"));

      // Create the machine type instance request object.
      SetMachineTypeInstanceRequest setMachineTypeInstanceRequest =
          SetMachineTypeInstanceRequest.newBuilder()
              .setProject(project)
              .setZone(zone)
              .setInstance(instanceName)
              .setInstancesSetMachineTypeRequestResource(InstancesSetMachineTypeRequest.newBuilder()
                  .setMachineType(String.format("%s-%d-ext", start, newMemory))
                  .build())
              .build();

      // Invoke the API with the request object and wait for the operation to complete.
      Operation response = instancesClient.setMachineTypeAsync(setMachineTypeInstanceRequest)
          .get(3, TimeUnit.MINUTES);

      // Check for errors.
      if (response.hasError()) {
        System.out.printf("Unable to update instance %s", response.getError());
        return;
      }
      System.out.println("Instance updated!");
    }
  }
}

Node.js

Antes de probar esta muestra, sigue las instrucciones de configuración de Node.js en la Guía de inicio rápido de Compute Engine: Usa las bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Node.js de Compute Engine.

Para autenticarte en Compute Engine, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const zone = 'europe-central2-b';
// const instanceName = 'YOUR_INSTANCE_NAME';
// const newMemory = 256;

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

async function modifyInstanceWithExtendedMemory() {
  const instancesClient = new compute.InstancesClient();

  const [instance] = await instancesClient.get({
    project: projectId,
    zone,
    instance: instanceName,
  });

  if (
    !['machineTypes/n1-', 'machineTypes/n2-', 'machineTypes/n2d-'].some(
      type => instance.machineType.includes(type)
    )
  ) {
    throw new Error('extra memory is available only for N1, N2 and N2D CPUs');
  }

  // Make sure that the machine is turned off
  if (!['TERMINATED', 'STOPPED'].some(status => instance.status === status)) {
    const [response] = await instancesClient.stop({
      project: projectId,
      zone,
      instance: instanceName,
    });

    let operation = response.latestResponse;
    const operationsClient = new compute.ZoneOperationsClient();

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

  // Modify the machine definition, remember that extended memory
  // is available only for N1, N2 and N2D CPUs

  const start = instance.machineType.substring(
    0,
    instance.machineType.lastIndexOf('-')
  );

  const [response] = await instancesClient.setMachineType({
    project: projectId,
    zone,
    instance: instanceName,
    instancesSetMachineTypeRequestResource: {
      machineType: `${start}-${newMemory}-ext`,
    },
  });
  let operation = response.latestResponse;
  const operationsClient = new compute.ZoneOperationsClient();

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

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

modifyInstanceWithExtendedMemory();

Python

Antes de probar esta muestra, sigue las instrucciones de configuración de Python en la Guía de inicio rápido de Compute Engine: Usa las bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Python de Compute Engine.

Para autenticarte en Compute Engine, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas cliente.

from __future__ import annotations

import sys
import time
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 add_extended_memory_to_instance(
    project_id: str, zone: str, instance_name: str, new_memory: int
):
    """
    Modify an existing VM to use extended memory.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        zone: name of the zone to create the instance in. For example: "us-west3-b"
        instance_name: name of the new virtual machine (VM) instance.
        new_memory: the amount of memory for the VM instance, in megabytes.

    Returns:
        Instance object.
    """
    instance_client = compute_v1.InstancesClient()
    instance = instance_client.get(
        project=project_id, zone=zone, instance=instance_name
    )

    if not (
        "n1-" in instance.machine_type
        or "n2-" in instance.machine_type
        or "n2d-" in instance.machine_type
    ):
        raise RuntimeError("Extra memory is available only for N1, N2 and N2D CPUs.")

    # Make sure that the machine is turned off
    if instance.status not in (
        instance.Status.TERMINATED.name,
        instance.Status.STOPPED.name,
    ):
        operation = instance_client.stop(
            project=project_id, zone=zone, instance=instance_name
        )
        wait_for_extended_operation(operation, "instance stopping")
        start = time.time()
        while instance.status not in (
            instance.Status.TERMINATED.name,
            instance.Status.STOPPED.name,
        ):
            # Waiting for the instance to be turned off.
            instance = instance_client.get(
                project=project_id, zone=zone, instance=instance_name
            )
            time.sleep(2)
            if time.time() - start >= 300:  # 5 minutes
                raise TimeoutError()

    # Modify the machine definition, remember that extended memory is available only for N1, N2 and N2D CPUs
    start, end = instance.machine_type.rsplit("-", maxsplit=1)
    instance.machine_type = start + f"-{new_memory}-ext"
    # TODO: If you prefer to use the CustomMachineType helper class, uncomment this code and comment the 2 lines above
    # Using CustomMachineType helper
    # cmt = CustomMachineType.from_str(instance.machine_type)
    # cmt.memory_mb = new_memory
    # cmt.extra_memory_used = True
    # instance.machine_type = str(cmt)
    operation = instance_client.update(
        project=project_id,
        zone=zone,
        instance=instance_name,
        instance_resource=instance,
    )
    wait_for_extended_operation(operation, "instance update")

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

REST

  1. Detén la VM llamando al método instances.stop.
  2. Actualiza los recursos de tipo de máquina llamando al método instances.setMachineType y especificando el sufijo -ext en el campo machineType:

    POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/INSTANCE_NAME/setMachineType
    
    {
      "machineType": "zones/ZONE/machineTypes/MACHINE_SERIES-custom-NUMBER_OF_VCPUS-AMOUNT_OF_MEMORY_MB-ext"
    }
    

    Reemplaza lo siguiente:

    • PROJECT_ID: Es el ID del proyecto que contiene la VM.
    • ZONE: la zona donde se ubica la VM.
    • INSTANCE_NAME: el nombre de la VM.
    • MACHINE_SERIES: Es la serie de máquinas en minúsculas, como n4, n4d, n4a, n2 o n2d. Para N1, omite MACHINE_SERIES- y comienza con custom-.
    • NUMBER_OF_VCPUS: Es la cantidad de CPU virtuales.
    • AMOUNT_OF_MEMORY_MB: Es la cantidad total de memoria en MB. Este valor debe ser un múltiplo entero de 256 MB.
  3. Reinicia la VM llamando al método instances.start.

¿Qué sigue?