diff --git a/modules/acm/README.md b/modules/acm/README.md index cd2a0d54c7..3b8791fcc6 100644 --- a/modules/acm/README.md +++ b/modules/acm/README.md @@ -67,6 +67,7 @@ data "google_client_config" "default" {} | cluster\_membership\_id | The cluster membership ID. If unset, one will be autogenerated. | `string` | `""` | no | | cluster\_name | GCP cluster Name used to reach cluster and which becomes the cluster name in the Config Sync kubernetes custom resource. | `string` | n/a | yes | | configmanagement\_version | Version of ACM. | `string` | `""` | no | +| create\_metrics\_gcp\_sa | Create a Google service account for ACM metrics writing | `bool` | `false` | no | | create\_ssh\_key | Controls whether a key will be generated for Git authentication | `bool` | `true` | no | | enable\_config\_sync | Whether to enable the ACM Config Sync on the cluster | `bool` | `true` | no | | enable\_fleet\_feature | Whether to enable the ACM feature on the fleet. | `bool` | `true` | no | @@ -78,6 +79,7 @@ data "google_client_config" "default" {} | https\_proxy | URL for the HTTPS proxy to be used when communicating with the Git repo. | `string` | `null` | no | | install\_template\_library | Whether to install the default Policy Controller template library | `bool` | `true` | no | | location | GCP location used to reach cluster. | `string` | n/a | yes | +| metrics\_gcp\_sa\_name | The name of the Google service account for ACM metrics writing | `string` | `"acm_metrics_writer_account"` | no | | policy\_bundles | A space separated list of Policy Controller policy bundles git urls (example: https://github.com/GoogleCloudPlatform/acm-policy-controller-library.git/bundles/policy-essentials-v2022) to install on the cluster. | `string` | `null` | no | | policy\_dir | Subfolder containing configs in ACM Git repo. If un-set, uses Config Management default. | `string` | `""` | no | | project\_id | GCP project\_id used to reach cluster. | `string` | n/a | yes | diff --git a/modules/acm/creds.tf b/modules/acm/creds.tf index 0e0ec5b0f2..0cec4206f9 100644 --- a/modules/acm/creds.tf +++ b/modules/acm/creds.tf @@ -14,6 +14,11 @@ * limitations under the License. */ +locals { + # GCP service account ids must be <= 30 chars matching regex ^[a-z](?:[-a-z0-9]{4,28}[a-z0-9])$ + service_account_name = trimsuffix(substr(var.metrics_gcp_sa_name, 0, 30), "-") +} + resource "tls_private_key" "k8sop_creds" { count = var.create_ssh_key ? 1 : 0 algorithm = "RSA" @@ -22,12 +27,67 @@ resource "tls_private_key" "k8sop_creds" { # Wait for the ACM operator to create the namespace resource "time_sleep" "wait_acm" { - count = (var.create_ssh_key == true || var.ssh_auth_key != null) ? 1 : 0 + count = (var.create_ssh_key == true || var.ssh_auth_key != null || var.enable_policy_controller == true) ? 1 : 0 depends_on = [google_gke_hub_feature_membership.main] create_duration = "300s" } +resource "google_service_account_iam_binding" "config-management-monitoring-iam" { + count = var.enable_config_sync && var.create_metrics_gcp_sa ? 1 : 0 + service_account_id = google_service_account.acm_metrics_writer_account[0].name + role = "roles/iam.workloadIdentityUser" + + members = ["serviceAccount:${var.project_id}.svc.id.goog[config-management-monitoring/default]"] +} + +resource "google_service_account_iam_binding" "gatekeeper-system-iam" { + count = var.enable_policy_controller && var.create_metrics_gcp_sa ? 1 : 0 + service_account_id = google_service_account.acm_metrics_writer_account[0].name + role = "roles/iam.workloadIdentityUser" + + members = ["serviceAccount:${var.project_id}.svc.id.goog[gatekeeper-system/gatekeeper-admin]"] +} + +module "annotate-sa-config-management-monitoring" { + source = "terraform-google-modules/gcloud/google//modules/kubectl-wrapper" + version = "~> 3.1" + + enabled = var.enable_config_sync && var.create_metrics_gcp_sa + skip_download = true + cluster_name = var.cluster_name + cluster_location = var.location + project_id = var.project_id + + kubectl_create_command = "kubectl annotate --overwrite sa -n config-management-monitoring default iam.gke.io/gcp-service-account=${google_service_account.acm_metrics_writer_account[0].email}" + kubectl_destroy_command = "kubectl annotate sa -n config-management-monitoring default iam.gke.io/gcp-service-account-" + + module_depends_on = time_sleep.wait_acm +} + +module "annotate-sa-gatekeeper-system" { + source = "terraform-google-modules/gcloud/google//modules/kubectl-wrapper" + version = "~> 3.1" + + enabled = var.enable_policy_controller && var.create_metrics_gcp_sa + skip_download = true + cluster_name = var.cluster_name + cluster_location = var.location + project_id = var.project_id + + kubectl_create_command = "kubectl annotate --overwrite sa -n gatekeeper-system gatekeeper-admin iam.gke.io/gcp-service-account=${google_service_account.acm_metrics_writer_account[0].email}" + kubectl_destroy_command = "kubectl annotate sa -n gatekeeper-system gatekeeper-admin iam.gke.io/gcp-service-account-" + + module_depends_on = time_sleep.wait_acm +} + +resource "google_service_account" "acm_metrics_writer_account" { + count = var.create_metrics_gcp_sa ? 1 : 0 + + account_id = local.service_account_name + project = var.project_id +} + resource "kubernetes_secret_v1" "creds" { count = (var.create_ssh_key == true || var.ssh_auth_key != null) ? 1 : 0 depends_on = [time_sleep.wait_acm] @@ -38,6 +98,6 @@ resource "kubernetes_secret_v1" "creds" { } data = { - "local.k8sop_creds_secret_key" = local.private_key + (local.k8sop_creds_secret_key) = local.private_key } } diff --git a/modules/acm/variables.tf b/modules/acm/variables.tf index 595ee6047b..f9d824d249 100644 --- a/modules/acm/variables.tf +++ b/modules/acm/variables.tf @@ -152,3 +152,16 @@ variable "policy_bundles" { type = string default = null } + +variable "create_metrics_gcp_sa" { + description = "Create a Google service account for ACM metrics writing" + type = bool + default = false +} + +variable "metrics_gcp_sa_name" { + description = "The name of the Google service account for ACM metrics writing" + type = string + default = "acm_metrics_writer_account" + +}