Search code examples
google-cloud-platformterraformterraform-provider-gcpgke-networking

How to create network tags for GKE nodes in Terraform


We are utilizing the GCP network and GKE modules in Terraform to create the VPC and GKE cluster subsequently. Now we would like to create a firewall rule with the target as GKE nodes. We don't want to update the existing firewall rules which are auto-created as the format which GCP uses to name them might change in future due to which our logic may fail. That's why there is a need to create a separate firewall rule along with a separate network tag pointing to the GKE nodes. Module info

VPC

module "vpc" {
  source       = "terraform-google-modules/network/google"
  #version      = "~> 2.5"
  project_id   = var.project_id
  network_name = "${var.project_name}-${var.env_name}-vpc"
  subnets = [
    {
      subnet_name   = "${var.project_name}-${var.env_name}-subnet"
      subnet_ip     = "${var.subnetwork_cidr}"
      subnet_region = var.region
    }
  ]
  secondary_ranges = {
    "${var.project_name}-${var.env_name}-subnet" = [
      {
        range_name    = "${var.project_name}-gke-pod-ip-range"
        ip_cidr_range = "${var.ip_range_pods_cidr}"
      },
      {
        range_name    = "${var.project_name}-gke-service-ip-range"
        ip_cidr_range = "${var.ip_range_services_cidr}"
      }
    ]
  }
}

GKE_CLUSTER

module "gke" {
  source                 = "terraform-google-modules/kubernetes-engine/google//modules/beta-private-cluster"
  project_id             = var.project_id
  name                   = "${var.project_name}-gke-${var.env_name}-cluster"
  regional               = true
  region                 = var.region
  zones                  = ["${var.region}-a", "${var.region}-b", "${var.region}-c"]
  network                = module.vpc.network_name
  subnetwork             = module.vpc.subnets_names[0]
  ip_range_pods          = "${var.project_name}-gke-pod-ip-range"
  ip_range_services      = "${var.project_name}-gke-service-ip-range"
  http_load_balancing        = false
  network_policy             = false
  horizontal_pod_autoscaling = true
  filestore_csi_driver       = false
  enable_private_endpoint    = false
  enable_private_nodes       = true
  master_ipv4_cidr_block     = "${var.control_plane_cidr}"
  istio                      = false
  cloudrun                   = false
  dns_cache                  = false
  node_pools = [
    {
      name                      = "${var.project_name}-gke-node-pool"
      machine_type              = "${var.machine_type}"
      node_locations            = "${var.region}-a,${var.region}-b,${var.region}-c"
      min_count                 = "${var.node_pools_min_count}"
      max_count                 = "${var.node_pools_max_count}"
      disk_size_gb              = "${var.node_pools_disk_size_gb}"
    #   local_ssd_count           = 0
    #   spot                      = false
    #   local_ssd_ephemeral_count = 0
    #   disk_type                 = "pd-standard"
    #   image_type                = "COS_CONTAINERD"
    #   enable_gcfs               = false
      auto_repair               = true
      auto_upgrade              = true
    #   service_account           = "project-service-account@<PROJECT ID>.iam.gserviceaccount.com"
      preemptible               = false
    #   initial_node_count        = 80
    }
  ]

  # node_pools_tags = {
  #   all = []

  #   default-node-pool = ["default-node-pool",]
  # }
}

FIREWALL

module "firewall_rules" {
  source       = "terraform-google-modules/network/google//modules/firewall-rules"
  project_id   = var.project_id
  network_name = module.vpc.network_name

  rules = [{
    name                    = "allow-istio-ingress"
    description             = null
    direction               = "INGRESS"
    priority                = null
    ranges                  = ["${var.control_plane_cidr}"]
    source_tags             = null
    source_service_accounts = null
    target_tags             = null
    target_service_accounts = null
    allow = [{
      protocol = "tcp"
      ports    = ["15017"]
    }]
    deny = []
    log_config = {
      metadata = "INCLUDE_ALL_METADATA"
    }
  }]

  depends_on = [module.gke]
}

Although the GKE module has tags property to define tags explicitly, we still need assistance to properly instantiate it and then fetch the same tag value in the firewall module.


Solution

  • I found a working solution to my question posted earlier. Please refer to the GKE module snippet. In that, we only need to modify the below part and an explicit network tag will be created to point to all the nodes in that node pool.

    module "gke" {
      .
      .
      node_pools = [
        {
          name = "gke-node-pool"
          .
          .
          .
        },
      ]
    
      node_pools_tags = {
        "gke-node-pool" = "gke-node-pool-network-tag"
      }
    }