diff --git a/examples/gke-public-cluster/README.md b/examples/gke-public-cluster/README.md index 9a48636..0911015 100644 --- a/examples/gke-public-cluster/README.md +++ b/examples/gke-public-cluster/README.md @@ -14,32 +14,24 @@ planes which do not. By default, regional clusters will create nodes across 3 zones in a region. If you're interested in how nodes are distributed in regional clusters, read the GCP docs about [balancing across zones](https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-autoscaler#balancing_across_zones). -The example follows best-practices and runs nodes using a custom service account to follow the principle of -least privilege. However you will need to ensure that the Identity and Access Management (IAM) API has been +The example follows best-practices and enables workload-identity on the cluster for access to GKE resources to follow the +principle least privilege. However you will need to ensure that the Identity and Access Management (IAM) API has been enabled for the given project. This can be enabled in the Google API Console: -https://console.developers.google.com/apis/api/iam.googleapis.com/overview. See "Why use Custom Service -Accounts?" for more information. +https://console.developers.google.com/apis/api/iam.googleapis.com/overview. See "Why use Workload Identity?" for more information. **Important:** Nodes in a public cluster are accessible from the public internet; try using a private cluster such as in [`gke-private-cluster`](../gke-private-cluster) to limit access to/from your nodes. Private clusters are recommended for running most apps and services. -## Why use Custom Service Accounts? +## Why use Workload Identity? -Each node in a GKE cluster is a Compute Engine instance. Therefore, applications running on a GKE cluster -inherit the scopes of the Compute Engine instances to which they are deployed. +Workload Identity is the recommended way to access Google Cloud services from applications running within GKE due to its improved security properties and manageability (https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity). -The recommended way to authenticate to GCP services from applications running on GKE is to create -your own service accounts. Ideally you must create a new service account for each application/service that makes requests to -Cloud Platform APIs. -GCP automatically creates a default service account, the "Compute Engine default service account" that GKE -associates it with the nodes it creates by default. Depending on how your project is configured, the default service account comes -pre-configured with project-wide permissions meaning that any given node will have access to every service every other -node has. Updating the default service account's permissions or assigning more access scopes to compute instances is -not the recommended way to authenticate to other Cloud Platform services from Pods running on GKE. In general, we -recommend using a per-node pool or per-cluster custom service account to allow you to more granularly restrict those -permissions. +Applications running on GKE must authenticate to use Google Cloud APIs such as the Compute APIs, Storage and Database APIs, or Machine Learning APIs. + +With Workload Identity, you can configure a Kubernetes service account to act as a Google service account. Any application running as the Kubernetes service account automatically authenticates as the Google service account when accessing Google Cloud APIs. This enables you to assign fine-grained identity and authorization for applications in your cluster. + ## Limitations @@ -56,6 +48,6 @@ your new zones are within the region your cluster is present in. 1. Run `terraform get`. 1. Run `terraform plan`. 1. If the plan looks good, run `terraform apply`. -1. To setup `kubectl` to access the deployed cluster, run `gcloud beta container clusters get-credentials $CLUSTER_NAME ---region $REGION --project $PROJECT`, where `CLUSTER_NAME`, `REGION` and `PROJECT` correspond to what you set for the +1. To setup `kubectl` to access the deployed cluster, run `gcloud beta container clusters get-credentials $CLUSTER_NAME +--region $REGION --project $PROJECT`, where `CLUSTER_NAME`, `REGION` and `PROJECT` correspond to what you set for the input variables. diff --git a/examples/gke-public-cluster/main.tf b/examples/gke-public-cluster/main.tf index f7eca8e..39310d9 100644 --- a/examples/gke-public-cluster/main.tf +++ b/examples/gke-public-cluster/main.tf @@ -53,6 +53,7 @@ module "gke_cluster" { alternative_default_service_account = var.override_default_node_pool_service_account ? module.gke_service_account.email : null enable_vertical_pod_autoscaling = var.enable_vertical_pod_autoscaling + enable_workload_identity = var.enable_workload_identity resource_labels = { environment = "testing" @@ -104,6 +105,10 @@ resource "google_container_node_pool" "node_pool" { service_account = module.gke_service_account.email + workload_metadata_config { + node_metadata = "GKE_METADATA_SERVER" + } + oauth_scopes = [ "https://www.googleapis.com/auth/cloud-platform", ] diff --git a/examples/gke-public-cluster/variables.tf b/examples/gke-public-cluster/variables.tf index 831a084..7e29cde 100644 --- a/examples/gke-public-cluster/variables.tf +++ b/examples/gke-public-cluster/variables.tf @@ -63,6 +63,12 @@ variable "enable_vertical_pod_autoscaling" { default = true } +variable "enable_workload_identity" { + description = "Enable Workload Identity on the cluster" + default = true + type = bool +} + # --------------------------------------------------------------------------------------------------------------------- # TEST PARAMETERS # These parameters are only used during testing and should not be touched. diff --git a/modules/gke-cluster/main.tf b/modules/gke-cluster/main.tf index e13edeb..e21fa11 100644 --- a/modules/gke-cluster/main.tf +++ b/modules/gke-cluster/main.tf @@ -10,6 +10,12 @@ terraform { required_version = ">= 0.12.26" } +locals { + workload_identity_config = ! var.enable_workload_identity ? [] : var.identity_namespace == null ? [{ + identity_namespace = "${var.project}.svc.id.goog" }] : [{ identity_namespace = var.identity_namespace + }] +} + # --------------------------------------------------------------------------------------------------------------------- # Create the GKE Cluster # We want to make a cluster with no node pools, and manage them all with the fine-grained google_container_node_pool resource @@ -153,6 +159,14 @@ resource "google_container_cluster" "cluster" { } } + dynamic "workload_identity_config" { + for_each = local.workload_identity_config + + content { + identity_namespace = workload_identity_config.value.identity_namespace + } + } + resource_labels = var.resource_labels } diff --git a/modules/gke-cluster/variables.tf b/modules/gke-cluster/variables.tf index 89dbe60..e4074c0 100644 --- a/modules/gke-cluster/variables.tf +++ b/modules/gke-cluster/variables.tf @@ -215,3 +215,15 @@ variable "services_secondary_range_name" { type = string default = null } + +variable "enable_workload_identity" { + description = "Enable Workload Identity on the cluster" + default = false + type = bool +} + +variable "identity_namespace" { + description = "Workload Identity Namespace. Default sets project based namespace [project_id].svc.id.goog" + default = null + type = string +}