modules/jupyter/main.tf (131 lines of code) (raw):

# Copyright 2023 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. data "google_project" "project" { project_id = var.project_id } locals { cloudsql_instance_connection_name = var.cloudsql_instance_name != "" ? format("%s:%s:%s", var.project_id, var.db_region, var.cloudsql_instance_name) : "" additional_labels = tomap({ for item in split(",", var.additional_labels) : split("=", item)[0] => split("=", item)[1] }) } # IAP Section: Creates the GKE components module "iap_auth" { count = var.add_auth ? 1 : 0 source = "../../modules/iap" project_id = var.project_id namespace = var.namespace app_name = "jupyter" create_brand = var.create_brand support_email = var.support_email k8s_ingress_name = var.k8s_ingress_name k8s_managed_cert_name = var.k8s_managed_cert_name k8s_iap_secret_name = var.k8s_iap_secret_name k8s_backend_config_name = var.k8s_backend_config_name k8s_backend_service_name = var.k8s_backend_service_name k8s_backend_service_port = var.k8s_backend_service_port client_id = var.client_id client_secret = var.client_secret domain = var.domain members_allowlist = var.members_allowlist depends_on = [ helm_release.jupyterhub ] } module "jupyterhub-workload-identity" { source = "terraform-google-modules/kubernetes-engine/google//modules/workload-identity" version = "30.0.0" # Pinning to a previous version as current version (30.1.0) showed inconsitent behaviour with workload identity service accounts name = var.workload_identity_service_account namespace = var.namespace project_id = var.project_id roles = concat(var.predefined_iam_roles, var.gcp_service_account_iam_roles) } resource "kubernetes_annotations" "hub" { api_version = "v1" kind = "ServiceAccount" metadata { name = "hub" namespace = var.namespace } annotations = { "iam.gke.io/gcp-service-account" = module.jupyterhub-workload-identity.gcp_service_account_email } depends_on = [ helm_release.jupyterhub, ] } resource "google_service_account_iam_binding" "hub-workload-identity-user" { count = var.add_auth ? 1 : 0 service_account_id = module.jupyterhub-workload-identity.gcp_service_account.name role = "roles/iam.workloadIdentityUser" members = [ "serviceAccount:${var.project_id}.svc.id.goog[${var.namespace}/hub]", "serviceAccount:${var.project_id}.svc.id.goog[${var.namespace}/${var.workload_identity_service_account}]", ] depends_on = [ helm_release.jupyterhub ] } resource "google_storage_bucket_iam_member" "gcs-bucket-iam" { bucket = var.gcs_bucket role = "roles/storage.objectAdmin" member = "serviceAccount:${module.jupyterhub-workload-identity.gcp_service_account_email}" } resource "random_password" "generated_password" { count = var.add_auth ? 0 : 1 length = 10 special = false } resource "helm_release" "jupyterhub" { name = "jupyterhub" repository = "https://jupyterhub.github.io/helm-chart" chart = "jupyterhub" namespace = var.namespace create_namespace = true cleanup_on_fail = "true" timeout = 600 version = "3.3.8" values = var.autopilot_cluster ? [templatefile("${path.module}/jupyter_config/config-selfauth-autopilot.yaml", { password = var.add_auth ? "dummy" : random_password.generated_password[0].result project_id = var.project_id project_number = data.google_project.project.number namespace = var.namespace additional_labels = local.additional_labels backend_config = var.k8s_backend_config_name service_name = var.k8s_backend_service_name authenticator_class = var.add_auth ? "'gcpiapjwtauthenticator.GCPIAPAuthenticator'" : "dummy" service_type = var.add_auth ? "NodePort" : "ClusterIP" gcs_bucket = var.gcs_bucket k8s_service_account = var.workload_identity_service_account ephemeral_storage = var.ephemeral_storage secret_name = var.db_secret_name cloudsql_instance_connection_name = local.cloudsql_instance_connection_name notebook_image = var.notebook_image notebook_image_tag = var.notebook_image_tag }) ] : [templatefile("${path.module}/jupyter_config/config-selfauth.yaml", { password = var.add_auth ? "dummy" : random_password.generated_password[0].result project_id = var.project_id project_number = data.google_project.project.number namespace = var.namespace additional_labels = local.additional_labels backend_config = var.k8s_backend_config_name service_name = var.k8s_backend_service_name authenticator_class = var.add_auth ? "'gcpiapjwtauthenticator.GCPIAPAuthenticator'" : "dummy" service_type = var.add_auth ? "NodePort" : "ClusterIP" gcs_bucket = var.gcs_bucket k8s_service_account = var.workload_identity_service_account ephemeral_storage = var.ephemeral_storage secret_name = var.db_secret_name cloudsql_instance_connection_name = local.cloudsql_instance_connection_name notebook_image = var.notebook_image notebook_image_tag = var.notebook_image_tag }) ] depends_on = [module.jupyterhub-workload-identity] } data "kubernetes_service" "jupyter" { metadata { name = var.k8s_backend_service_name namespace = var.namespace } depends_on = [module.iap_auth, helm_release.jupyterhub] }