From a03e73d3490aa29b33fa6a0d351eb8246c2cfbd4 Mon Sep 17 00:00:00 2001 From: Mateusz Jenek Date: Mon, 17 Jun 2024 11:07:59 +0200 Subject: [PATCH] feat: use dynamic credentials --- main.tf | 1 + modules/base/main.tf | 30 +++++++++---- modules/base/variables.tf | 6 +++ modules/dynamic_creds/main.tf | 51 +++++++++++++++++++++++ modules/dynamic_creds/outputs.tf | 4 ++ modules/dynamic_creds/providers.tf | 13 ++++++ modules/dynamic_creds/variables.tf | 27 ++++++++++++ modules/htc_res_defs/main.tf | 10 +---- modules/htc_res_defs/variables.tf | 6 ++- modules/network/{output.tf => outputs.tf} | 0 10 files changed, 129 insertions(+), 19 deletions(-) create mode 100644 modules/dynamic_creds/main.tf create mode 100644 modules/dynamic_creds/outputs.tf create mode 100644 modules/dynamic_creds/providers.tf create mode 100644 modules/dynamic_creds/variables.tf rename modules/network/{output.tf => outputs.tf} (100%) diff --git a/main.tf b/main.tf index 646e555..444a6b7 100644 --- a/main.tf +++ b/main.tf @@ -5,6 +5,7 @@ module "base" { project_id = var.project_id region = var.region humanitec_prefix = var.humanitec_prefix + humanitec_org_id = var.humanitec_org_id environment = var.environment environment_type = var.environment_type diff --git a/modules/base/main.tf b/modules/base/main.tf index 0b52d05..7cd3728 100644 --- a/modules/base/main.tf +++ b/modules/base/main.tf @@ -44,17 +44,29 @@ module "k8s" { gar_repository_location = var.gar_repository_location } +# ###################################################################### +# # DYNAMIC CREDENTIALS +# ###################################################################### +module "credentials" { + source = "../dynamic_creds" + humanitec_org = var.humanitec_org_id + gcp_project_id = var.project_id + +} + + # ###################################################################### # # HUMANITEC MODULE # ###################################################################### module "res_defs" { - source = "../htc_res_defs" - k8s_cluster_name = module.k8s.cluster_name - k8s_loadbalancer = module.k8s.loadbalancer - k8s_region = var.region - k8s_project_id = var.project_id - k8s_credentials = module.k8s.credentials - environment = var.environment - environment_type = var.environment_type - prefix = var.humanitec_prefix + source = "../htc_res_defs" + k8s_cluster_name = module.k8s.cluster_name + k8s_loadbalancer = module.k8s.loadbalancer + k8s_region = var.region + k8s_project_id = var.project_id + k8s_credentials = module.k8s.credentials + environment = var.environment + environment_type = var.environment_type + prefix = var.humanitec_prefix + humanitec_cloud_account = module.credentials.humanitec_cloud_account } diff --git a/modules/base/variables.tf b/modules/base/variables.tf index f6259d9..5826e02 100644 --- a/modules/base/variables.tf +++ b/modules/base/variables.tf @@ -13,6 +13,12 @@ variable "region" { description = "GCP Region to provision resources in." } +variable "humanitec_org_id" { + description = "Humanitec Organization ID (required for Backstage)" + type = string + default = null +} + ########################################## # OPTIONAL INPUTS ########################################## diff --git a/modules/dynamic_creds/main.tf b/modules/dynamic_creds/main.tf new file mode 100644 index 0000000..a8562f6 --- /dev/null +++ b/modules/dynamic_creds/main.tf @@ -0,0 +1,51 @@ +data "google_project" "project" { + project_id = var.gcp_project_id +} + +resource "google_iam_workload_identity_pool" "pool" { + workload_identity_pool_id = var.gcp_workload_identity_pool_id + display_name = "Humanitec Identity Pool" + description = "Identity pool for platform orchiestration" +} + +resource "google_iam_workload_identity_pool_provider" "pool_provider" { + workload_identity_pool_id = google_iam_workload_identity_pool.pool.workload_identity_pool_id + workload_identity_pool_provider_id = var.gcp_workload_identity_pool_provider_id + attribute_mapping = { + "google.subject" = "assertion.sub" + } + oidc { + issuer_uri = "https://idtoken.humanitec.io" + } +} + +resource "google_service_account" "service_account" { + account_id = var.gcp_service_account_id + display_name = "Humanitec GCP dynamic cloud account" + description = "Used by Humanitec Platform Orchestrator Cloud Account" +} + +resource "humanitec_resource_account" "cloud_account" { + id = "humanitec-gcp-dynamic-cloud-account" + name = "Humanitec GCP dynamic cloud account" + type = "gcp-identity" + credentials = jsonencode({ + "gcp_service_account" = "${google_service_account.service_account.account_id}@${var.gcp_project_id}.iam.gserviceaccount.com" + "gcp_audience" = "//iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.pool.workload_identity_pool_id}/providers/${google_iam_workload_identity_pool_provider.pool_provider.workload_identity_pool_provider_id}" + }) +} + +resource "google_service_account_iam_binding" "iam-binding" { + service_account_id = google_service_account.service_account.name + role = "roles/iam.workloadIdentityUser" + + members = [ + "principal://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/humanitec-wif-pool/subject/${var.humanitec_org}/${humanitec_resource_account.cloud_account.id}", + ] +} + +resource "google_project_iam_member" "cloud_account_container_role" { + project = var.gcp_project_id + role = "roles/container.admin" + member = "serviceAccount:${google_service_account.service_account.email}" +} diff --git a/modules/dynamic_creds/outputs.tf b/modules/dynamic_creds/outputs.tf new file mode 100644 index 0000000..f488fb8 --- /dev/null +++ b/modules/dynamic_creds/outputs.tf @@ -0,0 +1,4 @@ +output "humanitec_cloud_account" { + value = humanitec_resource_account.cloud_account.id + description = "The ID of the Humanitec Cloud Account." +} diff --git a/modules/dynamic_creds/providers.tf b/modules/dynamic_creds/providers.tf new file mode 100644 index 0000000..9c3aaee --- /dev/null +++ b/modules/dynamic_creds/providers.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + humanitec = { + source = "humanitec/humanitec" + version = "~> 1.0" + } + google = { + source = "hashicorp/google" + version = "~> 5.1" + } + } + required_version = ">= 1.3.0" +} diff --git a/modules/dynamic_creds/variables.tf b/modules/dynamic_creds/variables.tf new file mode 100644 index 0000000..80ba18a --- /dev/null +++ b/modules/dynamic_creds/variables.tf @@ -0,0 +1,27 @@ +variable "gcp_project_id" { + type = string + description = "The ID of the GCP project to which resources will be deployed." +} + +variable "gcp_workload_identity_pool_id" { + type = string + default = "humanitec-wif-pool" + description = "The ID of the Workload Identity Pool in GCP, which allows you to manage resources within the GCP project." +} + +variable "gcp_workload_identity_pool_provider_id" { + type = string + default = "humanitec-wif" + description = "The ID of the Workload Identity Pool Provider within the specified Workload Identity Pool in GCP, enabling integration with Humanitec." +} + +variable "gcp_service_account_id" { + type = string + default = "humanitec-cloud-account" + description = "The ID of the service account used for authenticating and managing GCP resources." +} + +variable "humanitec_org" { + type = string + description = "The identifier of the Humanitec organization used for managing deployments and resources." +} diff --git a/modules/htc_res_defs/main.tf b/modules/htc_res_defs/main.tf index 23d75c6..0285567 100644 --- a/modules/htc_res_defs/main.tf +++ b/modules/htc_res_defs/main.tf @@ -1,18 +1,10 @@ -resource "humanitec_resource_account" "cluster_account" { - id = "${var.prefix}cluster" - name = "${var.prefix}cluster" - type = "gcp" - - credentials = var.k8s_credentials -} - resource "humanitec_resource_definition" "k8s_cluster" { driver_type = "humanitec/k8s-cluster-gke" id = "${var.prefix}cluster" name = "${var.prefix}cluster" type = "k8s-cluster" - driver_account = humanitec_resource_account.cluster_account.id + driver_account = var.humanitec_cloud_account driver_inputs = { values_string = jsonencode({ "name" = var.k8s_cluster_name diff --git a/modules/htc_res_defs/variables.tf b/modules/htc_res_defs/variables.tf index 94fceba..a3df3fc 100644 --- a/modules/htc_res_defs/variables.tf +++ b/modules/htc_res_defs/variables.tf @@ -1,4 +1,3 @@ - variable "k8s_cluster_name" { type = string description = "The name of the cluster." @@ -32,3 +31,8 @@ variable "prefix" { description = "A prefix that will be attached to all IDs created in Humanitec." default = "" } + +variable "humanitec_cloud_account" { + type = string + description = "The ID of the Humanitec Cloud Account." +} diff --git a/modules/network/output.tf b/modules/network/outputs.tf similarity index 100% rename from modules/network/output.tf rename to modules/network/outputs.tf