Create GCP Compute Reservations

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

Reservations apply only to Compute Engine, Cloud Dataproc, and Google Kubernetes Engine VMs in specific zones. Template-based reservations reference existing instance templates. The examples are intentionally small. Combine them with your own instance templates and project configuration.

Reserve capacity with specific machine properties

Teams running predictable workloads reserve capacity in a specific zone to guarantee VM availability during peak demand periods.

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 how many instances to reserve and their characteristics. The count property sets the number of reserved instances; instanceProperties specifies the machineType and minCpuPlatform. The zone property determines where capacity is held. Reserved capacity remains available whether or not VMs are running.

Reserve capacity using an instance template

When your infrastructure already uses instance templates to standardize VM configuration, you can reference that template directly rather than duplicating its properties.

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. Compute Engine reads the machine type, CPU platform, and other properties from the template. This approach keeps reservation configuration synchronized with your template definitions.

Share reservations across projects and services

Organizations with multiple projects can share reservation capacity rather than creating isolated reservations per project, improving utilization.

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 how capacity is shared. Setting serviceShareType to “ALLOW_ALL” permits any project in your organization to consume this reservation. Without a sharing policy, only the project that owns the reservation can use it.

Beyond these examples

These snippets focus on specific reservation features: machine-specific and template-based reservations, and cross-project sharing policies. They’re intentionally minimal rather than full capacity management solutions.

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

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

  • Auto-deletion scheduling (deleteAtTime, deleteAfterDuration)
  • Emergent maintenance configuration (enableEmergentMaintenance)
  • Explicit reservation targeting (specificReservationRequired)
  • Fine-grained sharing controls (shareSettings with project lists)

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

Compatibility & Limitations
What workloads can I reserve capacity for?
Reservations apply only to Compute Engine, Cloud Dataproc, and Google Kubernetes Engine VM usage. They don’t support f1-micro or g1-small machine types, preemptible VMs, sole tenant nodes, or services like Cloud SQL and Dataflow.
Can I use preemptible VMs with reservations?
No, reservations don’t apply to preemptible VMs.
Configuration & Setup
What are the naming requirements for reservations?
The name must be 1-63 characters long and match the regex [a-z][-a-z0-9]*[a-z0-9]?. It must start with a lowercase letter, contain only lowercase letters, digits, and dashes, and cannot end with a dash.
How do I define what to reserve?

You have two options in specificReservation:

  1. Direct properties - Specify count and instanceProperties (machineType, minCpuPlatform)
  2. Instance template - Use sourceInstanceTemplate pointing to an existing template
What's the difference between deleteAtTime and deleteAfterDuration?
Both auto-delete the reservation but are mutually exclusive. Use deleteAtTime for an absolute RFC3339 timestamp, or deleteAfterDuration for a relative duration from creation.
Sharing & Access Control
What does specificReservationRequired control?
When set to true, only VMs that target this reservation by name can consume it. When false (default), any VM with affinity for any reservation can consume it.
How do I share a reservation across projects or services?
Configure reservationSharingPolicy with serviceShareType set to ALLOW_ALL, or use shareSettings to control sharing.
Lifecycle Management
What properties are immutable after creation?
The following properties cannot be changed: name, zone, project, deleteAtTime, description, enableEmergentMaintenance, and specificReservationRequired. Changes require recreating the reservation.
Can I change the zone after creating a reservation?
No, the zone property is immutable. You must recreate the reservation in a different zone.
What is enableEmergentMaintenance used for?
It indicates whether this group of VMs has emergent maintenance enabled, and is used with the maintenanceInterval property set to PERIODIC in instance properties.

Using a different cloud?

Explore compute guides for other cloud providers: