> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ensure that vTPM feature is enabled for your Vertex AI notebook instances

### More Info:

Ensure that vTPM feature is enabled for your Vertex AI notebook instances

### Risk Level

Medium

### Address

Security

### Compliance Standards

* CIS GCP

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are the console steps to ensure vTPM is enabled for Vertex AI notebook instances. vTPM is a Shielded VM feature; for many notebook types this is only settable at creation time, so you may need to recreate the instance.

        ***

        ### 1. Check whether vTPM is already enabled

        1. Go to **Vertex AI Workbench**
           * In the Google Cloud console, open:\
             `Navigation menu → Vertex AI → Workbench`
        2. Identify your notebook:
           * You’ll see **User-managed notebooks** and/or **Managed notebooks** tabs.
        3. Open the instance details:
           * Click the notebook name → in the details pane, look for **Shielded VM** or **Security** info.
           * If the instance indicates **vTPM** (or “Shielded VM with vTPM / integrity monitoring”) is enabled, no further action is needed.
           * If not visible or disabled, plan to recreate the notebook with vTPM on.

        > For existing Workbench instances, Shielded VM/vTPM settings generally **cannot be changed in place**. You must create a new notebook instance with vTPM enabled.

        ***

        ### 2. Create a new Vertex AI notebook with vTPM enabled

        #### A. Managed notebooks

        1. In the console, go to\
           **Navigation menu → Vertex AI → Workbench → Managed notebooks**.
        2. Click **New notebook** (or **Create notebook**) and choose the image/type you need.
        3. In the creation page, expand **Environment**, then **Advanced options** or **Security** (the naming can differ slightly):
           * Look for **Shielded VM** options.
        4. Enable:
           * **Turn on vTPM** (or **Virtual Trusted Platform Module (vTPM)**).
           * Optionally also enable **Integrity monitoring** (recommended).
        5. Configure other settings (machine type, region, disk, etc.).
        6. Click **Create**.

        Once created, the managed notebook VM will have vTPM enabled.

        ***

        #### B. User-managed notebooks

        1. In the console, go to\
           **Navigation menu → Vertex AI → Workbench → User-managed notebooks**.
        2. Click **New notebook** → select the image/framework and region/zone.
        3. On the creation page, expand **Machine configuration** or **Security** / **Shielded VM** section:
           * Check the box for **Enable Shielded VM options** if present.
           * Enable **vTPM** (sometimes presented as “Turn on vTPM”).
           * Optionally enable **Integrity monitoring**.
        4. Finish configuring instance details and click **Create**.

        ***

        ### 3. Migrate data / notebooks from old instance (if needed)

        1. Start both the **old** and **new** notebook instances.
        2. From JupyterLab (or SSH), copy:
           * Notebook files (`.ipynb`), scripts, and data from the old instance to:
             * A Cloud Storage bucket, or
             * Directly to the new instance using `gsutil`, `scp`, or Jupyter file upload.
        3. Once migration is confirmed, you can delete the old notebook instance.

        ***

        These steps ensure that your Vertex AI Workbench notebook instances are created with vTPM enabled via the GCP console.
      </Accordion>

      <Accordion title="Using CLI">
        In Vertex AI Workbench, vTPM is controlled by the **Shielded VM** settings of the notebook instance. You cannot toggle vTPM on/off for an existing notebook; you must create (or recreate) the instance with vTPM enabled.

        Below are CLI steps for both **User‑managed** and **Managed** notebooks.

        ***

        ## 1. Identify notebook instances missing vTPM

        List all Workbench instances in a region:

        ```bash theme={null}
        PROJECT_ID=your-project-id
        REGION=us-central1

        gcloud config set project $PROJECT_ID

        gcloud notebooks instances list \
          --location=$REGION
        ```

        To inspect a specific instance’s Shielded VM config:

        ```bash theme={null}
        INSTANCE_ID=your-notebook-id

        gcloud notebooks instances describe $INSTANCE_ID \
          --location=$REGION \
          --format="yaml|shieldedInstanceConfig"
        ```

        If `enableVtpm: true` is not present, vTPM is not enabled.

        ***

        ## 2. Recreate a **User‑managed** notebook with vTPM enabled

        1. Stop and delete the old instance (do **not** delete attached disks you need):

        ```bash theme={null}
        INSTANCE_ID=old-notebook
        REGION=us-central1

        gcloud notebooks instances stop $INSTANCE_ID --location=$REGION

        gcloud notebooks instances delete $INSTANCE_ID \
          --location=$REGION \
          --quiet
        ```

        2. Recreate a new instance with Shielded VM + vTPM:

        ```bash theme={null}
        NEW_INSTANCE_ID=new-notebook
        MACHINE_TYPE=e2-standard-4
        VM_IMAGE_PROJECT=deeplearning-platform-release
        VM_IMAGE_FAMILY=common-cpu-notebooks

        gcloud notebooks instances create $NEW_INSTANCE_ID \
          --location=$REGION \
          --machine-type=$MACHINE_TYPE \
          --vm-image-project=$VM_IMAGE_PROJECT \
          --vm-image-family=$VM_IMAGE_FAMILY \
          --shielded-secure-boot \
          --shielded-vtpm \
          --shielded-integrity-monitoring
        ```

        Key flag: `--shielded-vtpm` (enables vTPM).

        If you have an existing persistent disk you want to attach, use the relevant `--boot-disk-*` flags when creating the instance (or recreate using the same config as the previous instance).

        ***

        ## 3. Recreate a **Managed** notebook with vTPM enabled

        Managed notebooks are also backed by Shielded VMs; you must create them with vTPM:

        ```bash theme={null}
        NEW_INSTANCE_ID=new-managed-notebook
        REGION=us-central1
        MACHINE_TYPE=e2-standard-4

        gcloud notebooks instances create $NEW_INSTANCE_ID \
          --location=$REGION \
          --vm-image-project=deeplearning-platform-release \
          --vm-image-family=common-cpu-notebooks \
          --machine-type=$MACHINE_TYPE \
          --instance-owners=$(gcloud auth list --filter=status:ACTIVE --format="value(account)") \
          --shielded-secure-boot \
          --shielded-vtpm \
          --shielded-integrity-monitoring
        ```

        Migrate your notebooks/code from the old managed instance to the new one, then delete the old instance.

        ***

        If you share the output of `gcloud notebooks instances describe` for one of your current instances, I can give an exact `gcloud notebooks instances create` command matching its configuration but with vTPM enabled.
      </Accordion>

      <Accordion title="Using Python">
        Below are concrete steps and a Python example to enable vTPM (Shielded VM) on Vertex AI Workbench (Vertex AI Notebooks) instances.

        Assumptions:

        * You’re using **Vertex AI Workbench user-managed or managed notebooks** (Notebooks API).
        * You have `roles/notebooks.admin` (or equivalent) and appropriate project permissions.
        * `gcloud auth application-default login` has been run or you’re running in a GCP environment with a service account.

        ***

        ## 1. Install and import the Notebooks client library

        ```bash theme={null}
        pip install google-cloud-notebooks
        ```

        ```python theme={null}
        from google.cloud import notebooks_v1
        from google.api_core.operation import Operation
        ```

        ***

        ## 2. Helper: wait for long‑running operations

        ```python theme={null}
        def wait_for_op(op: Operation, desc: str = ""):
            print(f"Waiting for operation: {desc} ...")
            result = op.result()  # blocks until done
            print(f"Operation finished: {desc}")
            return result
        ```

        ***

        ## 3. Stop the instance (must be TERMINATED to change Shielded settings)

        ```python theme={null}
        def stop_notebook_instance(project_id: str, location: str, instance_id: str):
            client = notebooks_v1.NotebookServiceClient()
            name = client.instance_path(project_id, location, instance_id)
            op = client.stop_instance(name=name)
            wait_for_op(op, f"Stop instance {instance_id}")
        ```

        ***

        ## 4. Patch the instance to enable vTPM

        For Vertex AI Workbench **(Notebooks API)**, the Shielded VM config is under `gce_setup.shielded_instance_config` for Workbench instances, or `vm_image`/`container_image` for older ones. The common field in the Notebooks API is:

        * `gce_setup.shielded_instance_config.enable_vtpm`

        ```python theme={null}
        def enable_vtpm(project_id: str, location: str, instance_id: str):
            client = notebooks_v1.NotebookServiceClient()
            name = client.instance_path(project_id, location, instance_id)

            # Build the partial instance with only the field we change
            instance = notebooks_v1.Instance(
                name=name,
                gce_setup=notebooks_v1.GceSetup(
                    shielded_instance_config=notebooks_v1.Instance.ShieldedInstanceConfig(
                        enable_vtpm=True
                    )
                ),
            )

            update_mask = {"paths": ["gce_setup.shielded_instance_config.enable_vtpm"]}

            op = client.patch_instance(
                name=name,
                instance=instance,
                update_mask=update_mask,
            )
            wait_for_op(op, f"Enable vTPM on {instance_id}")
        ```

        If you get an error that `gce_setup` doesn’t exist (older notebook type), the path may instead be:

        ```python theme={null}
        update_mask = {"paths": ["shielded_instance_config.enable_vtpm"]}
        ```

        and you construct:

        ```python theme={null}
        instance = notebooks_v1.Instance(
            name=name,
            shielded_instance_config=notebooks_v1.Instance.ShieldedInstanceConfig(
                enable_vtpm=True
            ),
        )
        ```

        Use the one that matches your instance type (see the error message / object fields from `client.get_instance`).

        ***

        ## 5. Start the instance again

        ```python theme={null}
        def start_notebook_instance(project_id: str, location: str, instance_id: str):
            client = notebooks_v1.NotebookServiceClient()
            name = client.instance_path(project_id, location, instance_id)
            op = client.start_instance(name=name)
            wait_for_op(op, f"Start instance {instance_id}")
        ```

        ***

        ## 6. Full remediation script (single instance)

        ```python theme={null}
        from google.cloud import notebooks_v1

        def wait_for_op(op, desc=""):
            print(f"Waiting for operation: {desc} ...")
            result = op.result()
            print(f"Operation finished: {desc}")
            return result

        def remediate_vtpm_vertex_notebook(project_id: str, location: str, instance_id: str):
            client = notebooks_v1.NotebookServiceClient()
            name = client.instance_path(project_id, location, instance_id)

            # 1) Stop instance
            op = client.stop_instance(name=name)
            wait_for_op(op, f"Stop instance {instance_id}")

            # 2) Enable vTPM (adjust fields/mask if your instance uses a different schema)
            instance = notebooks_v1.Instance(
                name=name,
                gce_setup=notebooks_v1.GceSetup(
                    shielded_instance_config=notebooks_v1.Instance.ShieldedInstanceConfig(
                        enable_vtpm=True
                    )
                ),
            )
            update_mask = {"paths": ["gce_setup.shielded_instance_config.enable_vtpm"]}
            op = client.patch_instance(name=name, instance=instance, update_mask=update_mask)
            wait_for_op(op, f"Enable vTPM on {instance_id}")

            # 3) Start instance
            op = client.start_instance(name=name)
            wait_for_op(op, f"Start instance {instance_id}")

        if __name__ == "__main__":
            PROJECT_ID = "your-project-id"
            LOCATION = "us-central1-b"  # region or zone used by your Workbench instance
            INSTANCE_ID = "your-notebook-instance-name"

            remediate_vtpm_vertex_notebook(PROJECT_ID, LOCATION, INSTANCE_ID)
        ```

        ***

        ## 7. Verification (optional, via Python)

        ```python theme={null}
        def verify_vtpm_enabled(project_id: str, location: str, instance_id: str):
            client = notebooks_v1.NotebookServiceClient()
            name = client.instance_path(project_id, location, instance_id)
            inst = client.get_instance(name=name)
            cfg = inst.gce_setup.shielded_instance_config
            print("vTPM enabled:", cfg.enable_vtpm)

        # verify_vtpm_enabled(PROJECT_ID, LOCATION, INSTANCE_ID)
        ```

        This pattern can be wrapped in a loop to remediate multiple instances.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        resource "google_workbench_instance" "vertex_ai_notebook" {
          name     = "VERTEX_NOTEBOOK_INSTANCE_NAME"  # e.g. "notebook-1"
          location = "REGION"                         # e.g. "us-central1"
          project  = "PROJECT_ID"

          gce_setup {
            machine_type = "MACHINE_TYPE"             # e.g. "e2-standard-4"

            boot_disk {
              disk_type   = "BOOT_DISK_TYPE"          # e.g. "pd-balanced"
              disk_size_gb = BOOT_DISK_SIZE_GB        # e.g. 100
            }

            network_interfaces {
              network    = "NETWORK_SELF_LINK_OR_NAME"
              subnetwork = "SUBNETWORK_SELF_LINK_OR_NAME"
            }

            service_accounts {
              email = "SERVICE_ACCOUNT_EMAIL"
            }

            shielded_instance_config {
              enable_integrity_monitoring = true
              enable_secure_boot          = true
              enable_vtpm                 = true
            }
          }
        }
        ```

        Substitute:

        * `VERTEX_NOTEBOOK_INSTANCE_NAME` with your Vertex AI Workbench instance name.
        * `REGION`, `PROJECT_ID`, `MACHINE_TYPE`, `BOOT_DISK_TYPE`, `BOOT_DISK_SIZE_GB`, `NETWORK_SELF_LINK_OR_NAME`, `SUBNETWORK_SELF_LINK_OR_NAME`, and `SERVICE_ACCOUNT_EMAIL` with your values.

        Changing `shielded_instance_config.enable_vtpm` from `false` to `true` may force replacement of the underlying VM, causing a brief outage when Terraform recreates the instance.

        For verification, `terraform plan` should show `enable_vtpm` changing from `false` (or being added) to `true` in the `shielded_instance_config` of `google_workbench_instance.vertex_ai_notebook` (and, if the provider marks it `ForceNew`, a planned `-/+` replacement of the resource).
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
