Create GCP Compute Reservations

The gcp:compute/reservation:Reservation resource, part of the Pulumi GCP provider, reserves VM capacity in a specific zone, ensuring availability even when instances aren’t running. This guide focuses on three capabilities: machine type and CPU platform specification, instance template reuse, and cross-project sharing policies.

Reservations apply only to Compute Engine, Cloud Dataproc, and GKE. They don’t cover f1-micro, g1-small, preemptible VMs, or services like Cloud SQL. The examples are intentionally small. Combine them with your own instance templates and project configuration.

Reserve capacity with explicit machine specifications

Teams needing guaranteed capacity for production workloads often reserve VMs with specific machine types and CPU platforms to ensure availability during demand spikes.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const gceReservation = new gcp.compute.Reservation("gce_reservation", {
    name: "gce-reservation",
    zone: "us-central1-a",
    specificReservation: {
        count: 1,
        instanceProperties: {
            minCpuPlatform: "Intel Cascade Lake",
            machineType: "n2-standard-2",
        },
    },
});
import pulumi
import pulumi_gcp as gcp

gce_reservation = gcp.compute.Reservation("gce_reservation",
    name="gce-reservation",
    zone="us-central1-a",
    specific_reservation={
        "count": 1,
        "instance_properties": {
            "min_cpu_platform": "Intel Cascade Lake",
            "machine_type": "n2-standard-2",
        },
    })
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := compute.NewReservation(ctx, "gce_reservation", &compute.ReservationArgs{
			Name: pulumi.String("gce-reservation"),
			Zone: pulumi.String("us-central1-a"),
			SpecificReservation: &compute.ReservationSpecificReservationArgs{
				Count: pulumi.Int(1),
				InstanceProperties: &compute.ReservationSpecificReservationInstancePropertiesArgs{
					MinCpuPlatform: pulumi.String("Intel Cascade Lake"),
					MachineType:    pulumi.String("n2-standard-2"),
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var gceReservation = new Gcp.Compute.Reservation("gce_reservation", new()
    {
        Name = "gce-reservation",
        Zone = "us-central1-a",
        SpecificReservation = new Gcp.Compute.Inputs.ReservationSpecificReservationArgs
        {
            Count = 1,
            InstanceProperties = new Gcp.Compute.Inputs.ReservationSpecificReservationInstancePropertiesArgs
            {
                MinCpuPlatform = "Intel Cascade Lake",
                MachineType = "n2-standard-2",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Reservation;
import com.pulumi.gcp.compute.ReservationArgs;
import com.pulumi.gcp.compute.inputs.ReservationSpecificReservationArgs;
import com.pulumi.gcp.compute.inputs.ReservationSpecificReservationInstancePropertiesArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var gceReservation = new Reservation("gceReservation", ReservationArgs.builder()
            .name("gce-reservation")
            .zone("us-central1-a")
            .specificReservation(ReservationSpecificReservationArgs.builder()
                .count(1)
                .instanceProperties(ReservationSpecificReservationInstancePropertiesArgs.builder()
                    .minCpuPlatform("Intel Cascade Lake")
                    .machineType("n2-standard-2")
                    .build())
                .build())
            .build());

    }
}
resources:
  gceReservation:
    type: gcp:compute:Reservation
    name: gce_reservation
    properties:
      name: gce-reservation
      zone: us-central1-a
      specificReservation:
        count: 1
        instanceProperties:
          minCpuPlatform: Intel Cascade Lake
          machineType: n2-standard-2

The specificReservation block defines what you’re reserving. The count property sets how many instances to reserve; instanceProperties specifies the machineType and minCpuPlatform. The zone property determines where capacity is held. Google maintains this capacity whether or not you launch instances.

Enable emergent maintenance for reserved instances

Some workloads require maintenance windows that align with Google’s infrastructure updates, allowing reserved VMs to participate in periodic maintenance cycles.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const gceReservation = new gcp.compute.Reservation("gce_reservation", {
    name: "gce-reservation",
    zone: "us-central1-a",
    specificReservation: {
        count: 1,
        instanceProperties: {
            minCpuPlatform: "Intel Cascade Lake",
            machineType: "n2-standard-2",
            maintenanceInterval: "PERIODIC",
        },
    },
    enableEmergentMaintenance: true,
});
import pulumi
import pulumi_gcp as gcp

gce_reservation = gcp.compute.Reservation("gce_reservation",
    name="gce-reservation",
    zone="us-central1-a",
    specific_reservation={
        "count": 1,
        "instance_properties": {
            "min_cpu_platform": "Intel Cascade Lake",
            "machine_type": "n2-standard-2",
            "maintenance_interval": "PERIODIC",
        },
    },
    enable_emergent_maintenance=True)
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := compute.NewReservation(ctx, "gce_reservation", &compute.ReservationArgs{
			Name: pulumi.String("gce-reservation"),
			Zone: pulumi.String("us-central1-a"),
			SpecificReservation: &compute.ReservationSpecificReservationArgs{
				Count: pulumi.Int(1),
				InstanceProperties: &compute.ReservationSpecificReservationInstancePropertiesArgs{
					MinCpuPlatform:      pulumi.String("Intel Cascade Lake"),
					MachineType:         pulumi.String("n2-standard-2"),
					MaintenanceInterval: pulumi.String("PERIODIC"),
				},
			},
			EnableEmergentMaintenance: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var gceReservation = new Gcp.Compute.Reservation("gce_reservation", new()
    {
        Name = "gce-reservation",
        Zone = "us-central1-a",
        SpecificReservation = new Gcp.Compute.Inputs.ReservationSpecificReservationArgs
        {
            Count = 1,
            InstanceProperties = new Gcp.Compute.Inputs.ReservationSpecificReservationInstancePropertiesArgs
            {
                MinCpuPlatform = "Intel Cascade Lake",
                MachineType = "n2-standard-2",
                MaintenanceInterval = "PERIODIC",
            },
        },
        EnableEmergentMaintenance = true,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Reservation;
import com.pulumi.gcp.compute.ReservationArgs;
import com.pulumi.gcp.compute.inputs.ReservationSpecificReservationArgs;
import com.pulumi.gcp.compute.inputs.ReservationSpecificReservationInstancePropertiesArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var gceReservation = new Reservation("gceReservation", ReservationArgs.builder()
            .name("gce-reservation")
            .zone("us-central1-a")
            .specificReservation(ReservationSpecificReservationArgs.builder()
                .count(1)
                .instanceProperties(ReservationSpecificReservationInstancePropertiesArgs.builder()
                    .minCpuPlatform("Intel Cascade Lake")
                    .machineType("n2-standard-2")
                    .maintenanceInterval("PERIODIC")
                    .build())
                .build())
            .enableEmergentMaintenance(true)
            .build());

    }
}
resources:
  gceReservation:
    type: gcp:compute:Reservation
    name: gce_reservation
    properties:
      name: gce-reservation
      zone: us-central1-a
      specificReservation:
        count: 1
        instanceProperties:
          minCpuPlatform: Intel Cascade Lake
          machineType: n2-standard-2
          maintenanceInterval: PERIODIC
      enableEmergentMaintenance: true

The maintenanceInterval property within instanceProperties controls when Google can perform maintenance on reserved capacity. Setting enableEmergentMaintenance to true allows the reservation to participate in Google’s maintenance schedule. This extends the basic reservation structure with maintenance configuration.

Reserve capacity using an instance template

When your VM configuration is already defined in an instance template, you can reference that template instead of duplicating machine type and platform settings.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const myImage = gcp.compute.getImage({
    family: "debian-11",
    project: "debian-cloud",
});
const foobar = new gcp.compute.InstanceTemplate("foobar", {
    name: "instance-template",
    machineType: "n2-standard-2",
    canIpForward: false,
    tags: [
        "foo",
        "bar",
    ],
    disks: [{
        sourceImage: myImage.then(myImage => myImage.selfLink),
        autoDelete: true,
        boot: true,
    }],
    networkInterfaces: [{
        network: "default",
    }],
    scheduling: {
        preemptible: false,
        automaticRestart: true,
    },
    metadata: {
        foo: "bar",
    },
    serviceAccount: {
        scopes: [
            "userinfo-email",
            "compute-ro",
            "storage-ro",
        ],
    },
    labels: {
        my_label: "foobar",
    },
});
const gceReservationSourceInstanceTemplate = new gcp.compute.Reservation("gce_reservation_source_instance_template", {
    name: "gce-reservation-source-instance-template",
    zone: "us-central1-a",
    specificReservation: {
        count: 1,
        sourceInstanceTemplate: foobar.selfLink,
    },
});
import pulumi
import pulumi_gcp as gcp

my_image = gcp.compute.get_image(family="debian-11",
    project="debian-cloud")
foobar = gcp.compute.InstanceTemplate("foobar",
    name="instance-template",
    machine_type="n2-standard-2",
    can_ip_forward=False,
    tags=[
        "foo",
        "bar",
    ],
    disks=[{
        "source_image": my_image.self_link,
        "auto_delete": True,
        "boot": True,
    }],
    network_interfaces=[{
        "network": "default",
    }],
    scheduling={
        "preemptible": False,
        "automatic_restart": True,
    },
    metadata={
        "foo": "bar",
    },
    service_account={
        "scopes": [
            "userinfo-email",
            "compute-ro",
            "storage-ro",
        ],
    },
    labels={
        "my_label": "foobar",
    })
gce_reservation_source_instance_template = gcp.compute.Reservation("gce_reservation_source_instance_template",
    name="gce-reservation-source-instance-template",
    zone="us-central1-a",
    specific_reservation={
        "count": 1,
        "source_instance_template": foobar.self_link,
    })
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		myImage, err := compute.LookupImage(ctx, &compute.LookupImageArgs{
			Family:  pulumi.StringRef("debian-11"),
			Project: pulumi.StringRef("debian-cloud"),
		}, nil)
		if err != nil {
			return err
		}
		foobar, err := compute.NewInstanceTemplate(ctx, "foobar", &compute.InstanceTemplateArgs{
			Name:         pulumi.String("instance-template"),
			MachineType:  pulumi.String("n2-standard-2"),
			CanIpForward: pulumi.Bool(false),
			Tags: pulumi.StringArray{
				pulumi.String("foo"),
				pulumi.String("bar"),
			},
			Disks: compute.InstanceTemplateDiskArray{
				&compute.InstanceTemplateDiskArgs{
					SourceImage: pulumi.String(myImage.SelfLink),
					AutoDelete:  pulumi.Bool(true),
					Boot:        pulumi.Bool(true),
				},
			},
			NetworkInterfaces: compute.InstanceTemplateNetworkInterfaceArray{
				&compute.InstanceTemplateNetworkInterfaceArgs{
					Network: pulumi.String("default"),
				},
			},
			Scheduling: &compute.InstanceTemplateSchedulingArgs{
				Preemptible:      pulumi.Bool(false),
				AutomaticRestart: pulumi.Bool(true),
			},
			Metadata: pulumi.StringMap{
				"foo": pulumi.String("bar"),
			},
			ServiceAccount: &compute.InstanceTemplateServiceAccountArgs{
				Scopes: pulumi.StringArray{
					pulumi.String("userinfo-email"),
					pulumi.String("compute-ro"),
					pulumi.String("storage-ro"),
				},
			},
			Labels: pulumi.StringMap{
				"my_label": pulumi.String("foobar"),
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewReservation(ctx, "gce_reservation_source_instance_template", &compute.ReservationArgs{
			Name: pulumi.String("gce-reservation-source-instance-template"),
			Zone: pulumi.String("us-central1-a"),
			SpecificReservation: &compute.ReservationSpecificReservationArgs{
				Count:                  pulumi.Int(1),
				SourceInstanceTemplate: foobar.SelfLink,
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var myImage = Gcp.Compute.GetImage.Invoke(new()
    {
        Family = "debian-11",
        Project = "debian-cloud",
    });

    var foobar = new Gcp.Compute.InstanceTemplate("foobar", new()
    {
        Name = "instance-template",
        MachineType = "n2-standard-2",
        CanIpForward = false,
        Tags = new[]
        {
            "foo",
            "bar",
        },
        Disks = new[]
        {
            new Gcp.Compute.Inputs.InstanceTemplateDiskArgs
            {
                SourceImage = myImage.Apply(getImageResult => getImageResult.SelfLink),
                AutoDelete = true,
                Boot = true,
            },
        },
        NetworkInterfaces = new[]
        {
            new Gcp.Compute.Inputs.InstanceTemplateNetworkInterfaceArgs
            {
                Network = "default",
            },
        },
        Scheduling = new Gcp.Compute.Inputs.InstanceTemplateSchedulingArgs
        {
            Preemptible = false,
            AutomaticRestart = true,
        },
        Metadata = 
        {
            { "foo", "bar" },
        },
        ServiceAccount = new Gcp.Compute.Inputs.InstanceTemplateServiceAccountArgs
        {
            Scopes = new[]
            {
                "userinfo-email",
                "compute-ro",
                "storage-ro",
            },
        },
        Labels = 
        {
            { "my_label", "foobar" },
        },
    });

    var gceReservationSourceInstanceTemplate = new Gcp.Compute.Reservation("gce_reservation_source_instance_template", new()
    {
        Name = "gce-reservation-source-instance-template",
        Zone = "us-central1-a",
        SpecificReservation = new Gcp.Compute.Inputs.ReservationSpecificReservationArgs
        {
            Count = 1,
            SourceInstanceTemplate = foobar.SelfLink,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.ComputeFunctions;
import com.pulumi.gcp.compute.inputs.GetImageArgs;
import com.pulumi.gcp.compute.InstanceTemplate;
import com.pulumi.gcp.compute.InstanceTemplateArgs;
import com.pulumi.gcp.compute.inputs.InstanceTemplateDiskArgs;
import com.pulumi.gcp.compute.inputs.InstanceTemplateNetworkInterfaceArgs;
import com.pulumi.gcp.compute.inputs.InstanceTemplateSchedulingArgs;
import com.pulumi.gcp.compute.inputs.InstanceTemplateServiceAccountArgs;
import com.pulumi.gcp.compute.Reservation;
import com.pulumi.gcp.compute.ReservationArgs;
import com.pulumi.gcp.compute.inputs.ReservationSpecificReservationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        final var myImage = ComputeFunctions.getImage(GetImageArgs.builder()
            .family("debian-11")
            .project("debian-cloud")
            .build());

        var foobar = new InstanceTemplate("foobar", InstanceTemplateArgs.builder()
            .name("instance-template")
            .machineType("n2-standard-2")
            .canIpForward(false)
            .tags(            
                "foo",
                "bar")
            .disks(InstanceTemplateDiskArgs.builder()
                .sourceImage(myImage.selfLink())
                .autoDelete(true)
                .boot(true)
                .build())
            .networkInterfaces(InstanceTemplateNetworkInterfaceArgs.builder()
                .network("default")
                .build())
            .scheduling(InstanceTemplateSchedulingArgs.builder()
                .preemptible(false)
                .automaticRestart(true)
                .build())
            .metadata(Map.of("foo", "bar"))
            .serviceAccount(InstanceTemplateServiceAccountArgs.builder()
                .scopes(                
                    "userinfo-email",
                    "compute-ro",
                    "storage-ro")
                .build())
            .labels(Map.of("my_label", "foobar"))
            .build());

        var gceReservationSourceInstanceTemplate = new Reservation("gceReservationSourceInstanceTemplate", ReservationArgs.builder()
            .name("gce-reservation-source-instance-template")
            .zone("us-central1-a")
            .specificReservation(ReservationSpecificReservationArgs.builder()
                .count(1)
                .sourceInstanceTemplate(foobar.selfLink())
                .build())
            .build());

    }
}
resources:
  foobar:
    type: gcp:compute:InstanceTemplate
    properties:
      name: instance-template
      machineType: n2-standard-2
      canIpForward: false
      tags:
        - foo
        - bar
      disks:
        - sourceImage: ${myImage.selfLink}
          autoDelete: true
          boot: true
      networkInterfaces:
        - network: default
      scheduling:
        preemptible: false
        automaticRestart: true
      metadata:
        foo: bar
      serviceAccount:
        scopes:
          - userinfo-email
          - compute-ro
          - storage-ro
      labels:
        my_label: foobar
  gceReservationSourceInstanceTemplate:
    type: gcp:compute:Reservation
    name: gce_reservation_source_instance_template
    properties:
      name: gce-reservation-source-instance-template
      zone: us-central1-a
      specificReservation:
        count: 1
        sourceInstanceTemplate: ${foobar.selfLink}
variables:
  myImage:
    fn::invoke:
      function: gcp:compute:getImage
      arguments:
        family: debian-11
        project: debian-cloud

The sourceInstanceTemplate property points to an existing InstanceTemplate resource. This approach reuses your template’s machine type, disk configuration, and network settings for the reservation. You still specify count, but instanceProperties is replaced by the template reference.

Share reservations across projects and services

Organizations with multiple projects or services can share reserved capacity to maximize utilization and reduce costs.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const myImage = gcp.compute.getImage({
    family: "debian-11",
    project: "debian-cloud",
});
const foobar = new gcp.compute.InstanceTemplate("foobar", {
    name: "instance-template",
    machineType: "g2-standard-4",
    canIpForward: false,
    tags: [
        "foo",
        "bar",
    ],
    disks: [{
        sourceImage: myImage.then(myImage => myImage.selfLink),
        autoDelete: true,
        boot: true,
    }],
    networkInterfaces: [{
        network: "default",
    }],
    scheduling: {
        preemptible: false,
        automaticRestart: true,
    },
    metadata: {
        foo: "bar",
    },
    serviceAccount: {
        scopes: [
            "userinfo-email",
            "compute-ro",
            "storage-ro",
        ],
    },
    labels: {
        my_label: "foobar",
    },
});
const gceReservationSharingPolicy = new gcp.compute.Reservation("gce_reservation_sharing_policy", {
    name: "gce-reservation-sharing-policy",
    zone: "us-central1-b",
    specificReservation: {
        count: 2,
        sourceInstanceTemplate: foobar.selfLink,
    },
    reservationSharingPolicy: {
        serviceShareType: "ALLOW_ALL",
    },
});
import pulumi
import pulumi_gcp as gcp

my_image = gcp.compute.get_image(family="debian-11",
    project="debian-cloud")
foobar = gcp.compute.InstanceTemplate("foobar",
    name="instance-template",
    machine_type="g2-standard-4",
    can_ip_forward=False,
    tags=[
        "foo",
        "bar",
    ],
    disks=[{
        "source_image": my_image.self_link,
        "auto_delete": True,
        "boot": True,
    }],
    network_interfaces=[{
        "network": "default",
    }],
    scheduling={
        "preemptible": False,
        "automatic_restart": True,
    },
    metadata={
        "foo": "bar",
    },
    service_account={
        "scopes": [
            "userinfo-email",
            "compute-ro",
            "storage-ro",
        ],
    },
    labels={
        "my_label": "foobar",
    })
gce_reservation_sharing_policy = gcp.compute.Reservation("gce_reservation_sharing_policy",
    name="gce-reservation-sharing-policy",
    zone="us-central1-b",
    specific_reservation={
        "count": 2,
        "source_instance_template": foobar.self_link,
    },
    reservation_sharing_policy={
        "service_share_type": "ALLOW_ALL",
    })
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		myImage, err := compute.LookupImage(ctx, &compute.LookupImageArgs{
			Family:  pulumi.StringRef("debian-11"),
			Project: pulumi.StringRef("debian-cloud"),
		}, nil)
		if err != nil {
			return err
		}
		foobar, err := compute.NewInstanceTemplate(ctx, "foobar", &compute.InstanceTemplateArgs{
			Name:         pulumi.String("instance-template"),
			MachineType:  pulumi.String("g2-standard-4"),
			CanIpForward: pulumi.Bool(false),
			Tags: pulumi.StringArray{
				pulumi.String("foo"),
				pulumi.String("bar"),
			},
			Disks: compute.InstanceTemplateDiskArray{
				&compute.InstanceTemplateDiskArgs{
					SourceImage: pulumi.String(myImage.SelfLink),
					AutoDelete:  pulumi.Bool(true),
					Boot:        pulumi.Bool(true),
				},
			},
			NetworkInterfaces: compute.InstanceTemplateNetworkInterfaceArray{
				&compute.InstanceTemplateNetworkInterfaceArgs{
					Network: pulumi.String("default"),
				},
			},
			Scheduling: &compute.InstanceTemplateSchedulingArgs{
				Preemptible:      pulumi.Bool(false),
				AutomaticRestart: pulumi.Bool(true),
			},
			Metadata: pulumi.StringMap{
				"foo": pulumi.String("bar"),
			},
			ServiceAccount: &compute.InstanceTemplateServiceAccountArgs{
				Scopes: pulumi.StringArray{
					pulumi.String("userinfo-email"),
					pulumi.String("compute-ro"),
					pulumi.String("storage-ro"),
				},
			},
			Labels: pulumi.StringMap{
				"my_label": pulumi.String("foobar"),
			},
		})
		if err != nil {
			return err
		}
		_, err = compute.NewReservation(ctx, "gce_reservation_sharing_policy", &compute.ReservationArgs{
			Name: pulumi.String("gce-reservation-sharing-policy"),
			Zone: pulumi.String("us-central1-b"),
			SpecificReservation: &compute.ReservationSpecificReservationArgs{
				Count:                  pulumi.Int(2),
				SourceInstanceTemplate: foobar.SelfLink,
			},
			ReservationSharingPolicy: &compute.ReservationReservationSharingPolicyArgs{
				ServiceShareType: pulumi.String("ALLOW_ALL"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var myImage = Gcp.Compute.GetImage.Invoke(new()
    {
        Family = "debian-11",
        Project = "debian-cloud",
    });

    var foobar = new Gcp.Compute.InstanceTemplate("foobar", new()
    {
        Name = "instance-template",
        MachineType = "g2-standard-4",
        CanIpForward = false,
        Tags = new[]
        {
            "foo",
            "bar",
        },
        Disks = new[]
        {
            new Gcp.Compute.Inputs.InstanceTemplateDiskArgs
            {
                SourceImage = myImage.Apply(getImageResult => getImageResult.SelfLink),
                AutoDelete = true,
                Boot = true,
            },
        },
        NetworkInterfaces = new[]
        {
            new Gcp.Compute.Inputs.InstanceTemplateNetworkInterfaceArgs
            {
                Network = "default",
            },
        },
        Scheduling = new Gcp.Compute.Inputs.InstanceTemplateSchedulingArgs
        {
            Preemptible = false,
            AutomaticRestart = true,
        },
        Metadata = 
        {
            { "foo", "bar" },
        },
        ServiceAccount = new Gcp.Compute.Inputs.InstanceTemplateServiceAccountArgs
        {
            Scopes = new[]
            {
                "userinfo-email",
                "compute-ro",
                "storage-ro",
            },
        },
        Labels = 
        {
            { "my_label", "foobar" },
        },
    });

    var gceReservationSharingPolicy = new Gcp.Compute.Reservation("gce_reservation_sharing_policy", new()
    {
        Name = "gce-reservation-sharing-policy",
        Zone = "us-central1-b",
        SpecificReservation = new Gcp.Compute.Inputs.ReservationSpecificReservationArgs
        {
            Count = 2,
            SourceInstanceTemplate = foobar.SelfLink,
        },
        ReservationSharingPolicy = new Gcp.Compute.Inputs.ReservationReservationSharingPolicyArgs
        {
            ServiceShareType = "ALLOW_ALL",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.ComputeFunctions;
import com.pulumi.gcp.compute.inputs.GetImageArgs;
import com.pulumi.gcp.compute.InstanceTemplate;
import com.pulumi.gcp.compute.InstanceTemplateArgs;
import com.pulumi.gcp.compute.inputs.InstanceTemplateDiskArgs;
import com.pulumi.gcp.compute.inputs.InstanceTemplateNetworkInterfaceArgs;
import com.pulumi.gcp.compute.inputs.InstanceTemplateSchedulingArgs;
import com.pulumi.gcp.compute.inputs.InstanceTemplateServiceAccountArgs;
import com.pulumi.gcp.compute.Reservation;
import com.pulumi.gcp.compute.ReservationArgs;
import com.pulumi.gcp.compute.inputs.ReservationSpecificReservationArgs;
import com.pulumi.gcp.compute.inputs.ReservationReservationSharingPolicyArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        final var myImage = ComputeFunctions.getImage(GetImageArgs.builder()
            .family("debian-11")
            .project("debian-cloud")
            .build());

        var foobar = new InstanceTemplate("foobar", InstanceTemplateArgs.builder()
            .name("instance-template")
            .machineType("g2-standard-4")
            .canIpForward(false)
            .tags(            
                "foo",
                "bar")
            .disks(InstanceTemplateDiskArgs.builder()
                .sourceImage(myImage.selfLink())
                .autoDelete(true)
                .boot(true)
                .build())
            .networkInterfaces(InstanceTemplateNetworkInterfaceArgs.builder()
                .network("default")
                .build())
            .scheduling(InstanceTemplateSchedulingArgs.builder()
                .preemptible(false)
                .automaticRestart(true)
                .build())
            .metadata(Map.of("foo", "bar"))
            .serviceAccount(InstanceTemplateServiceAccountArgs.builder()
                .scopes(                
                    "userinfo-email",
                    "compute-ro",
                    "storage-ro")
                .build())
            .labels(Map.of("my_label", "foobar"))
            .build());

        var gceReservationSharingPolicy = new Reservation("gceReservationSharingPolicy", ReservationArgs.builder()
            .name("gce-reservation-sharing-policy")
            .zone("us-central1-b")
            .specificReservation(ReservationSpecificReservationArgs.builder()
                .count(2)
                .sourceInstanceTemplate(foobar.selfLink())
                .build())
            .reservationSharingPolicy(ReservationReservationSharingPolicyArgs.builder()
                .serviceShareType("ALLOW_ALL")
                .build())
            .build());

    }
}
resources:
  foobar:
    type: gcp:compute:InstanceTemplate
    properties:
      name: instance-template
      machineType: g2-standard-4
      canIpForward: false
      tags:
        - foo
        - bar
      disks:
        - sourceImage: ${myImage.selfLink}
          autoDelete: true
          boot: true
      networkInterfaces:
        - network: default
      scheduling:
        preemptible: false
        automaticRestart: true
      metadata:
        foo: bar
      serviceAccount:
        scopes:
          - userinfo-email
          - compute-ro
          - storage-ro
      labels:
        my_label: foobar
  gceReservationSharingPolicy:
    type: gcp:compute:Reservation
    name: gce_reservation_sharing_policy
    properties:
      name: gce-reservation-sharing-policy
      zone: us-central1-b
      specificReservation:
        count: 2
        sourceInstanceTemplate: ${foobar.selfLink}
      reservationSharingPolicy:
        serviceShareType: ALLOW_ALL
variables:
  myImage:
    fn::invoke:
      function: gcp:compute:getImage
      arguments:
        family: debian-11
        project: debian-cloud

The reservationSharingPolicy block controls who can consume reserved capacity. Setting serviceShareType to “ALLOW_ALL” permits any project in your organization to use the reservation. Without this policy, only the project that created the reservation can consume it.

Beyond these examples

These snippets focus on specific reservation-level features: explicit machine specifications and instance templates, maintenance configuration, and cross-project sharing policies. They’re intentionally minimal rather than full capacity planning solutions.

The examples may reference pre-existing infrastructure such as instance templates (for template-based reservations) and GCP project and zone configuration. They focus on configuring the reservation rather than provisioning the surrounding compute infrastructure.

To keep things focused, common reservation patterns are omitted, including:

  • Automatic deletion timing (deleteAtTime, deleteAfterDuration)
  • Exclusive reservation targeting (specificReservationRequired)
  • Fine-grained sharing controls (shareSettings)
  • Commitment-based reservations (commitment field)

These omissions are intentional: the goal is to illustrate how each reservation feature is wired, not provide drop-in capacity management modules. See the Compute Reservation resource reference for all available configuration options.

Let's create GCP Compute Reservations

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Machine Types & Compatibility
What machine types and services are NOT supported by reservations?
Reservations don’t apply to f1-micro or g1-small machine types, preemptible VMs, sole tenant nodes, or services like Cloud SQL and Dataflow. Use supported machine types like n2-standard-2 or g2-standard-4.
Can I use preemptible VMs with reservations?
No, reservations do not apply to preemptible VMs. Only standard (non-preemptible) Compute Engine, Cloud Dataproc, and GKE VMs can use reservations.
Configuration & Capacity
How do I define reservation capacity?
In specificReservation, set count and either define instanceProperties (with machineType and optionally minCpuPlatform) or reference an existing sourceInstanceTemplate.
Can I use an instance template instead of specifying machine type directly?
Yes, use sourceInstanceTemplate in specificReservation to reference an existing instance template instead of defining instanceProperties.
What are the naming requirements for reservations?
Names must be 1-63 characters long, start with a lowercase letter, and contain only lowercase letters, digits, and hyphens. The last character cannot be a hyphen (regex: [a-z][-a-z0-9]*[a-z0-9]?).
Sharing & Access Control
How do I share a reservation with other projects or services?
Configure reservationSharingPolicy with serviceShareType set to ALLOW_ALL to share the reservation with Google Cloud managed services.
What's the difference between targeted and non-targeted reservations?
When specificReservationRequired is true, only VMs that explicitly target the reservation by name can consume it. When false (default), any VM with reservation affinity can use it.
Lifecycle & Immutability
What properties can't be changed after creating a reservation?
The following properties are immutable: zone, name, project, description, deleteAtTime, enableEmergentMaintenance, and specificReservationRequired. Changes require recreating the reservation.
How can I configure auto-deletion for a reservation?
Use either deleteAtTime (absolute timestamp in RFC3339 format) or deleteAfterDuration (relative duration), but not both. These options are mutually exclusive.
Can I change the zone of an existing reservation?
No, zone is immutable. You must create a new reservation in the desired zone and delete the old one.

Using a different cloud?

Explore compute guides for other cloud providers: