Skip to content

Commit

Permalink
Example OIDC configuration modules for GKE (#2319)
Browse files Browse the repository at this point in the history
Example OIDC configuration modules for GKE
  • Loading branch information
alexsomesan authored Oct 17, 2023
1 parent f0f2b0f commit 224e9a9
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 5 deletions.
3 changes: 3 additions & 0 deletions .changelog/2319.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:doc
Add example module for configuring OIDC authentication on GKE
```
2 changes: 1 addition & 1 deletion _examples/eks/eks-oidc/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ variable "cluster_name" {
}

variable "oidc_issuer_url" {
default = "https://app.terraform.io"
default = "https://app.terraform.io"
}

variable "oidc_audience" {
Expand Down
21 changes: 20 additions & 1 deletion _examples/gke/gke-cluster/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,31 @@ terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "3.52"
version = ">= 5.1"
}
}
}

# This is used to set local variable google_zone.
# This can be replaced with a statically-configured zone, if preferred.
data "google_compute_zones" "available" {
provider = google-beta
}

locals {
google_zone = data.google_compute_zones.available.names[0]
}

data "google_container_engine_versions" "supported" {
provider = google-beta

location = local.google_zone
version_prefix = var.kubernetes_version
}

resource "google_container_cluster" "default" {
provider = google-beta

name = var.cluster_name
location = local.google_zone
initial_node_count = var.workers_count
Expand All @@ -29,6 +38,10 @@ resource "google_container_cluster" "default" {
# https://www.terraform.io/docs/providers/google/r/container_cluster.html#node_version
node_version = data.google_container_engine_versions.supported.latest_master_version

release_channel {
channel = "RAPID"
}

node_locations = [
data.google_compute_zones.available.names[1],
]
Expand All @@ -43,4 +56,10 @@ resource "google_container_cluster" "default" {
"https://www.googleapis.com/auth/monitoring",
]
}

identity_service_config {
enabled = var.idp_enabled
}

deletion_protection = false
}
7 changes: 4 additions & 3 deletions _examples/gke/gke-cluster/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: MPL-2.0

variable "kubernetes_version" {
default = "1.18"
default = "1.27"
}

variable "workers_count" {
Expand All @@ -13,6 +13,7 @@ variable "cluster_name" {
type = string
}

locals {
google_zone = data.google_compute_zones.available.names[0]
variable "idp_enabled" {
type = bool
default = false
}
32 changes: 32 additions & 0 deletions _examples/gke/gke-oidc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Summary

This module configures a GKE cluster to use Terraform Cloud or Terraform Enterprise as an OIDC identity provider.

# Usage

This module requires a GKE cluster that is up-and-running and has identity services enabled.
If you already have a GKE , but are unsure if identity services are enabled, you can enable it as described here: https://cloud.google.com/kubernetes-engine/docs/how-to/oidc#enabling_on_a_new_cluster

If you provisioned your cluster with Terraform, you can add the following block to your `resource "google_container_cluster"` configuration and re-apply:

```
identity_service_config {
enabled = true
}
```

Applying this module will modify an existing custom resource already present in the target cluster, adding the necessary details specific to TFC / TFE. The `authentication.gke.io.v2alpha1.ClientConfig` custom resoruce will only be present in cluster whrere identity service has been enabled (as described above).

To configure the module, the following Terraform variables need to be set. Variables with a default value are optional.

| Variable | Contents | Default value |
| ---------------- | -------------------------------------------------------------------------------------------- | --------------------------- |
| cluster_name | Name of the target GKE cluster to configure | |
| gke_location | Location (zone or region) of the cluster in GCP | |
| odic_issuer_uri | Base URL of TFC / TFE endpoint (default to public TFC) | https://app.terraform.io |
| oidc_audience | Audience value as configured in TFC / TFE environment variable | kubernetes |
| oidc_user_claim | Token claim to extract user name from (defaults to 'sub') | sub |
| oidc_group_claim | Token claim to extract the group membership from (defaults to 'terraform_organization_name') | terraform_organization_name |
| TFE_CA_cert | CA Certificate for the HTTPS API endpoint of Terraform Enterprise (contents, not filepath) | |

**BEWARE** _Once this module is successfully applied, the `authentication.gke.io.v2alpha1.ClientConfig` CR named "default" in namespace "kube-public" becomes managed by Terraform, as is usual with imported resources. As a consequence, destroying this module will also remove that resource from the cluster._
12 changes: 12 additions & 0 deletions _examples/gke/gke-oidc/gke.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

data "google_container_cluster" "upstream" {
provider = google-beta
name = var.cluster_name
location = var.gke_location
}

data "google_client_config" "provider" {
provider = google-beta
}
43 changes: 43 additions & 0 deletions _examples/gke/gke-oidc/k8s.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

provider "kubernetes" {
host = "https://${data.google_container_cluster.upstream.endpoint}"
token = data.google_client_config.provider.access_token
cluster_ca_certificate = base64decode(
data.google_container_cluster.upstream.master_auth[0].cluster_ca_certificate,
)
}

import {
// The name of this resource is hardcoded by GKE as described in:
// https://cloud.google.com/kubernetes-engine/docs/how-to/oidc#configuring_on_a_cluster
//
id = "apiVersion=authentication.gke.io/v2alpha1,kind=ClientConfig,namespace=kube-public,name=default"
to = kubernetes_manifest.oidc_conf
}

resource "kubernetes_manifest" "oidc_conf" {
manifest = {
apiVersion = "authentication.gke.io/v2alpha1"
kind = "ClientConfig"
metadata = {
name = "default"
namespace = "kube-public"
}
spec = {
authentication = [
{
name = data.google_container_cluster.upstream.name
oidc = {
clientID = var.oidc_audience
issuerURI = var.odic_issuer_uri
userClaim = var.oidc_user_claim
groupClaim = var.oidc_group_claim
certificateAuthorityData = var.TFE_CA_cert
}
}
]
}
}
}
6 changes: 6 additions & 0 deletions _examples/gke/gke-oidc/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

output "config_manifest" {
value = kubernetes_manifest.oidc_conf.object
}
42 changes: 42 additions & 0 deletions _examples/gke/gke-oidc/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

variable "cluster_name" {
description = "Name of target GKE cluster"
type = string
}

variable "gke_location" {
description = "Location of target GKE cluster"
type = string
}

variable "oidc_audience" {
description = "Audience value as configured in TFC / TFE environment variable"
type = string
default = "kubernetes"
}

variable "odic_issuer_uri" {
description = "Base URL of TFC / TFE endpoint (default to public TFC)"
type = string
default = "https://app.terraform.io"
}

variable "oidc_user_claim" {
description = "Token claim to extract user name from (defaults to 'sub')"
type = string
default = "sub"
}

variable "oidc_group_claim" {
description = "Token claim to extract the group membership from (defaults to 'terraform_organization_name')"
type = string
default = "terraform_organization_name"
}

variable "TFE_CA_cert" {
description = "CA Certificate for the HTTPS API endpoint of TFE"
type = string
default = null
}

0 comments on commit 224e9a9

Please sign in to comment.