Google Cloud Platform Container Security

Google Cloud Platform Container Security

Google Cloud Platform offers Cloud Run for serverless containers and Google Kubernetes Engine (GKE) for managed Kubernetes. GCP's security model emphasizes defense in depth with Binary Authorization, Container Analysis, and GKE Autopilot mode. These services provide comprehensive security capabilities when integrated properly.

Cloud Run security benefits from Google's infrastructure security while simplifying deployment. Automatic TLS termination, IAM integration, and VPC connectivity provide enterprise security features. Binary Authorization ensures only verified images deploy. However, the serverless model limits some traditional security controls. Organizations must understand these constraints when designing security architectures.

# Example: Secure GKE deployment with Terraform
terraform {
  required_version = ">= 1.0"
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 5.0"
    }
    google-beta = {
      source  = "hashicorp/google-beta"
      version = "~> 5.0"
    }
  }
}

variable "project_id" {
  description = "GCP Project ID"
  type        = string
}

variable "region" {
  description = "GCP Region"
  type        = string
  default     = "us-central1"
}

variable "environment" {
  description = "Environment name"
  type        = string
  default     = "production"
}

# Enable required APIs
resource "google_project_service" "required_apis" {
  for_each = toset([
    "container.googleapis.com",
    "compute.googleapis.com",
    "monitoring.googleapis.com",
    "logging.googleapis.com",
    "binaryauthorization.googleapis.com",
    "containeranalysis.googleapis.com",
    "containerscanning.googleapis.com",
    "artifactregistry.googleapis.com"
  ])
  
  project = var.project_id
  service = each.key
}

# Create VPC network
resource "google_compute_network" "gke_network" {
  name                    = "${var.environment}-gke-network"
  project                 = var.project_id
  auto_create_subnetworks = false
}

# Create subnet with secondary ranges
resource "google_compute_subnetwork" "gke_subnet" {
  name          = "${var.environment}-gke-subnet"
  project       = var.project_id
  region        = var.region
  network       = google_compute_network.gke_network.id
  ip_cidr_range = "10.0.0.0/20"
  
  secondary_ip_range {
    range_name    = "pods"
    ip_cidr_range = "10.4.0.0/14"
  }
  
  secondary_ip_range {
    range_name    = "services"
    ip_cidr_range = "10.0.16.0/20"
  }
  
  private_ip_google_access = true
  
  log_config {
    aggregation_interval = "INTERVAL_5_SEC"
    flow_sampling        = 0.5
    metadata             = "INCLUDE_ALL_METADATA"
  }
}

# Create Cloud NAT for private nodes
resource "google_compute_router" "nat_router" {
  name    = "${var.environment}-nat-router"
  project = var.project_id
  region  = var.region
  network = google_compute_network.gke_network.id
}

resource "google_compute_router_nat" "nat_gateway" {
  name                               = "${var.environment}-nat-gateway"
  project                            = var.project_id
  region                             = var.region
  router                             = google_compute_router.nat_router.name
  nat_ip_allocate_option            = "AUTO_ONLY"
  source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
  
  log_config {
    enable = true
    filter = "ERRORS_ONLY"
  }
}

# Create Artifact Registry
resource "google_artifact_registry_repository" "container_registry" {
  provider      = google-beta
  project       = var.project_id
  location      = var.region
  repository_id = "${var.environment}-containers"
  format        = "DOCKER"
  
  cleanup_policies {
    id     = "keep-recent-versions"
    action = "KEEP"
    
    most_recent_versions {
      keep_count = 10
    }
  }
  
  cleanup_policies {
    id     = "delete-old-versions"
    action = "DELETE"
    
    condition {
      older_than = "2592000s" # 30 days
    }
  }
}

# Create service account for GKE nodes
resource "google_service_account" "gke_node_sa" {
  project      = var.project_id
  account_id   = "${var.environment}-gke-node-sa"
  display_name = "GKE Node Service Account"
}

# Grant minimal permissions to node service account
resource "google_project_iam_member" "gke_node_permissions" {
  for_each = toset([
    "roles/logging.logWriter",
    "roles/monitoring.metricWriter",
    "roles/monitoring.viewer",
    "roles/artifactregistry.reader"
  ])
  
  project = var.project_id
  role    = each.key
  member  = "serviceAccount:${google_service_account.gke_node_sa.email}"
}

# Create GKE cluster with security features
resource "google_container_cluster" "secure_cluster" {
  provider = google-beta
  
  name     = "${var.environment}-secure-gke"
  project  = var.project_id
  location = var.region
  
  # Use release channel for automatic upgrades
  release_channel {
    channel = "REGULAR"
  }
  
  # Remove default node pool
  remove_default_node_pool = true
  initial_node_count       = 1
  
  # Network configuration
  network    = google_compute_network.gke_network.name
  subnetwork = google_compute_subnetwork.gke_subnet.name
  
  networking_mode = "VPC_NATIVE"
  ip_allocation_policy {
    cluster_secondary_range_name  = "pods"
    services_secondary_range_name = "services"
  }
  
  # Private cluster configuration
  private_cluster_config {
    enable_private_nodes    = true
    enable_private_endpoint = false
    master_ipv4_cidr_block  = "172.16.0.0/28"
    
    master_global_access_config {
      enabled = true
    }
  }
  
  # Security configurations
  master_auth {
    client_certificate_config {
      issue_client_certificate = false
    }
  }
  
  master_authorized_networks_config {
    cidr_blocks {
      cidr_block   = "10.0.0.0/8"
      display_name = "internal-networks"
    }
    
    gcp_public_cidrs_access_enabled = false
  }
  
  # Enable security features
  enable_shielded_nodes           = true
  enable_binary_authorization     = true
  enable_intranode_visibility     = true
  enable_l4_ilb_subsetting        = true
  
  # Workload Identity
  workload_identity_config {
    workload_pool = "${var.project_id}.svc.id.goog"
  }
  
  # Security posture
  security_posture_config {
    mode               = "ENTERPRISE"
    vulnerability_mode = "VULNERABILITY_ENTERPRISE"
  }
  
  # Cluster addons
  addons_config {
    http_load_balancing {
      disabled = false
    }
    
    horizontal_pod_autoscaling {
      disabled = false
    }
    
    network_policy_config {
      disabled = false
    }
    
    gce_persistent_disk_csi_driver_config {
      enabled = true
    }
    
    config_connector_config {
      enabled = true
    }
    
    gcs_fuse_csi_driver_config {
      enabled = true
    }
  }
  
  # Maintenance window
  maintenance_policy {
    recurring_window {
      start_time = "2023-01-01T00:00:00Z"
      end_time   = "2023-01-01T04:00:00Z"
      recurrence = "FREQ=WEEKLY;BYDAY=SU"
    }
  }
  
  # Logging and monitoring
  cluster_telemetry {
    type = "ENABLED"
  }
  
  logging_config {
    enable_components = [
      "SYSTEM_COMPONENTS",
      "WORKLOADS",
      "APISERVER",
      "CONTROLLER_MANAGER",
      "SCHEDULER"
    ]
  }
  
  monitoring_config {
    enable_components = [
      "SYSTEM_COMPONENTS",
      "WORKLOADS",
      "APISERVER",
      "CONTROLLER_MANAGER",
      "SCHEDULER"
    ]
    
    managed_prometheus {
      enabled = true
    }
  }
  
  # Resource usage export
  resource_usage_export_config {
    enable_network_egress_metering = true
    
    bigquery_destination {
      dataset_id = "${var.environment}_gke_usage"
    }
  }
  
  # Network policy
  network_policy {
    enabled  = true
    provider = "CALICO"
  }
  
  # Database encryption
  database_encryption {
    state    = "ENCRYPTED"
    key_name = google_kms_crypto_key.gke_db_key.id
  }
  
  depends_on = [google_project_service.required_apis]
}

# Create node pool with security configurations
resource "google_container_node_pool" "secure_node_pool" {
  provider = google-beta
  
  name     = "${var.environment}-secure-pool"
  project  = var.project_id
  location = var.region
  cluster  = google_container_cluster.secure_cluster.name
  
  initial_node_count = 3
  
  autoscaling {
    min_node_count  = 3
    max_node_count  = 10
    location_policy = "BALANCED"
  }
  
  management {
    auto_repair  = true
    auto_upgrade = true
  }
  
  node_config {
    machine_type = "n2-standard-4"
    disk_size_gb = 100
    disk_type    = "pd-ssd"
    
    # Use custom service account
    service_account = google_service_account.gke_node_sa.email
    oauth_scopes = [
      "https://www.googleapis.com/auth/cloud-platform"
    ]
    
    # Security configurations
    shielded_instance_config {
      enable_secure_boot          = true
      enable_integrity_monitoring = true
    }
    
    workload_metadata_config {
      mode = "GKE_METADATA"
    }
    
    image_type = "COS_CONTAINERD"
    
    metadata = {
      disable-legacy-endpoints = "true"
    }
    
    labels = {
      environment = var.environment
      security    = "hardened"
    }
    
    tags = ["gke-node", "${var.environment}-node"]
  }
}

# Binary Authorization policy
resource "google_binary_authorization_policy" "cluster_policy" {
  provider = google-beta
  project  = var.project_id
  
  global_policy_evaluation_mode = "ENABLE"
  
  default_admission_rule {
    evaluation_mode  = "REQUIRE_ATTESTATION"
    enforcement_mode = "ENFORCED_BLOCK_AND_AUDIT_LOG"
    
    require_attestations_by = [
      google_binary_authorization_attestor.prod_attestor.name
    ]
  }
  
  cluster_admission_rules {
    cluster                 = google_container_cluster.secure_cluster.id
    evaluation_mode        = "REQUIRE_ATTESTATION"
    enforcement_mode       = "ENFORCED_BLOCK_AND_AUDIT_LOG"
    
    require_attestations_by = [
      google_binary_authorization_attestor.prod_attestor.name
    ]
  }
}

# Create Binary Authorization attestor
resource "google_binary_authorization_attestor" "prod_attestor" {
  provider = google-beta
  project  = var.project_id
  name     = "${var.environment}-attestor"
  
  attestation_authority_note {
    note_reference = google_container_analysis_note.attestor_note.name
    
    public_keys {
      id = data.google_kms_crypto_key_version.attestor_key_version.id
      
      pkix_public_key {
        public_key_pem      = data.google_kms_crypto_key_version.attestor_key_version.public_key[0].pem
        signature_algorithm = data.google_kms_crypto_key_version.attestor_key_version.public_key[0].algorithm
      }
    }
  }
}

# Output important values
output "cluster_endpoint" {
  value       = google_container_cluster.secure_cluster.endpoint
  sensitive   = true
  description = "GKE cluster endpoint"
}

output "artifact_registry" {
  value       = "${var.region}-docker.pkg.dev/${var.project_id}/${google_artifact_registry_repository.container_registry.repository_id}"
  description = "Artifact Registry URL"
}