Create a secure user-managed notebooks instance in a VPC network

Vertex AI Workbench user-managed notebooks isdeprecated. On April 14, 2025, support for user-managed notebooks ended and the ability to create user-managed notebooks instances was removed. Existing instances will continue to function until March 30, 2026, but patches, updates, and upgrades won't be available. To continue using Vertex AI Workbench, we recommend that youmigrate your user-managed notebooks instances to Vertex AI Workbench instances.

This tutorial is intended for enterprise data scientists, researchers, andnetwork administrators. It shows how to secure auser-managed notebooks instance by creating itin a Virtual Private Cloud (VPC) network.

AVPC network is a virtual version ofa physical network that isimplemented inside of Google's production network. It is a private network,with its own private IP addresses, subnets, and network gateways.In the enterprise, VPC networks are used to protectdata and instances by controlling access tothem from other networks and from the internet.

The VPC network in this tutorial is a standalone network.However, you can share a VPC network from one project(called a host project) to other projects in your Google Cloud organization.To learn more about which type of VPC network to use, seeSingle VPC network and Shared VPC.

Following network security best practices,the VPCnetwork in this tutorial uses a combination ofCloud Router,Cloud NAT, andPrivate Google Accessto secure the instance in the following ways:

  • The user-managed notebooks instance doesn't have an externalIP address.
  • The instance has outbound internet access through a regional Cloud Routerand Cloud NAT gatewayso that you can install software packages or other dependencies.Cloud NAT allows outbound connections and the inbound responses to thoseconnections. It doesnot permit unsolicited inbound requests from theinternet.
  • The instance uses Private Google Access to reach the external IP addressesof Google APIs and services.

The tutorial also shows how to do the following:

  • Create a post-startup script to automatically clone a GitHub repo into thenewly created user-managed notebooks instance.
  • UseCloud Monitoringto monitor the user-managed notebooks instance.
  • Use theCompute EngineAPI to start and stop the instance automatically to optimize costs.

Architectural diagram of a user-managed notebook instance in a VPC network.

Objectives

  • Create a VPC network and add a subnet that has Private Google Accessenabled.
  • Create a Cloud Router and Cloud NAT for the VPC network.
  • Create a user-managed notebooks instance in the subnet, usinga post-startup script that clones theGoogle Cloud Generative AIGitHub repository.
  • Enable Cloud Monitoring for the instance.
  • Create a VM instance schedule and attach it to the instance.

Costs

In this document, you use the following billable components of Google Cloud:

To generate a cost estimate based on your projected usage, use thepricing calculator.

New Google Cloud users might be eligible for afree trial.

When you finish the tasks that are described in this document, you can avoid continued billing by deleting the resources that you created. For more information, seeClean up.

Before you begin

  1. In the Google Cloud console, go to the project selector page.

    Go to project selector

  2. Select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.create permission.Learn how to grant roles.
  3. Verify that billing is enabled for your Google Cloud project.

  4. OpenCloud Shell to execute the commands listed in this tutorial. Cloud Shell is an interactive shell environment for Google Cloud that lets you manage your projects and resources from your web browser.
  5. Go to Cloud Shell
  6. In the Cloud Shell, set the current project to your Google Cloud project ID and store the same project ID into theprojectid shell variable:
    projectid="PROJECT_ID"gcloudconfigsetproject${projectid}
    ReplacePROJECT_ID with your project ID. If necessary, you can locate your project ID in the Google Cloud console. For more information, seeFind your project ID.
  7. Enable the IAM, Compute Engine, Notebooks, Cloud Storage, and Vertex AI APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enable permission.Learn how to grant roles.

    Enable the APIs

  8. Make sure that you have the following role or roles on the project: roles/compute.networkAdmin, roles/compute.securityAdmin, roles/compute.instanceAdmin, roles/notebooks.admin, roles/resourcemanager.projectIamAdmin, roles/iam.serviceAccountAdmin, roles/iam.serviceAccountUser, roles/storage.Admin

    Check for the roles

    1. In the Google Cloud console, go to theIAM page.

      Go to IAM
    2. Select the project.
    3. In thePrincipal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.

    4. For all rows that specify or include you, check theRole column to see whether the list of roles includes the required roles.

    Grant the roles

    1. In the Google Cloud console, go to theIAM page.

      Go to IAM
    2. Select the project.
    3. ClickGrant access.
    4. In theNew principals field, enter your user identifier. This is typically the email address for a Google Account.

    5. In theSelect a role list, select a role.
    6. To grant additional roles, clickAdd another role and add each additional role.
    7. ClickSave.

Create and configure a standalone VPC

  1. Create a VPC network namedsecurevertex-vpc:

    gcloud compute networks create securevertex-vpc --subnet-mode=custom
  2. Create a subnet namedsecurevertex-subnet-a, with a primary IPv4 range of10.10.10.0/29:

    gcloudcomputenetworkssubnetscreatesecurevertex-subnet-a--range=10.10.10.0/29--network=securevertex-vpc--region=us-central1--enable-private-ip-google-access

    If desired, you can supply a different value for the--range parameter.However, the minimum prefix length for a single notebook is 29.For more information,seeIPv4 subnet ranges.

  3. Create a regional Cloud Router namedcloud-router-us-central1:

    gcloudcomputerouterscreatecloud-router-us-central1--networksecurevertex-vpc--regionus-central1
  4. Create a regional Cloud NAT gateway namedcloud-nat-us-central1:

    gcloudcomputeroutersnatscreatecloud-nat-us-central1--router=cloud-router-us-central1--auto-allocate-nat-external-ips--nat-all-subnet-ip-ranges--regionus-central1

Create a Cloud Storage bucket

  1. Create the Cloud Storage bucket:

    gcloud storage buckets create --location=us-central1 --uniform-bucket-level-access gs://BUCKET_NAME

    ReplaceBUCKET_NAME with a unique bucket name.

  2. Set theBUCKET_NAME shell variable and verify that it wasentered correctly:

    BUCKET_NAME=BUCKET_NAMEecho $BUCKET_NAME

    ReplaceBUCKET_NAME with the bucket name.

Create and upload a post-startup script

  1. To create the script, use a text editor such asviornano to create a file namedpoststartup.sh.

  2. Paste the following shell script into the file:

    #! /bin/bashecho"Current user: id" >>/tmp/notebook_config.log2>&1echo"Changing dir to /home/jupyter" >>/tmp/notebook_config.log2>&1cd/home/jupyterecho"Cloning generative-ai from github" >>/tmp/notebook_config.log2>&1su-jupyter-c"git clone https://github.com/GoogleCloudPlatform/generative-ai.git" >>/tmp/notebook_config.log2>&1echo"Current user: id" >>/tmp/notebook_config.log2>&1echo"Installing python packages" >>/tmp/notebook_config.log2&1su-jupyter-c"pip install --upgrade --no-warn-conflicts --no-warn-script-location --user \     google-cloud-bigquery \     google-cloud-pipeline-components \     google-cloud-aiplatform \     seaborn \     kfp" >>/tmp/notebook_config.log2>&1
  3. Save the file.

  4. Upload the file to your Cloud Storage bucket:

    gcloud storage cp poststartup.sh gs://$BUCKET_NAME

Create a custom service account

When you create a user-managed notebooks instance, we stronglyrecommend that you clear theUse Compute Engine default service accountcheckbox and specify a custom service account. If your organization doesn'tenforce theiam.automaticIamGrantsForDefaultServiceAccountsorganization policy constraint, the Compute Engine default service account(and thus anyone you specify as an instance user) is granted the Editor role(roles/editor) on your project. To turn off this behavior,seeDisable automatic role grants to default serviceaccounts.

  1. Create a custom service account nameduser-managed-notebook-sa:

    gcloud iam service-accounts create user-managed-notebook-sa \--display-name="user-managed-notebook-sa"
  2. Assign the Storage Object Viewer IAM role to the serviceaccount:

    gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:user-managed-notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/storage.objectViewer"
  3. Assign the Vertex AI User IAM role to the serviceaccount:

    gcloud projects add-iam-policy-binding $projectid --member="serviceAccount:user-managed-notebook-sa@$projectid.iam.gserviceaccount.com" --role="roles/aiplatform.user"

Create a user-managed notebooks instance

  1. In the Google Cloud console, go to theUser-managed notebooks page.

    Go to User-managed notebooks

  2. Click Create new,and then selectAdvanced Options.

    TheCreate instance page opens.

  3. On theCreate instance page,in theDetails section, provide the following information for your newinstance and then clickContinue:

    • Name: Provide a name for your new instance, or accept the default.
    • Region: Selectus-central1.
    • Zone: Selectus-central1-a.
  4. In theEnvironment section, provide the following and then clickContinue:

    • Post-startup script: ClickBrowse, double-click thepoststartup.sh file, click it one more time, andthen clickSelect.
  5. In theMachine type section, provide the following and then clickContinue:

    • Shielded VM: Select the following checkboxes:

      • Secure Boot
      • Virtual Trusted Platform Module (vTPM)
      • Integrity monitoring
  6. In theDisks section, make sure thatGoogle-managed encryption keyis selected, and then clickContinue:

  7. In theNetworking section, provide the following and then clickContinue:

    • Networking: SelectNetwork in this project and complete thefollowing steps:

      1. In theNetwork field, selectsecurevertex-vpc.

      2. In theSubnetwork field, selectsecurevertex-subnet-a.

      3. Clear theAssign external IP address checkbox. Not assigningan external IP address preventsthe instance from receiving unsolicited communication from theinternet or other VPC networks.

      4. Select theAllow proxy access checkbox.

  8. In theIAM and security section, provide the following and then clickContinue:

    • IAM and security: To grant a single user access to the instance'sJupyterLab interface, complete the following steps:

      1. SelectSingle user.
      2. In theUser email field, enter the email address for a singleuser account. If you're creating the instance for someone else,the following conditions apply:
        • You (the instance creator) don't have access to the instance'sJupyterLab interface. But you still control the instance, andyou can start, stop, or delete it.
        • After you create the instance, you need to grant the user theService Account User role(roles/iam.serviceAccountUser) on the instance's serviceaccount. SeeOptional: Grant the Service Account User role to the instance user.
      3. Clear theUse Compute Engine default service account checkbox.This step is important, because the Compute Engine defaultservice account (and thus the single user you just specified)could have the Editor role (roles/editor) on your project.
      4. In theService account email field, enteruser-managed-notebook-sa@$projectid.iam.gserviceaccount.com.(This is the custom serviceaccount email address that you created earlier.) This serviceaccount has limited permissions.

        To learn more about granting access, seeManage access to a user-managed notebooks instance's JupyterLab interface.

    • Security options: Clear the following checkbox:

      • Root access to the instance

      Select the following checkbox:

      • nbconvertnbconvertlets users export and download a notebook file as a different filetype, such as HTML, PDF, or LaTeX. This setting is required by some ofthe notebooks in theGoogle Cloud Generative AIGitHub repo.

      Clear the following checkbox:

      • File downloading

      Select the following checkbox, unless you're in a production environment:

      • Terminal accessThis enables terminal access to your instance from within theJupyterLab user interface.
  9. In theSystem health section, selectEnvironment auto-upgrade andprovide the following:

    • InReporting, select the following checkboxes:

      • Report system health
      • Report custom metrics to Cloud Monitoring
      • Install Cloud Monitoring
      • Report DNS status for required Google domains
  10. ClickCreate.

Optional: Grant the Service Account User role to the instance user

If you're creating the user-managed notebooksinstance for another user,you must grant them theService Account User role(roles/iam.serviceAccountUser) on theuser-managed-notebook-sacustom service account as follows:

gcloudiamservice-accountsadd-iam-policy-binding\user-managed-notebook-sa@PROJECT_ID.iam.gserviceaccount.com\--member="user:USER_EMAIL"\--role="roles/iam.serviceAccountUser"

Replace the following values:

  • PROJECT_ID: the project ID
  • USER_EMAIL: the email address for the user

Verify that the user-managed notebooks instance was created

Vertex AI Workbench creates a user-managed notebooksinstance based on your specified properties and automatically starts theinstance.

When the instance is ready to use, Vertex AI Workbenchactivates anOpen JupyterLab link. This link is accessible only tothe single user that you specified at instance creation time.

Open the instance in JupyterLab and verify that the clonedGoogle Cloud Generative AIGitHub repo is present.

  1. In the Google Cloud console, go to theUser-managed notebooks page.

    Go to User-managed notebooks

  2. In the list of user-managed notebooks instances,click theOpen JupyterLablink for the instance you created.

    In the folder list, you'll see agenerative-ai folder. Thisfolder contains the cloned GitHub repo.

Monitor health status through Monitoring

You can monitor the system and application metrics for youruser-managed notebooks instances by using theGoogle Cloud console. To learn more about instance monitoring andabout creating custom metrics, seeMonitor health status.

  1. In the Google Cloud console, go to theUser-managed notebooks page.

    Go to User-managed notebooks

  2. Click the name of the user-managed notebooks instancethat you want to view the metrics for.

  3. On theNotebook details page, click theMonitoring tab. ReviewtheCPU Utilization andNetwork Bytes for your notebook instance.To learn how to interpret these metrics, seeReview resource metrics.

    If you just created the instance, you won't see any data right away. Wait afew minutes and refresh the console tab.

Create a VM instance schedule for your user-managed notebooks instance

Because a user-managed notebooks instanceis a Compute Engine VM instance, you can use Compute Engine APIsto create a VM instance schedule for it.

Use a VM instance schedule to start and stop youruser-managed notebooks instance. During the hours when theinstance is stopped, you pay only for Cloud Storage costs.

You can attach an instance schedule to any VM instance that'sin the same region, so you can use the same instanceschedule to control all your user-managed notebooks instancesin the region.

To learn more about VM instance schedules, seeScheduling a VM instance to start and stop.

Create a custom IAM role

As a security best practice, we recommend creating a custom IAMrole that has only the following permissions andassigning it to the Compute Engine default service account:

  • compute.instances.start
  • compute.instances.stop
  1. Inside Cloud Shell, create a custom role namedVm_Scheduler and includethe necessary permissions:

    Go to Cloud Shell

    gcloud iam roles create Vm_Scheduler --project=$projectid \--title=vm-scheduler-notebooks \--permissions="compute.instances.start,compute.instances.stop" --stage=ga
  2. Describe the custom role:

    gcloud iam roles describe Vm_Scheduler --project=$projectid

Assign the role to the Compute Engine default service account

To give the Compute Engine default serviceaccount permission to start and stop youruser-managed notebooks instances, you need to assign theVm_Scheduler custom role to it.

The Compute Engine default service account for your projecthas the followingemail address:PROJECT_NUMBER-compute@developer.gserviceaccount.com,wherePROJECT_NUMBER is your project number.

  1. Identify your project number and store it in theproject_number shellvariable:

    project_number=$(gcloud projects describe $projectid --format 'get(projectNumber)')echo $project_number
  2. Assign the custom role to the default service account:

    gcloudprojectsadd-iam-policy-binding$projectid--member="serviceAccount:$project_number-compute@developer.gserviceaccount.com"--role="projects/$projectid/roles/Vm_Scheduler"

Create and attach the schedule

To create an instance schedule that starts youruser-managed notebooks instance at 7 AM andstops them at 6 PM:

  1. Create a start and stop schedule namedoptimize-notebooks:

    gcloudcomputeresource-policiescreateinstance-scheduleoptimize-notebooks\--region=us-central1\--vm-start-schedule='07***'\--vm-stop-schedule='018***'\--timezone=TIME_ZONE

    ReplaceTIME_ZONE with the location-basedIANA time zone for this instance schedule, for example,America/Chicago. If omitted, the default valueUTC is used. For more information, seetime zone.

  2. Identify the name of your user-managed notebooks instanceby running the followingcommand and noting theNAME value that it returns:

    gcloud compute instances list
  3. Store the name in thenotebook_vm shell variable:

    notebook_vm=NOTEBOOK_VM_NAMEecho $notebook_vm

    ReplaceNOTEBOOK_VM_NAME with youruser-managed notebooks instance name.

  4. Attach the instance schedule to youruser-managed notebooks instance:

    gcloud compute instances add-resource-policies $notebook_vm \  --resource-policies=optimize-notebooks \  --zone=us-central1-a
  5. Describe the instance schedule:

    gcloudcomputeresource-policiesdescribeoptimize-notebooks\--region=us-central1

You can verify if the instance schedule runs successfully by checking theCompute Engine audit logs forthe instance schedule resource policy and the attached VM instance.You might need to wait for up to 15 minutes after the scheduled timefor each operation.

Clean up

To avoid incurring charges to your Google Cloud account for the resources usedin this tutorial, eitherdelete the projectthat contains the resources, or keep the project and delete the individualresources.

You can delete the individual resources in the project as follows:

  1. In the Google Cloud console, go to theUser-managed notebooks page.

    Go to User-managed notebooks

  2. Select your user-managed notebook instance.

  3. ClickDelete.

  4. In the Cloud Shell, delete the remaining individual resources byexecuting the following commands.

    Go to Cloud Shell

    gcloudcomputeroutersdeletecloud-router-us-central1--region=us-central1--quietgcloudcomputeroutersnatsdeletecloud-nat-us-central1--region=us-central1--router=cloud-router-us-central1--quietgcloudcomputeinstancesremove-resource-policies$notebook_vm\--resource-policies=optimize-notebooks\--zone=us-central1-a--quietgcloudcomputeresource-policiesdeleteoptimize-notebooks--region=us-central1--quietgcloudcomputeinstancesdelete$notebook_vm--zone=us-central1-a--quietgcloudcomputenetworkssubnetsdeletesecurevertex-subnet-a--region=us-central1--quietgcloudiamservice-accountsdeleteuser-managed-notebook-sa@$projectid.iam.gserviceaccount.com--quietgcloudprojectsremove-iam-policy-binding$projectid--member="serviceAccount:$project_number-compute@developer.gserviceaccount.com"--role="projects/$projectid/roles/Vm_Scheduler"gcloudiamrolesdeleteVm_Scheduler--project=$projectidgcloudcomputenetworksdeletesecurevertex-vpc--quiet

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-15 UTC.