diff --git a/oauth2/oauth2.tf b/oauth2/oauth2.tf index 20b11c1..e48d09e 100644 --- a/oauth2/oauth2.tf +++ b/oauth2/oauth2.tf @@ -1,5 +1,6 @@ locals { - app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" + main_group = format("kydah-%s", local.app_slug) oauth2_labels = merge(var.labels, { "app.kubernetes.io/component" = "authentik-oauth2" }) @@ -7,35 +8,44 @@ locals { signing_id = local.cert_signing ? authentik_certificate_key_pair.name[0].id : data.authentik_certificate_key_pair.ca.id } -resource "kubectl_manifest" "secret_gen" { - yaml_body = <<-EOF - apiVersion: "secretgenerator.mittwald.de/v1alpha1" - kind: "StringSecret" - metadata: - name: "${local.app_slug}-oauth2" - namespace: "${var.namespace}" - labels: ${jsonencode(local.oauth2_labels)} - ownerReferences: ${jsonencode(var.owner_references)} - spec: - forceRegenerate: false - fields: - - fieldName: "client_id" - length: "32" - EOF -} -data "kubernetes_secret_v1" "secret_gen" { - metadata { - name = kubectl_manifest.secret_gen.name - namespace = var.namespace - } +resource "random_uuid" "client_id" { } + +# resource "kubectl_manifest" "secret_gen" { +# yaml_body = <<-EOF +# apiVersion: "secretgenerator.mittwald.de/v1alpha1" +# kind: "StringSecret" +# metadata: +# name: "${local.app_slug}-oauth2" +# namespace: "${var.namespace}" +# labels: ${jsonencode(local.oauth2_labels)} +# ownerReferences: ${jsonencode(var.owner_references)} +# spec: +# forceRegenerate: false +# fields: +# - fieldName: "client_id" +# length: "32" +# EOF +# } +# data "kubernetes_secret_v1" "secret_gen" { +# metadata { +# name = kubectl_manifest.secret_gen.name +# namespace = var.namespace +# } +# } data "authentik_certificate_key_pair" "ca" { name = "authentik Self-signed Certificate" } + +resource "authentik_property_mapping_provider_scope" "app_scope" { + count = var.scope_attributes != "" ? 1 : 0 + name = local.app_slug + scope_name = local.app_slug + expression = var.scope_attributes +} + data "authentik_property_mapping_provider_scope" "oauth2" { - managed_list = [ - for scope in var.scopes : "goauthentik.io/providers/oauth2/${scope}" - ] + managed_list = [for scope in var.scopes : "goauthentik.io/providers/oauth2/${scope}"] } data "authentik_flow" "default_authorization_flow" { slug = "default-provider-authorization-implicit-consent" @@ -48,17 +58,25 @@ data "authentik_flow" "default_invalidation_flow" { } resource "authentik_group" "app_group" { - name = local.app_slug - attributes = jsonencode({ "app_slug" = local.app_slug }) + name = local.main_group + attributes = jsonencode({ + "${local.app_slug}" = { + "kydah_instance" = var.instance + "kydah_component" = var.component + } + }) } -resource "authentik_group" "groups" { +resource "authentik_group" "sub_groups" { for_each = var.group_mapping - name = each.key + name = format("%s-%s", local.main_group, each.key) parent = authentik_group.app_group.id attributes = jsonencode({ - "app_slug" = local.app_slug - "gen_group_name" = each.value + "${local.app_slug}" = { + "kydah_instance" = var.instance + "kydah_component" = var.component + "kydah_app_group" = each.value + } }) } @@ -78,15 +96,19 @@ resource "authentik_certificate_key_pair" "name" { } resource "authentik_provider_oauth2" "oauth2" { + depends_on = [authentik_property_mapping_provider_scope.app_scope] name = local.app_slug - client_id = data.kubernetes_secret_v1.secret_gen.data.client_id + client_id = random_uuid.client_id.result authentication_flow = data.authentik_flow.default_authentication_flow.id authorization_flow = data.authentik_flow.default_authorization_flow.id invalidation_flow = data.authentik_flow.default_invalidation_flow.id client_type = var.client_type sub_mode = "user_username" signing_key = local.signing_id - property_mappings = data.authentik_property_mapping_provider_scope.oauth2.ids + property_mappings = concat( + data.authentik_property_mapping_provider_scope.oauth2.ids, + var.scope_attributes != "" ? [authentik_property_mapping_provider_scope.app_scope[0].id] : [] + ) redirect_uris = [ "https://${var.redirect_path != "" ? "${var.dns_name}/${var.redirect_path}" : var.dns_name}" ] @@ -100,7 +122,7 @@ data "kubernetes_ingress_v1" "authentik" { } resource "kubectl_manifest" "oauth2_client_secret" { - force_new = true + # force_new = true yaml_body = <<-EOF apiVersion: v1 kind: Secret @@ -111,7 +133,7 @@ resource "kubectl_manifest" "oauth2_client_secret" { ownerReferences: ${jsonencode(var.owner_references)} data: oidc_endpoint: "${base64encode("https://${data.kubernetes_ingress_v1.authentik.spec[0].rule[0].host}/application/o/${local.app_slug}/")}" - client_id: "${base64encode(data.kubernetes_secret_v1.secret_gen.data.client_id)}" + client_id: "${base64encode(random_uuid.client_id.result)}" client_secret: "${base64encode(authentik_provider_oauth2.oauth2.client_secret)}" EOF } diff --git a/oauth2/outputs.tf b/oauth2/outputs.tf index 4747ab1..ffa188e 100644 --- a/oauth2/outputs.tf +++ b/oauth2/outputs.tf @@ -23,7 +23,7 @@ output "sso_token_url" { } output "client_id" { - value = data.kubernetes_secret_v1.secret_gen.data.client_id + value = random_uuid.client_id.result } output "client_secret" { diff --git a/oauth2/providers.tf b/oauth2/providers.tf index f04752c..a612eab 100644 --- a/oauth2/providers.tf +++ b/oauth2/providers.tf @@ -14,5 +14,9 @@ terraform { source = "registry.terraform.io/goauthentik/authentik" version = "2024.10.0" } + random = { + source = "hashicorp/random" + version = "3.6.3" + } } } diff --git a/oauth2/variables.tf b/oauth2/variables.tf index d092bee..428a585 100644 --- a/oauth2/variables.tf +++ b/oauth2/variables.tf @@ -23,7 +23,7 @@ variable "redirect_path" { variable "group_mapping" { type = map(string) default = {} - description = "Group mapping where key application group and value the generic group name" + description = "Group mapping where key is authentik suffix group name and value is the application group name" } variable "owner_references" { type = list(object({})) @@ -39,6 +39,11 @@ variable "scopes" { "scope-profile", ] } +variable "scope_attributes" { + type = string + description = "Authentik expression for scope mapping" + default = "" +} variable "client_type" { type = string description = "OAuth client type confidential / public(PKCE)" diff --git a/postgresql/providers.tf b/postgresql/providers.tf index 852127e..a4674ce 100644 --- a/postgresql/providers.tf +++ b/postgresql/providers.tf @@ -1,5 +1,10 @@ terraform { + required_version = ">= 1.0" required_providers { + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 2.20.0" + } kubectl = { source = "gavinbunney/kubectl" version = "~> 1.14.0" diff --git a/postgresql/variables.tf b/postgresql/variables.tf index d9908ca..00e7569 100644 --- a/postgresql/variables.tf +++ b/postgresql/variables.tf @@ -25,21 +25,25 @@ variable "backups" { "use_barman" = false } type = object({ - enable = optional(bool), - endpoint = optional(string), - key_id_key = optional(string), - restic_key = optional(string), + enable = optional(bool, false), + endpoint = optional(string, ""), + key_id_key = optional(string, "s3-id"), + restic_key = optional(string, "bck-password"), schedule = optional(object({ - db = optional(string), - })), - secret_key = optional(string), - secret_name = optional(string), - use_barman = optional(bool) + db = string, + }), { db = "30 3 * * *" }), + secret_key = optional(string, "s3-secret"), + secret_name = optional(string, "backup-settings"), + use_barman = optional(bool, false) }) } variable "images" { type = object({ - postgresql = optional(object({ registry = optional(string), repository = optional(string), tag = optional(number) })), + postgresql = optional(object({ + registry = optional(string), + repository = optional(string), + tag = optional(number) + })), }) default = { "postgresql" = {