Configure GCP Vertex AI Notebook Runtime Templates

The gcp:colab/runtimeTemplate:RuntimeTemplate resource, part of the Pulumi GCP provider, defines reusable VM configurations for Colab Enterprise notebook runtimes: machine type, accelerators, storage, and network placement. This guide focuses on three capabilities: basic machine and network configuration, GPU acceleration and persistent storage, and idle shutdown and encryption.

Runtime templates specify how notebook VMs are created but don’t provision the VMs themselves. Templates may reference VPC networks, subnetworks, and KMS keys that must exist separately. The examples are intentionally small. Combine them with your own network infrastructure and security policies.

Create a basic runtime template with internet access

Most deployments start with a simple template that defines the VM machine type and network configuration.

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

const runtime_template = new gcp.colab.RuntimeTemplate("runtime-template", {
    name: "colab-runtime-template",
    displayName: "Runtime template basic",
    location: "us-central1",
    machineSpec: {
        machineType: "e2-standard-4",
    },
    networkSpec: {
        enableInternetAccess: true,
    },
});
import pulumi
import pulumi_gcp as gcp

runtime_template = gcp.colab.RuntimeTemplate("runtime-template",
    name="colab-runtime-template",
    display_name="Runtime template basic",
    location="us-central1",
    machine_spec={
        "machine_type": "e2-standard-4",
    },
    network_spec={
        "enable_internet_access": True,
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := colab.NewRuntimeTemplate(ctx, "runtime-template", &colab.RuntimeTemplateArgs{
			Name:        pulumi.String("colab-runtime-template"),
			DisplayName: pulumi.String("Runtime template basic"),
			Location:    pulumi.String("us-central1"),
			MachineSpec: &colab.RuntimeTemplateMachineSpecArgs{
				MachineType: pulumi.String("e2-standard-4"),
			},
			NetworkSpec: &colab.RuntimeTemplateNetworkSpecArgs{
				EnableInternetAccess: 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 runtime_template = new Gcp.Colab.RuntimeTemplate("runtime-template", new()
    {
        Name = "colab-runtime-template",
        DisplayName = "Runtime template basic",
        Location = "us-central1",
        MachineSpec = new Gcp.Colab.Inputs.RuntimeTemplateMachineSpecArgs
        {
            MachineType = "e2-standard-4",
        },
        NetworkSpec = new Gcp.Colab.Inputs.RuntimeTemplateNetworkSpecArgs
        {
            EnableInternetAccess = true,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.colab.RuntimeTemplate;
import com.pulumi.gcp.colab.RuntimeTemplateArgs;
import com.pulumi.gcp.colab.inputs.RuntimeTemplateMachineSpecArgs;
import com.pulumi.gcp.colab.inputs.RuntimeTemplateNetworkSpecArgs;
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 runtime_template = new RuntimeTemplate("runtime-template", RuntimeTemplateArgs.builder()
            .name("colab-runtime-template")
            .displayName("Runtime template basic")
            .location("us-central1")
            .machineSpec(RuntimeTemplateMachineSpecArgs.builder()
                .machineType("e2-standard-4")
                .build())
            .networkSpec(RuntimeTemplateNetworkSpecArgs.builder()
                .enableInternetAccess(true)
                .build())
            .build());

    }
}
resources:
  runtime-template:
    type: gcp:colab:RuntimeTemplate
    properties:
      name: colab-runtime-template
      displayName: Runtime template basic
      location: us-central1
      machineSpec:
        machineType: e2-standard-4
      networkSpec:
        enableInternetAccess: true

The machineSpec property sets the VM machine type (e.g., “e2-standard-4”). The networkSpec property controls network behavior; enableInternetAccess determines whether the runtime can reach public endpoints. The location property specifies the GCP region where runtimes will be created.

Configure GPU acceleration and persistent storage

Machine learning workloads often require GPU acceleration and persistent disk storage for datasets and model checkpoints.

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

const myNetwork = new gcp.compute.Network("my_network", {
    name: "colab-test-default",
    autoCreateSubnetworks: false,
});
const mySubnetwork = new gcp.compute.Subnetwork("my_subnetwork", {
    name: "colab-test-default",
    network: myNetwork.id,
    region: "us-central1",
    ipCidrRange: "10.0.1.0/24",
});
const runtime_template = new gcp.colab.RuntimeTemplate("runtime-template", {
    name: "colab-runtime-template",
    displayName: "Runtime template full",
    location: "us-central1",
    description: "Full runtime template",
    machineSpec: {
        machineType: "n1-standard-2",
        acceleratorType: "NVIDIA_TESLA_T4",
        acceleratorCount: 1,
    },
    dataPersistentDiskSpec: {
        diskType: "pd-standard",
        diskSizeGb: "200",
    },
    networkSpec: {
        enableInternetAccess: true,
        network: myNetwork.id,
        subnetwork: mySubnetwork.id,
    },
    labels: {
        k: "val",
    },
    idleShutdownConfig: {
        idleTimeout: "3600s",
    },
    eucConfig: {
        eucDisabled: false,
    },
    shieldedVmConfig: {
        enableSecureBoot: false,
    },
    networkTags: [
        "abc",
        "def",
    ],
    encryptionSpec: {
        kmsKeyName: "my-crypto-key",
    },
    softwareConfig: {
        envs: [{
            name: "TEST",
            value: "1",
        }],
        postStartupScriptConfig: {
            postStartupScript: "echo 'hello world'",
            postStartupScriptUrl: "gs://colab-enterprise-pss-secure/secure_pss.sh",
            postStartupScriptBehavior: "RUN_ONCE",
        },
    },
});
import pulumi
import pulumi_gcp as gcp

my_network = gcp.compute.Network("my_network",
    name="colab-test-default",
    auto_create_subnetworks=False)
my_subnetwork = gcp.compute.Subnetwork("my_subnetwork",
    name="colab-test-default",
    network=my_network.id,
    region="us-central1",
    ip_cidr_range="10.0.1.0/24")
runtime_template = gcp.colab.RuntimeTemplate("runtime-template",
    name="colab-runtime-template",
    display_name="Runtime template full",
    location="us-central1",
    description="Full runtime template",
    machine_spec={
        "machine_type": "n1-standard-2",
        "accelerator_type": "NVIDIA_TESLA_T4",
        "accelerator_count": 1,
    },
    data_persistent_disk_spec={
        "disk_type": "pd-standard",
        "disk_size_gb": "200",
    },
    network_spec={
        "enable_internet_access": True,
        "network": my_network.id,
        "subnetwork": my_subnetwork.id,
    },
    labels={
        "k": "val",
    },
    idle_shutdown_config={
        "idle_timeout": "3600s",
    },
    euc_config={
        "euc_disabled": False,
    },
    shielded_vm_config={
        "enable_secure_boot": False,
    },
    network_tags=[
        "abc",
        "def",
    ],
    encryption_spec={
        "kms_key_name": "my-crypto-key",
    },
    software_config={
        "envs": [{
            "name": "TEST",
            "value": "1",
        }],
        "post_startup_script_config": {
            "post_startup_script": "echo 'hello world'",
            "post_startup_script_url": "gs://colab-enterprise-pss-secure/secure_pss.sh",
            "post_startup_script_behavior": "RUN_ONCE",
        },
    })
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/colab"
	"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 {
		myNetwork, err := compute.NewNetwork(ctx, "my_network", &compute.NetworkArgs{
			Name:                  pulumi.String("colab-test-default"),
			AutoCreateSubnetworks: pulumi.Bool(false),
		})
		if err != nil {
			return err
		}
		mySubnetwork, err := compute.NewSubnetwork(ctx, "my_subnetwork", &compute.SubnetworkArgs{
			Name:        pulumi.String("colab-test-default"),
			Network:     myNetwork.ID(),
			Region:      pulumi.String("us-central1"),
			IpCidrRange: pulumi.String("10.0.1.0/24"),
		})
		if err != nil {
			return err
		}
		_, err = colab.NewRuntimeTemplate(ctx, "runtime-template", &colab.RuntimeTemplateArgs{
			Name:        pulumi.String("colab-runtime-template"),
			DisplayName: pulumi.String("Runtime template full"),
			Location:    pulumi.String("us-central1"),
			Description: pulumi.String("Full runtime template"),
			MachineSpec: &colab.RuntimeTemplateMachineSpecArgs{
				MachineType:      pulumi.String("n1-standard-2"),
				AcceleratorType:  pulumi.String("NVIDIA_TESLA_T4"),
				AcceleratorCount: pulumi.Int(1),
			},
			DataPersistentDiskSpec: &colab.RuntimeTemplateDataPersistentDiskSpecArgs{
				DiskType:   pulumi.String("pd-standard"),
				DiskSizeGb: pulumi.String("200"),
			},
			NetworkSpec: &colab.RuntimeTemplateNetworkSpecArgs{
				EnableInternetAccess: pulumi.Bool(true),
				Network:              myNetwork.ID(),
				Subnetwork:           mySubnetwork.ID(),
			},
			Labels: pulumi.StringMap{
				"k": pulumi.String("val"),
			},
			IdleShutdownConfig: &colab.RuntimeTemplateIdleShutdownConfigArgs{
				IdleTimeout: pulumi.String("3600s"),
			},
			EucConfig: &colab.RuntimeTemplateEucConfigArgs{
				EucDisabled: pulumi.Bool(false),
			},
			ShieldedVmConfig: &colab.RuntimeTemplateShieldedVmConfigArgs{
				EnableSecureBoot: pulumi.Bool(false),
			},
			NetworkTags: pulumi.StringArray{
				pulumi.String("abc"),
				pulumi.String("def"),
			},
			EncryptionSpec: &colab.RuntimeTemplateEncryptionSpecArgs{
				KmsKeyName: pulumi.String("my-crypto-key"),
			},
			SoftwareConfig: &colab.RuntimeTemplateSoftwareConfigArgs{
				Envs: colab.RuntimeTemplateSoftwareConfigEnvArray{
					&colab.RuntimeTemplateSoftwareConfigEnvArgs{
						Name:  pulumi.String("TEST"),
						Value: pulumi.String("1"),
					},
				},
				PostStartupScriptConfig: &colab.RuntimeTemplateSoftwareConfigPostStartupScriptConfigArgs{
					PostStartupScript:         pulumi.String("echo 'hello world'"),
					PostStartupScriptUrl:      pulumi.String("gs://colab-enterprise-pss-secure/secure_pss.sh"),
					PostStartupScriptBehavior: pulumi.String("RUN_ONCE"),
				},
			},
		})
		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 myNetwork = new Gcp.Compute.Network("my_network", new()
    {
        Name = "colab-test-default",
        AutoCreateSubnetworks = false,
    });

    var mySubnetwork = new Gcp.Compute.Subnetwork("my_subnetwork", new()
    {
        Name = "colab-test-default",
        Network = myNetwork.Id,
        Region = "us-central1",
        IpCidrRange = "10.0.1.0/24",
    });

    var runtime_template = new Gcp.Colab.RuntimeTemplate("runtime-template", new()
    {
        Name = "colab-runtime-template",
        DisplayName = "Runtime template full",
        Location = "us-central1",
        Description = "Full runtime template",
        MachineSpec = new Gcp.Colab.Inputs.RuntimeTemplateMachineSpecArgs
        {
            MachineType = "n1-standard-2",
            AcceleratorType = "NVIDIA_TESLA_T4",
            AcceleratorCount = 1,
        },
        DataPersistentDiskSpec = new Gcp.Colab.Inputs.RuntimeTemplateDataPersistentDiskSpecArgs
        {
            DiskType = "pd-standard",
            DiskSizeGb = "200",
        },
        NetworkSpec = new Gcp.Colab.Inputs.RuntimeTemplateNetworkSpecArgs
        {
            EnableInternetAccess = true,
            Network = myNetwork.Id,
            Subnetwork = mySubnetwork.Id,
        },
        Labels = 
        {
            { "k", "val" },
        },
        IdleShutdownConfig = new Gcp.Colab.Inputs.RuntimeTemplateIdleShutdownConfigArgs
        {
            IdleTimeout = "3600s",
        },
        EucConfig = new Gcp.Colab.Inputs.RuntimeTemplateEucConfigArgs
        {
            EucDisabled = false,
        },
        ShieldedVmConfig = new Gcp.Colab.Inputs.RuntimeTemplateShieldedVmConfigArgs
        {
            EnableSecureBoot = false,
        },
        NetworkTags = new[]
        {
            "abc",
            "def",
        },
        EncryptionSpec = new Gcp.Colab.Inputs.RuntimeTemplateEncryptionSpecArgs
        {
            KmsKeyName = "my-crypto-key",
        },
        SoftwareConfig = new Gcp.Colab.Inputs.RuntimeTemplateSoftwareConfigArgs
        {
            Envs = new[]
            {
                new Gcp.Colab.Inputs.RuntimeTemplateSoftwareConfigEnvArgs
                {
                    Name = "TEST",
                    Value = "1",
                },
            },
            PostStartupScriptConfig = new Gcp.Colab.Inputs.RuntimeTemplateSoftwareConfigPostStartupScriptConfigArgs
            {
                PostStartupScript = "echo 'hello world'",
                PostStartupScriptUrl = "gs://colab-enterprise-pss-secure/secure_pss.sh",
                PostStartupScriptBehavior = "RUN_ONCE",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.Network;
import com.pulumi.gcp.compute.NetworkArgs;
import com.pulumi.gcp.compute.Subnetwork;
import com.pulumi.gcp.compute.SubnetworkArgs;
import com.pulumi.gcp.colab.RuntimeTemplate;
import com.pulumi.gcp.colab.RuntimeTemplateArgs;
import com.pulumi.gcp.colab.inputs.RuntimeTemplateMachineSpecArgs;
import com.pulumi.gcp.colab.inputs.RuntimeTemplateDataPersistentDiskSpecArgs;
import com.pulumi.gcp.colab.inputs.RuntimeTemplateNetworkSpecArgs;
import com.pulumi.gcp.colab.inputs.RuntimeTemplateIdleShutdownConfigArgs;
import com.pulumi.gcp.colab.inputs.RuntimeTemplateEucConfigArgs;
import com.pulumi.gcp.colab.inputs.RuntimeTemplateShieldedVmConfigArgs;
import com.pulumi.gcp.colab.inputs.RuntimeTemplateEncryptionSpecArgs;
import com.pulumi.gcp.colab.inputs.RuntimeTemplateSoftwareConfigArgs;
import com.pulumi.gcp.colab.inputs.RuntimeTemplateSoftwareConfigPostStartupScriptConfigArgs;
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 myNetwork = new Network("myNetwork", NetworkArgs.builder()
            .name("colab-test-default")
            .autoCreateSubnetworks(false)
            .build());

        var mySubnetwork = new Subnetwork("mySubnetwork", SubnetworkArgs.builder()
            .name("colab-test-default")
            .network(myNetwork.id())
            .region("us-central1")
            .ipCidrRange("10.0.1.0/24")
            .build());

        var runtime_template = new RuntimeTemplate("runtime-template", RuntimeTemplateArgs.builder()
            .name("colab-runtime-template")
            .displayName("Runtime template full")
            .location("us-central1")
            .description("Full runtime template")
            .machineSpec(RuntimeTemplateMachineSpecArgs.builder()
                .machineType("n1-standard-2")
                .acceleratorType("NVIDIA_TESLA_T4")
                .acceleratorCount(1)
                .build())
            .dataPersistentDiskSpec(RuntimeTemplateDataPersistentDiskSpecArgs.builder()
                .diskType("pd-standard")
                .diskSizeGb("200")
                .build())
            .networkSpec(RuntimeTemplateNetworkSpecArgs.builder()
                .enableInternetAccess(true)
                .network(myNetwork.id())
                .subnetwork(mySubnetwork.id())
                .build())
            .labels(Map.of("k", "val"))
            .idleShutdownConfig(RuntimeTemplateIdleShutdownConfigArgs.builder()
                .idleTimeout("3600s")
                .build())
            .eucConfig(RuntimeTemplateEucConfigArgs.builder()
                .eucDisabled(false)
                .build())
            .shieldedVmConfig(RuntimeTemplateShieldedVmConfigArgs.builder()
                .enableSecureBoot(false)
                .build())
            .networkTags(            
                "abc",
                "def")
            .encryptionSpec(RuntimeTemplateEncryptionSpecArgs.builder()
                .kmsKeyName("my-crypto-key")
                .build())
            .softwareConfig(RuntimeTemplateSoftwareConfigArgs.builder()
                .envs(RuntimeTemplateSoftwareConfigEnvArgs.builder()
                    .name("TEST")
                    .value("1")
                    .build())
                .postStartupScriptConfig(RuntimeTemplateSoftwareConfigPostStartupScriptConfigArgs.builder()
                    .postStartupScript("echo 'hello world'")
                    .postStartupScriptUrl("gs://colab-enterprise-pss-secure/secure_pss.sh")
                    .postStartupScriptBehavior("RUN_ONCE")
                    .build())
                .build())
            .build());

    }
}
resources:
  myNetwork:
    type: gcp:compute:Network
    name: my_network
    properties:
      name: colab-test-default
      autoCreateSubnetworks: false
  mySubnetwork:
    type: gcp:compute:Subnetwork
    name: my_subnetwork
    properties:
      name: colab-test-default
      network: ${myNetwork.id}
      region: us-central1
      ipCidrRange: 10.0.1.0/24
  runtime-template:
    type: gcp:colab:RuntimeTemplate
    properties:
      name: colab-runtime-template
      displayName: Runtime template full
      location: us-central1
      description: Full runtime template
      machineSpec:
        machineType: n1-standard-2
        acceleratorType: NVIDIA_TESLA_T4
        acceleratorCount: '1'
      dataPersistentDiskSpec:
        diskType: pd-standard
        diskSizeGb: 200
      networkSpec:
        enableInternetAccess: true
        network: ${myNetwork.id}
        subnetwork: ${mySubnetwork.id}
      labels:
        k: val
      idleShutdownConfig:
        idleTimeout: 3600s
      eucConfig:
        eucDisabled: false
      shieldedVmConfig:
        enableSecureBoot: false
      networkTags:
        - abc
        - def
      encryptionSpec:
        kmsKeyName: my-crypto-key
      softwareConfig:
        envs:
          - name: TEST
            value: 1
        postStartupScriptConfig:
          postStartupScript: echo 'hello world'
          postStartupScriptUrl: gs://colab-enterprise-pss-secure/secure_pss.sh
          postStartupScriptBehavior: RUN_ONCE

The acceleratorType and acceleratorCount properties attach GPUs to the runtime VM. The dataPersistentDiskSpec property configures a persistent disk that survives runtime restarts; diskType and diskSizeGb control performance and capacity. The idleShutdownConfig property automatically stops idle runtimes after the specified timeout, reducing costs. Custom network and subnetwork properties place the runtime in a specific VPC, while encryptionSpec enables customer-managed encryption keys for the persistent disk.

Beyond these examples

These snippets focus on specific runtime template features: machine type and GPU acceleration, persistent disk and network configuration, and idle shutdown and encryption. They’re intentionally minimal rather than full notebook environments.

The examples may reference pre-existing infrastructure such as VPC networks and subnetworks for custom networking, and KMS encryption keys for disk encryption. They focus on template configuration rather than provisioning the surrounding infrastructure.

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

  • Name auto-generation (example 2 shows omitting name property)
  • Network tags for firewall rules (networkTags)
  • Post-startup scripts and environment variables (softwareConfig)
  • EUC and Shielded VM security controls

These omissions are intentional: the goal is to illustrate how each template feature is wired, not provide drop-in notebook modules. See the Colab RuntimeTemplate resource reference for all available configuration options.

Let's configure GCP Vertex AI Notebook Runtime Templates

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Immutability
What happens if I change the machine type or network configuration?
Most properties are immutable and force resource replacement. Immutable properties include displayName, location, machineSpec, networkSpec, dataPersistentDiskSpec, eucConfig, idleShutdownConfig, shieldedVmConfig, softwareConfig, description, encryptionSpec, networkTags, name, and project.
Do I need to specify a name for my runtime template?
No, the name field is optional. If omitted, a name will be auto-generated for you.
Why aren't my label deletions reflected in GCP?
The labels field is non-authoritative and only manages labels in your Pulumi configuration. It won’t remove labels set by other clients or services. Use the effectiveLabels output to see all labels on the resource.
Networking & Access
Can I use a custom VPC network instead of the default?
Yes, configure networkSpec.network and networkSpec.subnetwork with your custom network and subnetwork IDs.
How do I control internet access for my runtime?
Set networkSpec.enableInternetAccess to true or false to enable or disable public internet access.
Machine Configuration
How do I add GPU accelerators to my runtime template?
Configure machineSpec.acceleratorType (e.g., NVIDIA_TESLA_T4) and machineSpec.acceleratorCount to specify the GPU type and quantity.
What machine types can I use?
Specify any valid Compute Engine machine type in machineSpec.machineType, such as e2-standard-4 or n1-standard-2.
Advanced Features
How do I configure automatic shutdown for idle runtimes?
Use idleShutdownConfig.idleTimeout to specify the idle duration (e.g., 3600s for 1 hour) before automatic shutdown.
Can I run custom scripts when the runtime starts?
Yes, configure softwareConfig.postStartupScriptConfig with a script URL or inline script. Set postStartupScriptBehavior to RUN_ONCE or another behavior.
What import formats are supported for existing runtime templates?
You can import using three formats: full path (projects/{{project}}/locations/{{location}}/notebookRuntimeTemplates/{{name}}), project-scoped ({{project}}/{{location}}/{{name}}), or location-scoped ({{location}}/{{name}}).

Using a different cloud?

Explore compute guides for other cloud providers: