diff --git a/README.md b/README.md
index 44e0bc6..84e3c8c 100644
--- a/README.md
+++ b/README.md
@@ -112,6 +112,7 @@ resources that lack official modules.
| [force\_ssl](#input\_force\_ssl) | Enforce SSL through the usage of the Cloud SQL Proxy (cloudsql://) in the DB connection string | `bool` | `false` | no |
| [gke\_machine\_type](#input\_gke\_machine\_type) | Specifies the machine type to be allocated for the database | `string` | `"n1-standard-4"` | no |
| [gke\_node\_count](#input\_gke\_node\_count) | n/a | `number` | `2` | no |
+| [kms\_gcs\_sa\_name](#input\_kms\_gcs\_sa\_name) | n/a | `string` | `"wandb-serviceaccount"` | no |
| [labels](#input\_labels) | Labels to apply to resources | `map(string)` | `{}` | no |
| [license](#input\_license) | Your wandb/local license | `string` | n/a | yes |
| [local\_restore](#input\_local\_restore) | Restores W&B to a stable state if needed | `bool` | `false` | no |
@@ -157,6 +158,7 @@ resources that lack official modules.
| [fqdn](#output\_fqdn) | The FQDN to the W&B application |
| [gke\_node\_count](#output\_gke\_node\_count) | n/a |
| [gke\_node\_instance\_type](#output\_gke\_node\_instance\_type) | n/a |
+| [sa\_account\_email](#output\_sa\_account\_email) | This output provides the email address of the service account created for workload identity, if workload identity is enabled. Otherwise, it returns null |
| [service\_account](#output\_service\_account) | Weights & Biases service account used to manage resources. |
| [standardized\_size](#output\_standardized\_size) | n/a |
| [url](#output\_url) | The URL to the W&B application |
diff --git a/main.tf b/main.tf
index 881cb9c..06e62ff 100644
--- a/main.tf
+++ b/main.tf
@@ -29,12 +29,14 @@ locals {
}
module "service_accounts" {
- source = "./modules/service_accounts"
- namespace = var.namespace
- bucket_name = var.bucket_name
- stackdriver_sa_name = var.stackdriver_sa_name
- enable_stackdriver = var.enable_stackdriver
- depends_on = [module.project_factory_project_services]
+ source = "./modules/service_accounts"
+ namespace = var.namespace
+ bucket_name = var.bucket_name
+ kms_gcs_sa_name = var.kms_gcs_sa_name
+ create_workload_identity = var.create_workload_identity
+ stackdriver_sa_name = var.stackdriver_sa_name
+ enable_stackdriver = var.enable_stackdriver
+ depends_on = [module.project_factory_project_services]
}
module "kms" {
@@ -150,7 +152,10 @@ module "gke_app" {
database_connection_string = module.database.connection_string
redis_connection_string = local.redis_connection_string
redis_ca_cert = local.redis_certificate
-
+ service_account_name = var.kms_gcs_sa_name
+ service_account_annotations = var.create_workload_identity ? {
+ "iam.gke.io/gcp-service-account" : module.service_accounts.sa_account_email
+ } : {}
oidc_client_id = var.oidc_client_id
oidc_issuer = var.oidc_issuer
oidc_auth_method = var.oidc_auth_method
@@ -246,6 +251,15 @@ module "wandb" {
app = {
extraEnvs = var.app_wandb_env
+ serviceaccount = var.create_workload_identity ? {
+ create = false
+ name = var.kms_gcs_sa_name
+ annotations = { "iam.gke.io/gcp-service-account" = module.service_accounts.sa_account_email }
+ } : {
+ create = true
+ name = ""
+ annotations = {}
+ }
}
ingress = {
diff --git a/modules/app_gke/main.tf b/modules/app_gke/main.tf
index 6b8338c..965168f 100644
--- a/modules/app_gke/main.tf
+++ b/modules/app_gke/main.tf
@@ -7,12 +7,12 @@ locals {
resource "google_container_cluster" "default" {
name = "${var.namespace}-cluster"
- network = var.network.self_link
- subnetwork = var.subnetwork.self_link
- networking_mode = "VPC_NATIVE"
-
+ network = var.network.self_link
+ subnetwork = var.subnetwork.self_link
+ networking_mode = "VPC_NATIVE"
enable_intranode_visibility = true
+
binary_authorization {
evaluation_mode = "PROJECT_SINGLETON_POLICY_ENFORCE"
}
@@ -24,7 +24,7 @@ resource "google_container_cluster" "default" {
workload_pool = "${local.project_id}.svc.id.goog"
}
}
-
+
ip_allocation_policy {
cluster_ipv4_cidr_block = "/14"
services_ipv4_cidr_block = "/19"
@@ -78,12 +78,13 @@ resource "google_container_node_pool" "default" {
"https://www.googleapis.com/auth/sqlservice.admin",
]
- dynamic "workload_metadata_config" {
- for_each = var.create_workload_identity == true ? [1] : []
- content {
- mode = "GKE_METADATA"
+ dynamic "workload_metadata_config" {
+ for_each = var.create_workload_identity == true ? [1] : []
+ content {
+ mode = "GKE_METADATA"
+ }
}
- }
+
shielded_instance_config {
enable_secure_boot = true
}
diff --git a/modules/service_accounts/main.tf b/modules/service_accounts/main.tf
index 457af76..4bee861 100644
--- a/modules/service_accounts/main.tf
+++ b/modules/service_accounts/main.tf
@@ -62,7 +62,43 @@ resource "google_project_iam_member" "secretmanager_admin" {
role = "roles/secretmanager.admin"
}
+####### service account for kms and gcs cross project access
+resource "google_service_account" "kms_gcs_sa" {
+ count = var.create_workload_identity == true ? 1 : 0
+ account_id = var.kms_gcs_sa_name
+ display_name = "Service Account For Workload Identity"
+}
+
+resource "google_project_iam_member" "storage" {
+ count = var.create_workload_identity == true ? 1 : 0
+ project = local.project_id
+ role = "roles/storage.admin"
+ member = "serviceAccount:${google_service_account.kms_gcs_sa[count.index].email}"
+}
+
+resource "google_project_iam_member" "kms" {
+ count = var.create_workload_identity == true ? 1 : 0
+ project = local.project_id
+ role = "roles/cloudkms.admin"
+ member = "serviceAccount:${google_service_account.kms_gcs_sa[count.index].email}"
+}
+
+resource "google_service_account_iam_member" "token_creator_binding" {
+ count = var.create_workload_identity == true ? 1 : 0
+ service_account_id = google_service_account.kms_gcs_sa[count.index].id
+ role = "roles/iam.serviceAccountTokenCreator"
+ member = "serviceAccount:${google_service_account.kms_gcs_sa[count.index].email}"
+}
+
+resource "google_service_account_iam_member" "workload_binding" {
+ count = var.create_workload_identity == true ? 1 : 0
+ service_account_id = google_service_account.kms_gcs_sa[count.index].id
+ role = "roles/iam.workloadIdentityUser"
+ member = "serviceAccount:${local.project_id}.svc.id.goog[default/${var.kms_gcs_sa_name}]"
+}
+
+### service account for stackdriver
resource "google_service_account" "stackdriver" {
count = var.enable_stackdriver == true ? 1 : 0
account_id = var.stackdriver_sa_name
diff --git a/modules/service_accounts/outputs.tf b/modules/service_accounts/outputs.tf
index dfb57f2..e485235 100644
--- a/modules/service_accounts/outputs.tf
+++ b/modules/service_accounts/outputs.tf
@@ -1,9 +1,12 @@
output "service_account" {
value = google_service_account.main
-
description = "The service account."
}
+output "sa_account_email" {
+ value = var.create_workload_identity == true ? google_service_account.kms_gcs_sa[0].email : null
+}
+
output "stackdriver_email" {
value = var.enable_stackdriver == true ? google_service_account.stackdriver[0].email : null
}
\ No newline at end of file
diff --git a/modules/service_accounts/variables.tf b/modules/service_accounts/variables.tf
index 65b56d0..64c2953 100644
--- a/modules/service_accounts/variables.tf
+++ b/modules/service_accounts/variables.tf
@@ -10,9 +10,20 @@ variable "bucket_name" {
}
+variable "create_workload_identity" {
+ description = "Flag to indicate whether to create a workload identity for the service account."
+ type = bool
+}
+
+variable "kms_gcs_sa_name" {
+ type = string
+ default = "wandb-serviceaccount"
+}
+
variable "stackdriver_sa_name" {
description = "The name of the service account."
type = string
+ default = "wandb-stackdriver"
}
variable "enable_stackdriver" {
diff --git a/outputs.tf b/outputs.tf
index 0a9cbe2..1a600d3 100644
--- a/outputs.tf
+++ b/outputs.tf
@@ -85,5 +85,7 @@ output "database_instance_type" {
value = coalesce(try(local.deployment_size[var.size].db, null), var.database_machine_type)
}
-
-
+output "sa_account_email" {
+ description = "This output provides the email address of the service account created for workload identity, if workload identity is enabled. Otherwise, it returns null"
+ value = var.create_workload_identity == true ? module.service_accounts.sa_account_email : null
+}
\ No newline at end of file
diff --git a/variables.tf b/variables.tf
index 7d2deef..03ef2f6 100644
--- a/variables.tf
+++ b/variables.tf
@@ -254,18 +254,24 @@ variable "parquet_wandb_env" {
default = {}
}
-variable "enable_stackdriver" {
- type = bool
- default = true
-}
-
variable "create_workload_identity" {
description = "Flag to indicate whether to create a workload identity for the service account."
type = bool
default = true
}
+variable "kms_gcs_sa_name" {
+ type = string
+ default = "wandb-serviceaccount"
+}
+
+variable "enable_stackdriver" {
+ type = bool
+ default = true
+}
+
variable "stackdriver_sa_name" {
type = string
default = "wandb-stackdriver"
}
+