Skip to content

Week 2 Day 1-2: VPC Service Controls

Prerequisites: Create Access Policy

# Check if Access Policy exists at organization level

export ORG_ID="123456789012"  # Your organization ID

gcloud access-context-manager policies list \
  --organization=$ORG_ID

## If no policy exists, create one

gcloud access-context-manager policies create \
  --organization=$ORG_ID \
  --title="Abhavtech Access Policy"

## Get policy name

export ACCESS_POLICY=$(gcloud access-context-manager policies list \
  --organization=$ORG_ID \
  --format="value(name)")

echo "export ACCESS_POLICY=$ACCESS_POLICY" >> ~/.bashrc

Terraform Module: VPC Service Controls

File: terraform/06-vpc-sc/main.tf

terraform {
  required_version = ">= 1.5.0"
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 5.0"
    }
  }
}

provider "google" {
  project = var.project_id
}

## Access Level: Trusted Source IPs

resource "google_access_context_manager_access_level" "trusted_sources" {
  parent = "accessPolicies/${var.access_policy_name}"
  name   = "accessPolicies/${var.access_policy_name}/accessLevels/wxcc_trusted_sources"
  title  = "WxCC Trusted Source IPs"

  basic {
    conditions {
      ip_subnetworks = concat(
        var.wxcc_ip_ranges,
        [
          "${var.mumbai_nat_ip}/32",
          "${var.london_nat_ip}/32",
          "${var.nj_nat_ip}/32"
        ]
      )
    }
  }
}

## Service Perimeter: WxCC Production

resource "google_access_context_manager_service_perimeter" "wxcc_perimeter" {
  parent = "accessPolicies/${var.access_policy_name}"
  name   = "accessPolicies/${var.access_policy_name}/servicePerimeters/wxcc_production"
  title  = "WxCC Production Data Perimeter"

  status {
    restricted_services = [
      "aiplatform.googleapis.com",
      "bigquery.googleapis.com",
      "storage.googleapis.com",
      "speech.googleapis.com",
      "language.googleapis.com",
      "dlp.googleapis.com"
    ]

    resources = ["projects/${var.project_number}"]

## INGRESS: Allow from trusted sources

    ingress_policies {
      ingress_from {
        sources {
          access_level = google_access_context_manager_access_level.trusted_sources.name
        }
        identity_type = "ANY_IDENTITY"
      }

      ingress_to {
        resources = ["*"]
        operations {
          service_name = "*"
          method_selectors {
            method = "*"
          }
        }
      }
    }

## EGRESS: Allow to authorized destinations

    egress_policies {
      egress_from {
        identities = [
          "serviceAccount:${var.vertex_ai_sa_email}",
          "serviceAccount:${var.cloud_functions_sa_email}"
        ]
      }

      egress_to {
        resources = ["*"]
        operations {
          service_name = "*"
          method_selectors {
            method = "*"
          }
        }
      }
    }

    vpc_accessible_services {
      enable_restriction = true
      allowed_services = [
        "aiplatform.googleapis.com",
        "bigquery.googleapis.com",
        "storage.googleapis.com",
        "speech.googleapis.com",
        "language.googleapis.com",
        "dlp.googleapis.com",
        "pubsub.googleapis.com"
      ]
    }
  }
}

Deployment

cd ~/gcp-wxcc-deployment/terraform/06-vpc-sc
terraform init
terraform plan -out=tfplan
terraform apply tfplan

## Verify perimeter

gcloud access-context-manager perimeters list \
  --policy=$ACCESS_POLICY

## Test access (should work from allowed IPs)

gcloud ai-platform models list --region=us-east4 --project=$PROJECT_ID

Week 2 Day 3: Cloud DLP Configuration

Python Script: DLP Templates

File: scripts/dlp_setup.py

#!/usr/bin/env python3

"""Configure Cloud DLP templates for PII detection and redaction"""

from google.cloud import dlp_v2
import os
import sys

PROJECT_ID = os.environ.get('GCP_PROJECT_ID')

def create_inspect_template():
    """Create DLP inspect template"""
    dlp = dlp_v2.DlpServiceClient()
    parent = f"projects/{PROJECT_ID}"

    inspect_config = {
        "info_types": [
            {"name": "PERSON_NAME"},
            {"name": "PHONE_NUMBER"},
            {"name": "EMAIL_ADDRESS"},
            {"name": "CREDIT_CARD_NUMBER"},
            {"name": "US_SOCIAL_SECURITY_NUMBER"},
            {"name": "STREET_ADDRESS"},
            {"name": "DATE_OF_BIRTH"}
        ],
        "min_likelihood": "POSSIBLE",
        "limits": {"max_findings_per_request": 0},
        "include_quote": True
    }

    template = {
        "inspect_config": inspect_config,
        "display_name": "WxCC PII Detection",
        "description": "Detect PII in call transcripts"
    }

    try:
        response = dlp.create_inspect_template(
            request={
                "parent": parent,
                "inspect_template": template,
                "template_id": "wxcc-pii-detection"
            }
        )
        print(f"✅ Created inspect template: {response.name}")
        return response.name
    except Exception as e:
        if "already exists" in str(e):
            print("⚠️  Template already exists")
            return f"{parent}/inspectTemplates/wxcc-pii-detection"
        raise

def create_deidentify_template():
    """Create DLP de-identify template"""
    dlp = dlp_v2.DlpServiceClient()
    parent = f"projects/{PROJECT_ID}"

    deidentify_config = {
        "info_type_transformations": {
            "transformations": [
                {
                    "info_types": [{"name": "CREDIT_CARD_NUMBER"}],
                    "primitive_transformation": {
                        "replace_config": {
                            "new_value": {"string_value": "[CREDIT_CARD]"}
                        }
                    }
                },
                {
                    "info_types": [{"name": "US_SOCIAL_SECURITY_NUMBER"}],
                    "primitive_transformation": {
                        "replace_config": {
                            "new_value": {"string_value": "[SSN]"}
                        }
                    }
                },
                {
                    "primitive_transformation": {
                        "replace_with_info_type_config": {}
                    }
                }
            ]
        }
    }

    template = {
        "deidentify_config": deidentify_config,
        "display_name": "WxCC PII Redaction",
        "description": "Redact PII in call transcripts"
    }

    try:
        response = dlp.create_deidentify_template(
            request={
                "parent": parent,
                "deidentify_template": template,
                "template_id": "wxcc-pii-redaction"
            }
        )
        print(f"✅ Created de-identify template: {response.name}")
        return response.name
    except Exception as e:
        if "already exists" in str(e):
            print("⚠️  Template already exists")
            return f"{parent}/deidentifyTemplates/wxcc-pii-redaction"
        raise

if __name__ == "__main__":
    print("🔧 Configuring Cloud DLP...")
    inspect_tmpl = create_inspect_template()
    deidentify_tmpl = create_deidentify_template()
    print(f"\n✅ Configuration Complete")
    print(f"   Inspect: {inspect_tmpl}")
    print(f"   De-identify: {deidentify_tmpl}")

Deployment

cd ~/gcp-wxcc-deployment/scripts
chmod +x dlp_setup.py
python3 dlp_setup.py

## Verify templates

gcloud dlp inspect-templates list --project=$PROJECT_ID
gcloud dlp deidentify-templates list --project=$PROJECT_ID

Week 3: Vertex AI Platform Deployment