Configure GCP Vertex AI Notebook Runtime Templates

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

Runtime templates reference GCP projects and locations, and may depend on custom VPC networks or KMS encryption keys. The examples are intentionally small. Combine them with your own network infrastructure and security policies.

Create a runtime template with machine and network specs

Most deployments start by defining a template that specifies the VM machine type and network access for notebook runtimes.

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

When you create a runtime from this template, Colab provisions a VM according to these specifications. The machineSpec sets the machine type (here, e2-standard-4 with 4 vCPUs and 16 GB memory). The networkSpec controls whether the runtime can access the public internet; setting enableInternetAccess to true allows outbound connections for package installation and external data access.

Configure GPU acceleration and persistent storage

Machine learning workloads often need 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

This configuration adds GPU acceleration by setting acceleratorType to NVIDIA_TESLA_T4 and acceleratorCount to 1. The dataPersistentDiskSpec provisions a 200 GB persistent disk (pd-standard) that survives runtime restarts. The idleShutdownConfig automatically stops the runtime after 3600 seconds of inactivity to reduce costs. Custom network placement is achieved by referencing a VPC network and subnetwork, allowing the runtime to access private resources.

Beyond these examples

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

The examples may reference pre-existing infrastructure such as GCP projects and locations, and KMS encryption keys for encrypted storage. They focus on configuring the runtime template rather than provisioning all surrounding infrastructure.

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

  • Auto-generated template names (name property optional)
  • Network tags for firewall rules (networkTags)
  • Post-startup scripts and environment variables (softwareConfig)
  • EUC and Shielded VM security settings

These omissions are intentional: the goal is to illustrate how each runtime 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 properties can't I change after creating a runtime template?
Nearly all properties are immutable, including displayName, location, machineSpec, networkSpec, dataPersistentDiskSpec, eucConfig, idleShutdownConfig, shieldedVmConfig, softwareConfig, description, encryptionSpec, and networkTags. To change these, you must recreate the template.
Why aren't all my labels showing up in Pulumi state?
The labels field is non-authoritative and only manages labels in your configuration. Labels added by other clients or services won’t be removed. Use effectiveLabels to see all labels present on the resource.
Machine & Compute Resources
Do I need to specify a name for my runtime template?
No, the name field is optional and will be auto-generated if omitted.
How do I add a GPU accelerator to my runtime template?
Configure acceleratorType and acceleratorCount within machineSpec. For example, set acceleratorType to NVIDIA_TESLA_T4 and acceleratorCount to 1.
Networking & VPC
How do I configure networking for my runtime template?

Use networkSpec to configure networking. You can:

  1. Enable internet access - Set enableInternetAccess to true
  2. Use custom VPC - Set network and subnetwork to reference your VPC resources
Can I use a custom VPC with my runtime template?
Yes, specify network and subnetwork in networkSpec to connect to your custom VPC and subnet.
Storage & Persistence
How do I configure the data disk for my runtime?
Use dataPersistentDiskSpec to set diskType (e.g., pd-standard) and diskSizeGb (e.g., 200).
Lifecycle & Automation
Can I automatically shut down idle runtimes?
Yes, configure idleShutdownConfig with an idleTimeout value (e.g., 3600s for 1 hour).
How do I run scripts when a runtime starts?
Use softwareConfig.postStartupScriptConfig to specify scripts. You can provide inline scripts with postStartupScript, reference scripts in Cloud Storage with postStartupScriptUrl, and control execution with postStartupScriptBehavior (e.g., RUN_ONCE).

Using a different cloud?

Explore compute guides for other cloud providers: