Deploy GCP Notebook Instances

The gcp:notebooks/instance:Instance resource, part of the Pulumi GCP provider, provisions AI Platform Notebook instances for interactive data science and ML development. This resource is deprecated; for new projects, use gcp.workbench.Instance instead. This guide focuses on three capabilities: VM and container image deployment, GPU acceleration, and private networking with encryption.

Notebook instances run in VPC networks and may reference service accounts, KMS keys, and container registries. The examples are intentionally small. Combine them with your own VPC configuration, IAM roles, and security controls.

Launch a notebook with VM image and machine type

Most deployments start with a managed VM image, a machine type, and a zone to create a running instance.

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

const instance = new gcp.notebooks.Instance("instance", {
    name: "notebooks-instance",
    location: "us-west1-a",
    machineType: "e2-medium",
    vmImage: {
        project: "cloud-notebooks-managed",
        imageFamily: "workbench-instances",
    },
});
import pulumi
import pulumi_gcp as gcp

instance = gcp.notebooks.Instance("instance",
    name="notebooks-instance",
    location="us-west1-a",
    machine_type="e2-medium",
    vm_image={
        "project": "cloud-notebooks-managed",
        "image_family": "workbench-instances",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := notebooks.NewInstance(ctx, "instance", &notebooks.InstanceArgs{
			Name:        pulumi.String("notebooks-instance"),
			Location:    pulumi.String("us-west1-a"),
			MachineType: pulumi.String("e2-medium"),
			VmImage: &notebooks.InstanceVmImageArgs{
				Project:     pulumi.String("cloud-notebooks-managed"),
				ImageFamily: pulumi.String("workbench-instances"),
			},
		})
		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 instance = new Gcp.Notebooks.Instance("instance", new()
    {
        Name = "notebooks-instance",
        Location = "us-west1-a",
        MachineType = "e2-medium",
        VmImage = new Gcp.Notebooks.Inputs.InstanceVmImageArgs
        {
            Project = "cloud-notebooks-managed",
            ImageFamily = "workbench-instances",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.notebooks.Instance;
import com.pulumi.gcp.notebooks.InstanceArgs;
import com.pulumi.gcp.notebooks.inputs.InstanceVmImageArgs;
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 instance = new Instance("instance", InstanceArgs.builder()
            .name("notebooks-instance")
            .location("us-west1-a")
            .machineType("e2-medium")
            .vmImage(InstanceVmImageArgs.builder()
                .project("cloud-notebooks-managed")
                .imageFamily("workbench-instances")
                .build())
            .build());

    }
}
resources:
  instance:
    type: gcp:notebooks:Instance
    properties:
      name: notebooks-instance
      location: us-west1-a
      machineType: e2-medium
      vmImage:
        project: cloud-notebooks-managed
        imageFamily: workbench-instances

The vmImage property specifies the base environment using a project and imageFamily. The machineType determines CPU and memory resources. The location places the instance in a specific zone. Without explicit networking configuration, the instance uses default VPC settings.

Control instance state at creation time

Teams provisioning infrastructure often create instances in a stopped state to control costs or defer startup.

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

const instance = new gcp.notebooks.Instance("instance", {
    name: "notebooks-instance",
    location: "us-west1-a",
    machineType: "e2-medium",
    vmImage: {
        project: "cloud-notebooks-managed",
        imageFamily: "workbench-instances",
    },
    desiredState: "STOPPED",
});
import pulumi
import pulumi_gcp as gcp

instance = gcp.notebooks.Instance("instance",
    name="notebooks-instance",
    location="us-west1-a",
    machine_type="e2-medium",
    vm_image={
        "project": "cloud-notebooks-managed",
        "image_family": "workbench-instances",
    },
    desired_state="STOPPED")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := notebooks.NewInstance(ctx, "instance", &notebooks.InstanceArgs{
			Name:        pulumi.String("notebooks-instance"),
			Location:    pulumi.String("us-west1-a"),
			MachineType: pulumi.String("e2-medium"),
			VmImage: &notebooks.InstanceVmImageArgs{
				Project:     pulumi.String("cloud-notebooks-managed"),
				ImageFamily: pulumi.String("workbench-instances"),
			},
			DesiredState: pulumi.String("STOPPED"),
		})
		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 instance = new Gcp.Notebooks.Instance("instance", new()
    {
        Name = "notebooks-instance",
        Location = "us-west1-a",
        MachineType = "e2-medium",
        VmImage = new Gcp.Notebooks.Inputs.InstanceVmImageArgs
        {
            Project = "cloud-notebooks-managed",
            ImageFamily = "workbench-instances",
        },
        DesiredState = "STOPPED",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.notebooks.Instance;
import com.pulumi.gcp.notebooks.InstanceArgs;
import com.pulumi.gcp.notebooks.inputs.InstanceVmImageArgs;
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 instance = new Instance("instance", InstanceArgs.builder()
            .name("notebooks-instance")
            .location("us-west1-a")
            .machineType("e2-medium")
            .vmImage(InstanceVmImageArgs.builder()
                .project("cloud-notebooks-managed")
                .imageFamily("workbench-instances")
                .build())
            .desiredState("STOPPED")
            .build());

    }
}
resources:
  instance:
    type: gcp:notebooks:Instance
    properties:
      name: notebooks-instance
      location: us-west1-a
      machineType: e2-medium
      vmImage:
        project: cloud-notebooks-managed
        imageFamily: workbench-instances
      desiredState: STOPPED

The desiredState property controls whether the instance starts immediately. Set it to “STOPPED” to provision the instance without incurring compute charges until you explicitly start it. This extends the basic configuration with lifecycle control.

Deploy from a container image repository

Custom environments packaged as container images provide more flexibility than VM images.

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

const instance = new gcp.notebooks.Instance("instance", {
    name: "notebooks-instance",
    location: "us-west1-a",
    machineType: "e2-medium",
    metadata: {
        "proxy-mode": "service_account",
    },
    containerImage: {
        repository: "gcr.io/deeplearning-platform-release/base-cpu",
        tag: "latest",
    },
});
import pulumi
import pulumi_gcp as gcp

instance = gcp.notebooks.Instance("instance",
    name="notebooks-instance",
    location="us-west1-a",
    machine_type="e2-medium",
    metadata={
        "proxy-mode": "service_account",
    },
    container_image={
        "repository": "gcr.io/deeplearning-platform-release/base-cpu",
        "tag": "latest",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := notebooks.NewInstance(ctx, "instance", &notebooks.InstanceArgs{
			Name:        pulumi.String("notebooks-instance"),
			Location:    pulumi.String("us-west1-a"),
			MachineType: pulumi.String("e2-medium"),
			Metadata: pulumi.StringMap{
				"proxy-mode": pulumi.String("service_account"),
			},
			ContainerImage: &notebooks.InstanceContainerImageArgs{
				Repository: pulumi.String("gcr.io/deeplearning-platform-release/base-cpu"),
				Tag:        pulumi.String("latest"),
			},
		})
		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 instance = new Gcp.Notebooks.Instance("instance", new()
    {
        Name = "notebooks-instance",
        Location = "us-west1-a",
        MachineType = "e2-medium",
        Metadata = 
        {
            { "proxy-mode", "service_account" },
        },
        ContainerImage = new Gcp.Notebooks.Inputs.InstanceContainerImageArgs
        {
            Repository = "gcr.io/deeplearning-platform-release/base-cpu",
            Tag = "latest",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.notebooks.Instance;
import com.pulumi.gcp.notebooks.InstanceArgs;
import com.pulumi.gcp.notebooks.inputs.InstanceContainerImageArgs;
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 instance = new Instance("instance", InstanceArgs.builder()
            .name("notebooks-instance")
            .location("us-west1-a")
            .machineType("e2-medium")
            .metadata(Map.of("proxy-mode", "service_account"))
            .containerImage(InstanceContainerImageArgs.builder()
                .repository("gcr.io/deeplearning-platform-release/base-cpu")
                .tag("latest")
                .build())
            .build());

    }
}
resources:
  instance:
    type: gcp:notebooks:Instance
    properties:
      name: notebooks-instance
      location: us-west1-a
      machineType: e2-medium
      metadata:
        proxy-mode: service_account
      containerImage:
        repository: gcr.io/deeplearning-platform-release/base-cpu
        tag: latest

The containerImage property replaces vmImage, pointing to a container registry repository and tag. The metadata property configures proxy behavior. This approach lets you version and distribute custom notebook environments through container registries like GCR.

Attach GPU accelerators for ML workloads

Machine learning training benefits from GPU acceleration with automatic driver installation.

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

const instance = new gcp.notebooks.Instance("instance", {
    name: "notebooks-instance",
    location: "us-west1-a",
    machineType: "n1-standard-1",
    installGpuDriver: true,
    acceleratorConfig: {
        type: "NVIDIA_TESLA_T4",
        coreCount: 1,
    },
    vmImage: {
        project: "cloud-notebooks-managed",
        imageFamily: "workbench-instances",
    },
});
import pulumi
import pulumi_gcp as gcp

instance = gcp.notebooks.Instance("instance",
    name="notebooks-instance",
    location="us-west1-a",
    machine_type="n1-standard-1",
    install_gpu_driver=True,
    accelerator_config={
        "type": "NVIDIA_TESLA_T4",
        "core_count": 1,
    },
    vm_image={
        "project": "cloud-notebooks-managed",
        "image_family": "workbench-instances",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := notebooks.NewInstance(ctx, "instance", &notebooks.InstanceArgs{
			Name:             pulumi.String("notebooks-instance"),
			Location:         pulumi.String("us-west1-a"),
			MachineType:      pulumi.String("n1-standard-1"),
			InstallGpuDriver: pulumi.Bool(true),
			AcceleratorConfig: &notebooks.InstanceAcceleratorConfigArgs{
				Type:      pulumi.String("NVIDIA_TESLA_T4"),
				CoreCount: pulumi.Int(1),
			},
			VmImage: &notebooks.InstanceVmImageArgs{
				Project:     pulumi.String("cloud-notebooks-managed"),
				ImageFamily: pulumi.String("workbench-instances"),
			},
		})
		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 instance = new Gcp.Notebooks.Instance("instance", new()
    {
        Name = "notebooks-instance",
        Location = "us-west1-a",
        MachineType = "n1-standard-1",
        InstallGpuDriver = true,
        AcceleratorConfig = new Gcp.Notebooks.Inputs.InstanceAcceleratorConfigArgs
        {
            Type = "NVIDIA_TESLA_T4",
            CoreCount = 1,
        },
        VmImage = new Gcp.Notebooks.Inputs.InstanceVmImageArgs
        {
            Project = "cloud-notebooks-managed",
            ImageFamily = "workbench-instances",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.notebooks.Instance;
import com.pulumi.gcp.notebooks.InstanceArgs;
import com.pulumi.gcp.notebooks.inputs.InstanceAcceleratorConfigArgs;
import com.pulumi.gcp.notebooks.inputs.InstanceVmImageArgs;
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 instance = new Instance("instance", InstanceArgs.builder()
            .name("notebooks-instance")
            .location("us-west1-a")
            .machineType("n1-standard-1")
            .installGpuDriver(true)
            .acceleratorConfig(InstanceAcceleratorConfigArgs.builder()
                .type("NVIDIA_TESLA_T4")
                .coreCount(1)
                .build())
            .vmImage(InstanceVmImageArgs.builder()
                .project("cloud-notebooks-managed")
                .imageFamily("workbench-instances")
                .build())
            .build());

    }
}
resources:
  instance:
    type: gcp:notebooks:Instance
    properties:
      name: notebooks-instance
      location: us-west1-a
      machineType: n1-standard-1
      installGpuDriver: true
      acceleratorConfig:
        type: NVIDIA_TESLA_T4
        coreCount: 1
      vmImage:
        project: cloud-notebooks-managed
        imageFamily: workbench-instances

The acceleratorConfig property specifies the GPU type and count. Setting installGpuDriver to true tells Google Cloud to install NVIDIA drivers automatically. The machineType must support the chosen accelerator.

Configure networking, encryption, and access controls

Production deployments require private networking, customer-managed encryption, and explicit service accounts.

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

const myNetwork = gcp.compute.getNetwork({
    name: "default",
});
const mySubnetwork = gcp.compute.getSubnetwork({
    name: "default",
    region: "us-central1",
});
const instance = new gcp.notebooks.Instance("instance", {
    name: "notebooks-instance",
    location: "us-central1-a",
    machineType: "e2-medium",
    vmImage: {
        project: "cloud-notebooks-managed",
        imageFamily: "workbench-instances",
    },
    instanceOwners: ["my@service-account.com"],
    serviceAccount: "my@service-account.com",
    installGpuDriver: true,
    bootDiskType: "PD_SSD",
    bootDiskSizeGb: 150,
    noPublicIp: true,
    noProxyAccess: true,
    network: myNetwork.then(myNetwork => myNetwork.id),
    subnet: mySubnetwork.then(mySubnetwork => mySubnetwork.id),
    labels: {
        k: "val",
    },
    metadata: {
        terraform: "true",
    },
    serviceAccountScopes: [
        "https://www.googleapis.com/auth/bigquery",
        "https://www.googleapis.com/auth/devstorage.read_write",
        "https://www.googleapis.com/auth/cloud-platform",
        "https://www.googleapis.com/auth/userinfo.email",
    ],
    tags: [
        "foo",
        "bar",
    ],
    diskEncryption: "CMEK",
    kmsKey: "my-crypto-key",
    desiredState: "ACTIVE",
});
import pulumi
import pulumi_gcp as gcp

my_network = gcp.compute.get_network(name="default")
my_subnetwork = gcp.compute.get_subnetwork(name="default",
    region="us-central1")
instance = gcp.notebooks.Instance("instance",
    name="notebooks-instance",
    location="us-central1-a",
    machine_type="e2-medium",
    vm_image={
        "project": "cloud-notebooks-managed",
        "image_family": "workbench-instances",
    },
    instance_owners=["my@service-account.com"],
    service_account="my@service-account.com",
    install_gpu_driver=True,
    boot_disk_type="PD_SSD",
    boot_disk_size_gb=150,
    no_public_ip=True,
    no_proxy_access=True,
    network=my_network.id,
    subnet=my_subnetwork.id,
    labels={
        "k": "val",
    },
    metadata={
        "terraform": "true",
    },
    service_account_scopes=[
        "https://www.googleapis.com/auth/bigquery",
        "https://www.googleapis.com/auth/devstorage.read_write",
        "https://www.googleapis.com/auth/cloud-platform",
        "https://www.googleapis.com/auth/userinfo.email",
    ],
    tags=[
        "foo",
        "bar",
    ],
    disk_encryption="CMEK",
    kms_key="my-crypto-key",
    desired_state="ACTIVE")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		myNetwork, err := compute.LookupNetwork(ctx, &compute.LookupNetworkArgs{
			Name: "default",
		}, nil)
		if err != nil {
			return err
		}
		mySubnetwork, err := compute.LookupSubnetwork(ctx, &compute.LookupSubnetworkArgs{
			Name:   pulumi.StringRef("default"),
			Region: pulumi.StringRef("us-central1"),
		}, nil)
		if err != nil {
			return err
		}
		_, err = notebooks.NewInstance(ctx, "instance", &notebooks.InstanceArgs{
			Name:        pulumi.String("notebooks-instance"),
			Location:    pulumi.String("us-central1-a"),
			MachineType: pulumi.String("e2-medium"),
			VmImage: &notebooks.InstanceVmImageArgs{
				Project:     pulumi.String("cloud-notebooks-managed"),
				ImageFamily: pulumi.String("workbench-instances"),
			},
			InstanceOwners: pulumi.StringArray{
				pulumi.String("my@service-account.com"),
			},
			ServiceAccount:   pulumi.String("my@service-account.com"),
			InstallGpuDriver: pulumi.Bool(true),
			BootDiskType:     pulumi.String("PD_SSD"),
			BootDiskSizeGb:   pulumi.Int(150),
			NoPublicIp:       pulumi.Bool(true),
			NoProxyAccess:    pulumi.Bool(true),
			Network:          pulumi.String(myNetwork.Id),
			Subnet:           pulumi.String(mySubnetwork.Id),
			Labels: pulumi.StringMap{
				"k": pulumi.String("val"),
			},
			Metadata: pulumi.StringMap{
				"terraform": pulumi.String("true"),
			},
			ServiceAccountScopes: pulumi.StringArray{
				pulumi.String("https://www.googleapis.com/auth/bigquery"),
				pulumi.String("https://www.googleapis.com/auth/devstorage.read_write"),
				pulumi.String("https://www.googleapis.com/auth/cloud-platform"),
				pulumi.String("https://www.googleapis.com/auth/userinfo.email"),
			},
			Tags: pulumi.StringArray{
				pulumi.String("foo"),
				pulumi.String("bar"),
			},
			DiskEncryption: pulumi.String("CMEK"),
			KmsKey:         pulumi.String("my-crypto-key"),
			DesiredState:   pulumi.String("ACTIVE"),
		})
		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 = Gcp.Compute.GetNetwork.Invoke(new()
    {
        Name = "default",
    });

    var mySubnetwork = Gcp.Compute.GetSubnetwork.Invoke(new()
    {
        Name = "default",
        Region = "us-central1",
    });

    var instance = new Gcp.Notebooks.Instance("instance", new()
    {
        Name = "notebooks-instance",
        Location = "us-central1-a",
        MachineType = "e2-medium",
        VmImage = new Gcp.Notebooks.Inputs.InstanceVmImageArgs
        {
            Project = "cloud-notebooks-managed",
            ImageFamily = "workbench-instances",
        },
        InstanceOwners = new[]
        {
            "my@service-account.com",
        },
        ServiceAccount = "my@service-account.com",
        InstallGpuDriver = true,
        BootDiskType = "PD_SSD",
        BootDiskSizeGb = 150,
        NoPublicIp = true,
        NoProxyAccess = true,
        Network = myNetwork.Apply(getNetworkResult => getNetworkResult.Id),
        Subnet = mySubnetwork.Apply(getSubnetworkResult => getSubnetworkResult.Id),
        Labels = 
        {
            { "k", "val" },
        },
        Metadata = 
        {
            { "terraform", "true" },
        },
        ServiceAccountScopes = new[]
        {
            "https://www.googleapis.com/auth/bigquery",
            "https://www.googleapis.com/auth/devstorage.read_write",
            "https://www.googleapis.com/auth/cloud-platform",
            "https://www.googleapis.com/auth/userinfo.email",
        },
        Tags = new[]
        {
            "foo",
            "bar",
        },
        DiskEncryption = "CMEK",
        KmsKey = "my-crypto-key",
        DesiredState = "ACTIVE",
    });

});
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.GetNetworkArgs;
import com.pulumi.gcp.compute.inputs.GetSubnetworkArgs;
import com.pulumi.gcp.notebooks.Instance;
import com.pulumi.gcp.notebooks.InstanceArgs;
import com.pulumi.gcp.notebooks.inputs.InstanceVmImageArgs;
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 myNetwork = ComputeFunctions.getNetwork(GetNetworkArgs.builder()
            .name("default")
            .build());

        final var mySubnetwork = ComputeFunctions.getSubnetwork(GetSubnetworkArgs.builder()
            .name("default")
            .region("us-central1")
            .build());

        var instance = new Instance("instance", InstanceArgs.builder()
            .name("notebooks-instance")
            .location("us-central1-a")
            .machineType("e2-medium")
            .vmImage(InstanceVmImageArgs.builder()
                .project("cloud-notebooks-managed")
                .imageFamily("workbench-instances")
                .build())
            .instanceOwners("my@service-account.com")
            .serviceAccount("my@service-account.com")
            .installGpuDriver(true)
            .bootDiskType("PD_SSD")
            .bootDiskSizeGb(150)
            .noPublicIp(true)
            .noProxyAccess(true)
            .network(myNetwork.id())
            .subnet(mySubnetwork.id())
            .labels(Map.of("k", "val"))
            .metadata(Map.of("terraform", "true"))
            .serviceAccountScopes(            
                "https://www.googleapis.com/auth/bigquery",
                "https://www.googleapis.com/auth/devstorage.read_write",
                "https://www.googleapis.com/auth/cloud-platform",
                "https://www.googleapis.com/auth/userinfo.email")
            .tags(            
                "foo",
                "bar")
            .diskEncryption("CMEK")
            .kmsKey("my-crypto-key")
            .desiredState("ACTIVE")
            .build());

    }
}
resources:
  instance:
    type: gcp:notebooks:Instance
    properties:
      name: notebooks-instance
      location: us-central1-a
      machineType: e2-medium
      vmImage:
        project: cloud-notebooks-managed
        imageFamily: workbench-instances
      instanceOwners:
        - my@service-account.com
      serviceAccount: my@service-account.com
      installGpuDriver: true
      bootDiskType: PD_SSD
      bootDiskSizeGb: 150
      noPublicIp: true
      noProxyAccess: true
      network: ${myNetwork.id}
      subnet: ${mySubnetwork.id}
      labels:
        k: val
      metadata:
        terraform: 'true'
      serviceAccountScopes:
        - https://www.googleapis.com/auth/bigquery
        - https://www.googleapis.com/auth/devstorage.read_write
        - https://www.googleapis.com/auth/cloud-platform
        - https://www.googleapis.com/auth/userinfo.email
      tags:
        - foo
        - bar
      diskEncryption: CMEK
      kmsKey: my-crypto-key
      desiredState: ACTIVE
variables:
  myNetwork:
    fn::invoke:
      function: gcp:compute:getNetwork
      arguments:
        name: default
  mySubnetwork:
    fn::invoke:
      function: gcp:compute:getSubnetwork
      arguments:
        name: default
        region: us-central1

The network and subnet properties place the instance in a specific VPC. Setting noPublicIp to true prevents external access. The diskEncryption property enables customer-managed encryption keys (CMEK), with kmsKey pointing to your KMS key. The serviceAccount and instanceOwners properties control who can access and use the instance.

Beyond these examples

These snippets focus on specific notebook instance features: VM and container image deployment, GPU acceleration and driver installation, and private networking and encryption. They’re intentionally minimal rather than full data science environments.

The examples may reference pre-existing infrastructure such as VPC networks and subnets, KMS encryption keys, and service accounts with appropriate IAM permissions. They focus on configuring the notebook instance rather than provisioning the surrounding infrastructure.

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

  • Startup scripts and post-boot automation (postStartupScript)
  • Disk sizing and type selection (bootDiskSizeGb, dataDiskSizeGb)
  • Shielded VM configuration (shieldedInstanceConfig)
  • Reservation affinity for committed use discounts

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

Let's deploy GCP Notebook Instances

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Migration & Deprecation
Should I use this resource for new projects?
No, gcp.notebooks.Instance is deprecated and will be removed in a future release. Use gcp.workbench.Instance instead for new projects.
Resource Lifecycle & State
Why aren't my configuration changes being detected?
The Notebooks Instance API has limitations that prevent proper drift detection for many fields. These fields also won’t appear in state once imported.
What properties can't I change after creating the instance?
Most properties are immutable, including location, machineType, network, subnet, diskEncryption, acceleratorConfig, vmImage, containerImage, serviceAccount, installGpuDriver, and many others. Changing these requires replacing the instance.
How do I stop or start my notebook instance?
Set desiredState to STOPPED to stop the instance or ACTIVE to start it.
What happens to my data disk when I delete the instance?
By default, the data disk is auto-deleted. Set noRemoveDataDisk to true to preserve it.
Instance Configuration
What's the difference between vmImage and containerImage?
You can start an instance with either a Compute Engine VM image (vmImage with project and imageFamily) or a container image (containerImage with repository and tag). These options are mutually exclusive.
How do I add GPU support to my instance?
Configure acceleratorConfig with the GPU type and coreCount, and set installGpuDriver to true. Ensure your machineType has enough vCPUs and memory to support the GPU.
What are the disk size limits for notebook instances?
Both bootDiskSizeGb and dataDiskSizeGb default to 100 GB and support a maximum of 64000 GB (64 TB). The minimum recommended boot disk size is 100 GB.
How do I use customer-managed encryption keys?
Set diskEncryption to CMEK and provide a kmsKey in the format projects/{project_id}/locations/{location}/keyRings/{key_ring_id}/cryptoKeys/{key_id}. The default is GMEK (Google-managed encryption).
Security & Access
What service account is used if I don't specify one?
The Compute Engine default service account is used. Default scopes include cloud-platform and userinfo.email.
Troubleshooting
Why is proxyUri empty after creating my instance?
The proxyUri is only available when the instance is in a PROVISIONED state. You may need to run pulumi up -refresh-only to populate this value.
Why don't all my labels show up in the labels field?
The labels field is non-authoritative and only manages labels in your configuration. Use effectiveLabels to see all labels present on the resource, including those set by other clients.

Using a different cloud?

Explore analytics guides for other cloud providers: