From 1e1cedcaebb8cf7cc32920bac23533dba297aac0 Mon Sep 17 00:00:00 2001 From: Xavier Mortelette Date: Tue, 6 Feb 2024 11:03:20 +0100 Subject: [PATCH] Refacto and add modules --- application/application.tf | 24 +++--- application/outputs.tf | 8 +- application/variables.tf | 4 + backup/backup.tf | 21 +++-- backup/providers.tf | 4 +- backup/variables.tf | 48 ++++++------ forward/forward.tf | 24 +++--- forward/outputs.tf | 6 +- forward/providers.tf | 16 ++-- forward/variables.tf | 20 +++-- ingress/ingress.tf | 25 +++--- ingress/outputs.tf | 2 +- ingress/providers.tf | 4 +- ingress/variables.tf | 50 ++++++------ ldap/ldap.tf | 157 +++++++++++++++++++++++++++++++++++++ ldap/outputs.tf | 23 ++++++ ldap/providers.tf | 24 ++++++ ldap/variables.tf | 25 ++++++ mongo/mongo.tf | 58 +++++++------- mongo/outputs.tf | 6 +- mongo/providers.tf | 4 +- mongo/variables.tf | 24 +++--- mysql/mysql.tf | 8 +- mysql/outpost.tf | 19 +++-- mysql/providers.tf | 8 +- oauth2/oauth2.tf | 32 ++++---- oauth2/outputs.tf | 10 +-- oauth2/providers.tf | 12 +-- postgresql/outputs.tf | 24 +++++- postgresql/postgresql.tf | 30 ++++--- postgresql/providers.tf | 4 +- postgresql/variables.tf | 40 +++++----- pvc/providers.tf | 4 +- pvc/pvc.tf | 19 +++-- pvc/variables.tf | 27 ++++--- redis/outputs.tf | 17 +++- redis/providers.tf | 4 +- redis/redis.tf | 16 ++-- redis/variables.tf | 48 ++++++------ saml/outputs.tf | 4 +- saml/providers.tf | 8 +- saml/saml.tf | 30 +++---- saml/variables.tf | 14 ++-- service/outputs.tf | 6 +- service/providers.tf | 4 +- service/svc.tf | 59 +++++++++----- service/variables.tf | 21 ++++- 47 files changed, 685 insertions(+), 360 deletions(-) create mode 100644 ldap/ldap.tf create mode 100644 ldap/outputs.tf create mode 100644 ldap/providers.tf create mode 100644 ldap/variables.tf diff --git a/application/application.tf b/application/application.tf index 1827782..866833f 100644 --- a/application/application.tf +++ b/application/application.tf @@ -1,6 +1,8 @@ locals { - app_name = (var.component == var.instance || var.component=="") ? var.instance : format("%s-%s", var.component, var.instance) - main_group = format("app-%s", local.app_name) + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" + app_name = var.app_name != "" ? var.app_name : var.component == var.instance ? var.instance : format("%s-%s", var.instance, var.component) + main_group = format("app-%s", local.app_slug) + url_icon = startswith(var.icon, "fa-") ? "fa://${var.icon}" : format("https://%s/%s", var.dns_name, var.icon) } data "authentik_group" "akadmin" { name = "authentik Admins" @@ -16,31 +18,31 @@ resource "authentik_group" "subgroup" { parent = authentik_group.groups.id } -resource "authentik_application" "prj_app" { - name = var.instance - slug = "${var.component}-${var.instance}" +resource "authentik_application" "app" { + name = var.app_name + slug = local.app_slug group = var.app_group protocol_provider = var.protocol_provider backchannel_providers = var.backchannel_providers meta_launch_url = format("https://%s", var.dns_name) - meta_icon = format("https://%s/%s", var.dns_name, var.icon) + meta_icon = local.url_icon } resource "authentik_policy_expression" "policy" { - name = local.main_group + name = "${local.app_slug}-${local.main_group}" expression = <<-EOF attr = request.user.group_attributes() return attr['${local.app_name}'] if '${local.app_name}' in attr else False EOF } -resource "authentik_policy_binding" "prj_access_users" { - target = authentik_application.prj_app.uuid +resource "authentik_policy_binding" "access_users" { + target = authentik_application.app.uuid policy = authentik_policy_expression.policy.id order = 0 } -resource "authentik_policy_binding" "prj_access_vynil" { - target = authentik_application.prj_app.uuid +resource "authentik_policy_binding" "access_vynil" { + target = authentik_application.app.uuid group = data.authentik_group.akadmin.id order = 1 } diff --git a/application/outputs.tf b/application/outputs.tf index 831f21a..7233c4c 100644 --- a/application/outputs.tf +++ b/application/outputs.tf @@ -1,10 +1,10 @@ -output "application-id" { - value = authentik_application.prj_app.uuid +output "application_id" { + value = authentik_application.app.uuid } -output "policy-id" { +output "policy_id" { value = authentik_policy_expression.policy.id } output "main_group" { value = local.main_group -} \ No newline at end of file +} diff --git a/application/variables.tf b/application/variables.tf index 3a6d05b..63f487e 100644 --- a/application/variables.tf +++ b/application/variables.tf @@ -17,6 +17,10 @@ variable "protocol_provider" { variable "dns_name" { type = string } +variable "app_name" { + type = string + default = "" +} variable "sub_groups" { type = list(string) default = [] diff --git a/backup/backup.tf b/backup/backup.tf index c526b8f..9fe6436 100644 --- a/backup/backup.tf +++ b/backup/backup.tf @@ -1,16 +1,15 @@ locals { - app_slug = (var.component == var.instance || var.component=="") ? var.instance : format("%s-%s", var.component, var.instance) + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" } resource "kubectl_manifest" "backup_schedule" { - count = var.backups.enable ? 1 : 0 - yaml_body = <<-EOF + yaml_body = <<-EOF apiVersion: k8up.io/v1 kind: Schedule metadata: - name: "${var.app_slug}-backup" + name: "${local.app_slug}-backup" namespace: "${var.namespace}" - labels: ${jsonencode(local.labels)} + labels: ${jsonencode(var.labels)} spec: backend: repoPasswordSecretRef: @@ -20,11 +19,11 @@ resource "kubectl_manifest" "backup_schedule" { accessKeyIDSecretRef: key: "${var.backups.key_id_key}" name: "${var.backups.secret_name}" - bucket: "${var.app_slug}-${var.namespace}" + bucket: "${local.app_slug}-${var.namespace}" endpoint: "${var.backups.endpoint}/restic" secretAccessKeySecretRef: key: "${var.backups.secret_key}" - name: "${var.backups.secret-name}" + name: "${var.backups.secret_name}" backup: schedule: "${var.backups.schedule.backup}" failedJobsHistoryLimit: 2 @@ -33,10 +32,10 @@ resource "kubectl_manifest" "backup_schedule" { schedule: "${var.backups.schedule.check}" prune: retention: - keepDaily: ${var.backups.retention.keepDaily} - keepMonthly: ${var.backups.retention.keepMonthly} - keepWeekly: ${var.backups.retention.keepWeekly} - keepYearly: ${var.backups.retention.keepYearly} + keepDaily: ${var.backups.retention.keep_daily} + keepMonthly: ${var.backups.retention.keep_monthly} + keepWeekly: ${var.backups.retention.keep_weekly} + keepYearly: ${var.backups.retention.keep_yearly} schedule: "${var.backups.schedule.prune}" EOF } diff --git a/backup/providers.tf b/backup/providers.tf index 45aaada..852127e 100644 --- a/backup/providers.tf +++ b/backup/providers.tf @@ -1,8 +1,8 @@ terraform { required_providers { kubectl = { - source = "gavinbunney/kubectl" - version = "~> 1.14.0" + source = "gavinbunney/kubectl" + version = "~> 1.14.0" } } } diff --git a/backup/variables.tf b/backup/variables.tf index ae57590..7a5703f 100644 --- a/backup/variables.tf +++ b/backup/variables.tf @@ -11,45 +11,45 @@ variable "labels" { type = map(string) } variable "backups" { - default = { - "enable" = false - "endpoint" = "" + default = { + "enable" = false + "endpoint" = "" "key_id_key" = "s3-id" "restic_key" = "bck-password" "retention" = { - "keepDaily" = 14 - "keepMonthly" = 12 - "keepWeekly" = 6 - "keepYearly" = 12 + "keep_daily" = 14 + "keep_monthly" = 12 + "keep_weekly" = 6 + "keep_yearly" = 12 } "schedule" = { "backup" = "30 3 * * *" - "check" = "30 5 * * 1" - "db" = "30 3 * * *" - "prune" = "30 1 * * 0" + "check" = "30 5 * * 1" + "db" = "30 3 * * *" + "prune" = "30 1 * * 0" } - "secret_key" = "s3-secret" + "secret_key" = "s3-secret" "secret_name" = "backup-settings" - "use_barman" = false + "use_barman" = false } - type = object({ - enable = optional(bool), - endpoint = optional(string), + type = object({ + enable = optional(bool), + endpoint = optional(string), key_id_key = optional(string), restic_key = optional(string), retention = optional(object({ - keepDaily = optional(number), - keepMonthly = optional(number), - keepWeekly = optional(number), - keepYearly = optional(number) + keep_daily = optional(number), + keep_monthly = optional(number), + keep_weekly = optional(number), + keep_yearly = optional(number) })), schedule = optional(object({ backup = optional(string), - check = optional(string), - prune = optional(string) + check = optional(string), + prune = optional(string) })), - secret_key = optional(string), + secret_key = optional(string), secret_name = optional(string), - use_barman = optional(bool) + use_barman = optional(bool) }) -} \ No newline at end of file +} diff --git a/forward/forward.tf b/forward/forward.tf index cf4b055..1219008 100644 --- a/forward/forward.tf +++ b/forward/forward.tf @@ -1,12 +1,10 @@ locals { - forward_outpost_providers = jsondecode(data.http.get_forward_outpost.response_body).results[0].providers - forward_outpost_pk = jsondecode(data.http.get_forward_outpost.response_body).results[0].pk - app_slug = "${var.instance}${var.component==""?"":"-"}${var.component}" + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" forward_labels = merge(var.labels, { "app.kubernetes.io/component" = "authentik-forward" }) - main_group = format("app-%s", var.app_name) - external_url = format("https://%s", var.dns_names[0]) + main_group = format("app-%s", var.app_name) + external_url = format("https://%s", var.dns_names[0]) rules_icons = [for v in var.dns_names : { "host" = "${v}" "http" = { @@ -19,9 +17,11 @@ locals { }] } }] + forward_outpost_providers = jsondecode(data.http.get_forward_outpost.response_body).results[0].providers + forward_outpost_pk = jsondecode(data.http.get_forward_outpost.response_body).results[0].pk } -resource "kubectl_manifest" "prj_ingress_icon" { +resource "kubectl_manifest" "ingress_icon" { force_conflicts = true yaml_body = <<-EOF apiVersion: "networking.k8s.io/v1" @@ -39,20 +39,20 @@ resource "kubectl_manifest" "prj_ingress_icon" { EOF } -data "authentik_flow" "default-authorization-flow" { +data "authentik_flow" "default_authorization_flow" { slug = "default-provider-authorization-implicit-consent" } -resource "authentik_provider_proxy" "prj_forward" { +resource "authentik_provider_proxy" "forward" { name = local.app_slug external_host = local.external_url - authorization_flow = data.authentik_flow.default-authorization-flow.id + authorization_flow = data.authentik_flow.default_authorization_flow.id mode = "forward_single" access_token_validity = var.access_token_validity } data "http" "get_forward_outpost" { - depends_on = [authentik_provider_proxy.prj_forward] + depends_on = [authentik_provider_proxy.forward] url = "http://authentik.${var.domain}-auth.svc/api/v3/outposts/instances/?name__iexact=forward" method = "GET" request_headers = var.request_headers @@ -68,11 +68,11 @@ resource "restapi_object" "forward_outpost_binding" { path = "/outposts/instances/${local.forward_outpost_pk}/" data = jsonencode({ name = "forward" - providers = contains(local.forward_outpost_providers, authentik_provider_proxy.prj_forward.id) ? local.forward_outpost_providers : concat(local.forward_outpost_providers, [authentik_provider_proxy.prj_forward.id]) + providers = contains(local.forward_outpost_providers, authentik_provider_proxy.forward.id) ? local.forward_outpost_providers : concat(local.forward_outpost_providers, [authentik_provider_proxy.forward.id]) }) } -resource "kubectl_manifest" "prj_middleware" { +resource "kubectl_manifest" "middleware" { yaml_body = <<-EOF apiVersion: traefik.io/v1alpha1 kind: Middleware diff --git a/forward/outputs.tf b/forward/outputs.tf index ed063a0..4cc3e1a 100644 --- a/forward/outputs.tf +++ b/forward/outputs.tf @@ -1,5 +1,5 @@ -output "provider-id" { - value = authentik_provider_proxy.prj_forward.id +output "provider_id" { + value = authentik_provider_proxy.forward.id } output "sso_logout" { @@ -8,4 +8,4 @@ output "sso_logout" { output "middleware" { value = "${local.app_slug}-forward" -} \ No newline at end of file +} diff --git a/forward/providers.tf b/forward/providers.tf index 92c0b09..a5079b4 100644 --- a/forward/providers.tf +++ b/forward/providers.tf @@ -1,20 +1,20 @@ terraform { required_providers { kubectl = { - source = "gavinbunney/kubectl" - version = "~> 1.14.0" + source = "gavinbunney/kubectl" + version = "~> 1.14.0" } authentik = { - source = "goauthentik/authentik" - version = "~> 2023.5.0" + source = "goauthentik/authentik" + version = "~> 2023.5.0" } http = { - source = "hashicorp/http" - version = "~> 3.3.0" + source = "hashicorp/http" + version = "~> 3.3.0" } restapi = { - source = "Mastercard/restapi" - version = "~> 1.18.0" + source = "Mastercard/restapi" + version = "~> 1.18.0" } } } diff --git a/forward/variables.tf b/forward/variables.tf index 0a19500..23cd296 100644 --- a/forward/variables.tf +++ b/forward/variables.tf @@ -6,10 +6,6 @@ variable "instance" { type = string } -variable "icon" { - type = string -} - variable "domain" { type = string } @@ -18,12 +14,16 @@ variable "namespace" { type = string } +variable "labels" { + type = map(string) +} + variable "ingress_class" { type = string } -variable "labels" { - type = map(string) +variable "icon" { + type = string } variable "dns_names" { @@ -36,11 +36,17 @@ variable "access_token_validity" { } variable "app_name" { - type = string + type = string default = "" } variable "service" { + type = object({ + name = string + port = object({ + number = number + }) + }) } variable "request_headers" { diff --git a/ingress/ingress.tf b/ingress/ingress.tf index cc3074f..19d53aa 100644 --- a/ingress/ingress.tf +++ b/ingress/ingress.tf @@ -1,24 +1,25 @@ locals { - app_slug = "${var.instance}${var.component==""?"":"-"}${var.component}" + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" pres_labels = merge(var.labels, { "app.kubernetes.io/component" = "presentation" }) rules = [for v in var.dns_names : { "host" = "${v}" "http" = { - "paths" = [for idx, svc in var.services : { - "path" = "/${var.sub_paths[idx]}" + "paths" = [for mapper in var.services_mapping : { + "path" = "/${mapper.path}" "pathType" = "Prefix" "backend" = { - "service" = svc + "service" = mapper.service } }] } }] - tls = var.enforce_tls ? [ + secret_name = var.cert_name != "" ? var.cert_name : "${local.app_slug}-cert" + tls = var.entrypoint == "" || length(regexall(".*websecure.*", var.entrypoint)) > 0 ? [ { - secretName = var.cert_name != "" ? var.cert_name : "${local.app_slug}-cert" + secretName = local.secret_name hosts = var.dns_names } ] : [] @@ -36,8 +37,8 @@ locals { ) } -resource "kubectl_manifest" "prj_certificate" { - count = var.create_cert ? 1 : 0 +resource "kubectl_manifest" "certificate" { + count = var.cert_name == "" ? 1 : 0 yaml_body = <<-EOF apiVersion: "cert-manager.io/v1" kind: "Certificate" @@ -46,7 +47,7 @@ resource "kubectl_manifest" "prj_certificate" { namespace: "${var.namespace}" labels: ${jsonencode(local.pres_labels)} spec: - secretName: "${local.app_slug}-cert" + secretName: "${local.secret_name}" dnsNames: ${jsonencode(var.dns_names)} issuerRef: kind: "ClusterIssuer" @@ -55,8 +56,8 @@ resource "kubectl_manifest" "prj_certificate" { EOF } -resource "kubectl_manifest" "prj_https_redirect" { - count = var.create_redirect || var.component == "" ? 1 : 0 +resource "kubectl_manifest" "https_redirect" { + count = var.create_redirect ? 1 : 0 yaml_body = <<-EOF apiVersion: "traefik.io/v1alpha1" kind: "Middleware" @@ -71,7 +72,7 @@ resource "kubectl_manifest" "prj_https_redirect" { EOF } -resource "kubectl_manifest" "prj_ingress" { +resource "kubectl_manifest" "ingress" { force_conflicts = true yaml_body = <<-EOF apiVersion: "networking.k8s.io/v1" diff --git a/ingress/outputs.tf b/ingress/outputs.tf index d959947..4f660e9 100644 --- a/ingress/outputs.tf +++ b/ingress/outputs.tf @@ -1,3 +1,3 @@ output "secret_name" { - value = var.create_cert ? "${local.app_slug}-cert":"" + value = var.cert_name == "" ? "${local.app_slug}-cert" : var.cert_name } diff --git a/ingress/providers.tf b/ingress/providers.tf index d959f39..8b33b04 100644 --- a/ingress/providers.tf +++ b/ingress/providers.tf @@ -2,8 +2,8 @@ terraform { required_providers { kubectl = { - source = "gavinbunney/kubectl" - version = "~> 1.14.0" + source = "gavinbunney/kubectl" + version = "~> 1.14.0" } } } diff --git a/ingress/variables.tf b/ingress/variables.tf index 6f760d8..0d43892 100644 --- a/ingress/variables.tf +++ b/ingress/variables.tf @@ -24,35 +24,37 @@ variable "middlewares" { type = list(string) default = [] } -variable "services" { - type = list(any) + +variable "services_mapping" { + type = list(object({ + path = optional(string) + service = object({ + name= string + port = object({ + number = number + }) + }) + })) } -variable "create_redirect" { - type = bool - default = true -} -variable "create_cert" { - type = bool - default = true -} -variable "enforce_tls" { - type = bool - default = true -} -variable "sub_paths" { - type = list(string) - default = [""] -} -variable "cert_name" { - type = string - default = "" -} variable "entrypoint" { - type = string - default = "" + type = string + default = "" + description = "Define ingres support, if empty or define to websecure, tls will be activate" validation { condition = contains(["", "web", "websecure"], var.entrypoint) error_message = "Only empty \"\", web or websecure is allowed" } } + +variable "cert_name" { + type = string + default = "" + description = "Give a secret name for tls, if empty and entrypointis websecure or empty, one will be created" +} + +variable "create_redirect" { + type = bool + default = true + description = "Enfore https redirection" +} diff --git a/ldap/ldap.tf b/ldap/ldap.tf new file mode 100644 index 0000000..a5fc1da --- /dev/null +++ b/ldap/ldap.tf @@ -0,0 +1,157 @@ +locals { + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" + ldap_labels = merge(var.labels, { + "app.kubernetes.io/component" = "authentik-ldap" + }) + base_dn = format("dc=%s", join(",dc=", split(".", var.dns_name))) + base_group_dn = format("ou=groups,%s", local.base_dn) + base_user_dn = format("ou=users,%s", local.base_dn) + authentik_base_url = "http://authentik.${var.domain}-auth.svc" + ldap_outpost_providers = jsondecode(data.http.get_ldap_outpost.response_body).results[0].providers + ldap_outpost_pk = jsondecode(data.http.get_ldap_outpost.response_body).results[0].pk + + app_name = var.component == var.instance ? var.instance : format("%s-%s", var.component, var.instance) + main_group = format("app-%s", local.app_name) + sorted_group_names = reverse(distinct(sort([ + for grp in var.user_groups : grp.name + ]))) + sorted_groups = flatten([ + for name in local.sorted_group_names : [ + for grp in var.user_groups : + grp if grp.name == name + ] + ]) +} + +data "authentik_group" "vynil_admin" { + name = "vynil-ldap-admins" +} + +resource "authentik_group" "groups" { + count = length(local.sorted_groups) + name = local.sorted_groups[count.index].name + attributes = jsonencode({ "${local.app_name}" = true }) +} + +data "authentik_group" "readed_groups" { + depends_on = [authentik_group.groups] + count = length(local.sorted_groups) + name = local.sorted_groups[count.index].name +} + +resource "authentik_application" "application_ldap" { + name = local.app_slug + slug = "${local.app_slug}-ldap" + protocol_provider = authentik_provider_ldap.provider_ldap.id + meta_launch_url = "blank://blank" +} + +resource "authentik_policy_expression" "policy" { + name = local.main_group + expression = <<-EOF + attr = request.user.group_attributes() + return attr['${local.app_name}'] if '${local.app_name}' in attr else False + EOF +} + +resource "authentik_policy_binding" "ldap_access_users" { + target = authentik_application.application_ldap.uuid + policy = authentik_policy_expression.policy.id + order = 0 +} +resource "authentik_policy_binding" "ldap_access_ldap" { + target = authentik_application.application_ldap.uuid + group = authentik_group.ldapsearch.id + order = 1 +} +resource "authentik_policy_binding" "ldap_access_vynil" { + target = authentik_application.application_ldap.uuid + group = data.authentik_group.vynil_admin.id + order = 2 +} + + +resource "kubectl_manifest" "ldap" { + ignore_fields = ["metadata.annotations"] + yaml_body = <<-EOF + apiVersion: "secretgenerator.mittwald.de/v1alpha1" + kind: "StringSecret" + metadata: + name: "${local.app_slug}-ldapsearch" + namespace: "${var.namespace}" + labels: ${jsonencode(local.ldap_labels)} + data: + LDAP_ADMIN_USR: "${local.app_slug}-ldapsearch" + spec: + forceRegenerate: false + fields: + - fieldName: "LDAP_ADMIN_PASS" + length: "32" + EOF +} + +data "kubernetes_secret_v1" "ldap_password" { + depends_on = [kubectl_manifest.ldap] + metadata { + name = kubectl_manifest.ldap.name + namespace = var.namespace + } +} + +resource "authentik_user" "ldapsearch" { + username = "${local.app_slug}-ldapsearch" + name = "${local.app_slug}-ldapsearch" +} + +resource "authentik_group" "ldapsearch" { + name = "${local.app_slug}-ldapsearch" + users = [authentik_user.ldapsearch.id] +} + + +data "http" "ldapsearch_password" { + url = "${local.authentik_base_url}/api/v3/core/users/${authentik_user.ldapsearch.id}/set_password/" + method = "POST" + request_headers = var.request_headers + request_body = jsonencode({ + password = data.kubernetes_secret_v1.ldap_password.data["LDAP_ADMIN_PASS"] + }) + lifecycle { + postcondition { + condition = contains([201, 204], self.status_code) + error_message = "Status code invalid" + } + } +} + +data "authentik_flow" "ldap_authentication_flow" { + slug = "ldap-authentication-flow" +} + +resource "authentik_provider_ldap" "provider_ldap" { + name = "${local.app_slug}-ldap" + base_dn = local.base_dn + search_group = authentik_group.ldapsearch.id + bind_flow = data.authentik_flow.ldap_authentication_flow.id +} + +data "http" "get_ldap_outpost" { + depends_on = [authentik_policy_binding.ldap_access_users] # fake dependency so it is not evaluated at plan stage + url = "${local.authentik_base_url}/api/v3/outposts/instances/?name__iexact=ldap" + method = "GET" + request_headers = var.request_headers + lifecycle { + postcondition { + condition = contains([200], self.status_code) + error_message = "Status code invalid" + } + } +} + +resource "restapi_object" "ldap_outpost_binding" { + path = "/outposts/instances/${local.ldap_outpost_pk}/" + data = jsonencode({ + name = "ldap" + providers = contains(local.ldap_outpost_providers, authentik_provider_ldap.provider_ldap.id) ? local.ldap_outpost_providers : concat(local.ldap_outpost_providers, [authentik_provider_ldap.provider_ldap.id]) + }) +} diff --git a/ldap/outputs.tf b/ldap/outputs.tf new file mode 100644 index 0000000..a0076c1 --- /dev/null +++ b/ldap/outputs.tf @@ -0,0 +1,23 @@ +output "provider_id" { + value = authentik_provider_ldap.provider_ldap.id +} + +output "ldap_address" { + value = "ak-outpost-ldap.${var.domain}-auth.svc" +} + +output "ldap_search_account" { + value = "${local.app_slug}-ldapsearch" +} + +output "base_dn" { + value = local.base_dn +} + +output "base_group_dn" { + value = local.base_group_dn +} + +output "base_user_dn" { + value = local.base_user_dn +} diff --git a/ldap/providers.tf b/ldap/providers.tf new file mode 100644 index 0000000..f9fb97f --- /dev/null +++ b/ldap/providers.tf @@ -0,0 +1,24 @@ +terraform { + required_providers { + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 2.20.0" + } + kubectl = { + source = "gavinbunney/kubectl" + version = "~> 1.14.0" + } + authentik = { + source = "goauthentik/authentik" + version = "~> 2023.5.0" + } + http = { + source = "hashicorp/http" + version = "~> 3.3.0" + } + restapi = { + source = "Mastercard/restapi" + version = "~> 1.18.0" + } + } +} diff --git a/ldap/variables.tf b/ldap/variables.tf new file mode 100644 index 0000000..46855df --- /dev/null +++ b/ldap/variables.tf @@ -0,0 +1,25 @@ +variable "component" { + type = string +} +variable "instance" { + type = string +} +variable "domain" { + type = string +} +variable "namespace" { + type = string +} +variable "labels" { + type = map(string) +} +variable "dns_name" { + type = string +} +variable "request_headers" { + type = map(string) +} +variable "user_groups" { + type = map(string) + default = {} +} diff --git a/mongo/mongo.tf b/mongo/mongo.tf index 6fb9803..552e2d4 100644 --- a/mongo/mongo.tf +++ b/mongo/mongo.tf @@ -1,21 +1,21 @@ locals { - app_slug = (var.component == var.instance || var.component=="") ? var.instance : format("%s-%s", var.component, var.instance) - mongo-password = data.kubernetes_secret_v1.prj_mongo_secret.data["password"] - username = var.username==""?var.component==""?var.instance:var.component:var.username - db_name = var.db_name==""?var.component==""?var.instance:var.component:var.db_name - mongo-labels = merge(var.labels, { + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" + mongo_labels = merge(var.labels, { "app.kubernetes.io/component" = "mongo" }) + db_name = var.db_name == "" ? var.component == "" ? var.instance : var.component : var.db_name + username = var.username == "" ? var.component == "" ? var.instance : var.component : var.username + mongo_password = data.kubernetes_secret_v1.mongo_secret.data["password"] } -resource "kubectl_manifest" "prj_mongo_secret" { +resource "kubectl_manifest" "mongo_secret" { ignore_fields = ["metadata.annotations"] - yaml_body = <<-EOF + yaml_body = <<-EOF apiVersion: "secretgenerator.mittwald.de/v1alpha1" kind: "StringSecret" metadata: name: "${local.app_slug}-mongo" namespace: "${var.namespace}" - labels: ${jsonencode(local.mongo-labels)} + labels: ${jsonencode(local.mongo_labels)} spec: forceRegenerate: false fields: @@ -23,21 +23,21 @@ resource "kubectl_manifest" "prj_mongo_secret" { length: "16" EOF } -data "kubernetes_secret_v1" "prj_mongo_secret" { - depends_on = [ kubectl_manifest.prj_mongo_secret ] +data "kubernetes_secret_v1" "mongo_secret" { + depends_on = [kubectl_manifest.mongo_secret] metadata { - name = "${local.app_slug}-mongo" + name = "${local.app_slug}-mongo" namespace = var.namespace } } -resource "kubectl_manifest" "prj_mongo" { - yaml_body = <<-EOF +resource "kubectl_manifest" "mongo" { + yaml_body = <<-EOF apiVersion: mongodbcommunity.mongodb.com/v1 kind: MongoDBCommunity metadata: name: "${local.app_slug}-mongo" namespace: "${var.namespace}" - labels: ${jsonencode(local.mongo-labels)} + labels: ${jsonencode(local.mongo_labels)} spec: members: 1 type: ${var.mongo_type} @@ -52,7 +52,7 @@ resource "kubectl_manifest" "prj_mongo" { spec: containers: - name: mongod - imagePullPolicy: "${var.pullPolicy}" + imagePullPolicy: "${var.pull_policy}" resources: ${jsonencode(var.resources)} env: - name: MONGODB_NAME @@ -80,24 +80,24 @@ resource "kubectl_manifest" "prj_mongo" { scramCredentialsSecretName: "${local.app_slug}-mongo-scram" EOF } -resource "kubectl_manifest" "prj_mongo_sa" { - yaml_body = <<-EOF +resource "kubectl_manifest" "mongo_sa" { + yaml_body = <<-EOF apiVersion: v1 kind: ServiceAccount metadata: - name: "mongodb-database" + name: "${local.app_slug}-mongodb-database" namespace: "${var.namespace}" - labels: ${jsonencode(local.mongo-labels)} + labels: ${jsonencode(local.mongo_labels)} EOF } -resource "kubectl_manifest" "prj_mongo_role" { - yaml_body = <<-EOF +resource "kubectl_manifest" "mongo_role" { + yaml_body = <<-EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: "mongodb-database" + name: "${local.app_slug}-mongodb-database" namespace: "${var.namespace}" - labels: ${jsonencode(local.mongo-labels)} + labels: ${jsonencode(local.mongo_labels)} rules: - apiGroups: [""] resources: ["secrets"] @@ -107,20 +107,20 @@ resource "kubectl_manifest" "prj_mongo_role" { verbs: ["patch", "delete", "get"] EOF } -resource "kubectl_manifest" "prj_mongo_rb" { - yaml_body = <<-EOF +resource "kubectl_manifest" "mongo_rb" { + yaml_body = <<-EOF apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: "mongodb-database" + name: "${local.app_slug}-mongodb-database" namespace: "${var.namespace}" - labels: ${jsonencode(local.mongo-labels)} + labels: ${jsonencode(local.mongo_labels)} subjects: - kind: ServiceAccount - name: mongodb-database + name: ${local.app_slug}-mongodb-database roleRef: kind: Role - name: mongodb-database + name: ${local.app_slug}-mongodb-database apiGroup: rbac.authorization.k8s.io EOF } diff --git a/mongo/outputs.tf b/mongo/outputs.tf index db5158e..00253d6 100644 --- a/mongo/outputs.tf +++ b/mongo/outputs.tf @@ -1,11 +1,11 @@ output "url" { - value = "mongodb://${local.username}:${local.mongo-password}@${local.app_slug}-mongo-svc.${var.namespace}.svc:27017/${local.db_name}" + value = "mongodb://${urlencode(local.username)}:${urlencode(local.mongo_password)}@${local.app_slug}-mongo-svc.${var.namespace}.svc:27017/${local.db_name}" } output "service" { value = "${local.app_slug}-mongo-svc.${var.namespace}.svc" } output "password" { - value = local.mongo-password + value = local.mongo_password } output "username" { value = local.username @@ -16,6 +16,6 @@ output "db_name" { output "secret" { value = { name = "${local.app_slug}-mongo" - key = "password" + key = "password" } } diff --git a/mongo/providers.tf b/mongo/providers.tf index 45aaada..852127e 100644 --- a/mongo/providers.tf +++ b/mongo/providers.tf @@ -1,8 +1,8 @@ terraform { required_providers { kubectl = { - source = "gavinbunney/kubectl" - version = "~> 1.14.0" + source = "gavinbunney/kubectl" + version = "~> 1.14.0" } } } diff --git a/mongo/variables.tf b/mongo/variables.tf index d49d08f..5d1553c 100644 --- a/mongo/variables.tf +++ b/mongo/variables.tf @@ -11,45 +11,45 @@ variable "labels" { type = map(string) } variable "db_name" { - type = string + type = string default = "" } variable "username" { - type = string + type = string default = "" } variable "mongo_version" { - type = string + type = string default = "6.0.13" } variable "mongo_type" { - type = string + type = string default = "ReplicaSet" } -variable "pullPolicy" { - type = string +variable "pull_policy" { + type = string default = "IfNotPresent" } variable "resources" { - type = object({ + type = object({ limits = optional(object({ - cpu = string + cpu = string memory = string })) requests = optional(object({ - cpu = string + cpu = string memory = string })) }) default = { limits = { - cpu = "1" + cpu = "1" memory = "1100M" } requests = { - cpu = "0.3" + cpu = "0.3" memory = "400M" } } -} \ No newline at end of file +} diff --git a/mysql/mysql.tf b/mysql/mysql.tf index fa6eb8f..5e3fc69 100644 --- a/mysql/mysql.tf +++ b/mysql/mysql.tf @@ -1,8 +1,8 @@ locals { + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" mysql_labels = merge(var.labels, { "app.kubernetes.io/component" = "mysql" }) - app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" mysql_host = "${local.app_slug}-mysql.${var.namespace}.svc" mysql_username = data.kubernetes_secret_v1.mysql_secret.data["rootUser"] mysql_password = data.kubernetes_secret_v1.mysql_secret.data["rootPassword"] @@ -36,12 +36,12 @@ data "kubernetes_secret_v1" "mysql_secret" { metadata { name = "${local.app_slug}-mysql" namespace = var.namespace - labels = local.mysql_labels + labels = local.mysql_labels } } resource "kubectl_manifest" "mysql" { - yaml_body = <<-EOF + yaml_body = <<-EOF apiVersion: mysql.oracle.com/v2 kind: InnoDBCluster metadata: @@ -66,7 +66,7 @@ resource "kubectl_manifest" "mysql" { } resource "time_sleep" "wait_mysql_ready" { - depends_on = [kubectl_manifest.mysql] + depends_on = [kubectl_manifest.mysql] create_duration = "45s" } diff --git a/mysql/outpost.tf b/mysql/outpost.tf index 0106dd9..06b6e56 100644 --- a/mysql/outpost.tf +++ b/mysql/outpost.tf @@ -1,12 +1,15 @@ -output "dns_names" { - value = [ - "${local.app_slug}-mysql", - "${local.app_slug}-mysql-instances" - ] +output "conn_string" { + value = "mysql://${urlencode(data.kubernetes_secret_v1.mysql_secret.data["username"])}:${urlencode(data.kubernetes_secret_v1.mysql_secret.data["password"])}@${local.app_slug}-mysql.${var.namespace}.svc:3306/${var.database}" } -output "mysql_host" { - value =" ${local.app_slug}-mysql" + +output "service" { + value = "${local.app_slug}-mysql.${var.namespace}.svc" } + +output "host" { + value = "${local.app_slug}-mysql" +} + output "secret_name" { value = "${local.app_slug}-db" -} \ No newline at end of file +} diff --git a/mysql/providers.tf b/mysql/providers.tf index 2f82f2d..5244d86 100644 --- a/mysql/providers.tf +++ b/mysql/providers.tf @@ -1,12 +1,12 @@ terraform { required_providers { kubectl = { - source = "gavinbunney/kubectl" - version = "~> 1.14.0" + source = "gavinbunney/kubectl" + version = "~> 1.14.0" } mysql = { - source = "TakatoHano/mysql" + source = "TakatoHano/mysql" version = "1.2.1" } } -} \ No newline at end of file +} diff --git a/oauth2/oauth2.tf b/oauth2/oauth2.tf index 4b2d2aa..a1a56f2 100644 --- a/oauth2/oauth2.tf +++ b/oauth2/oauth2.tf @@ -1,10 +1,10 @@ locals { - app_slug = "${var.instance}${var.component==""?"":"-"}${var.component}" + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" oauth2_labels = merge(var.labels, { "app.kubernetes.io/component" = "authentik-oauth2" }) } -resource "kubectl_manifest" "oauth2-secret" { +resource "kubectl_manifest" "oauth2_secret" { ignore_fields = ["metadata.annotations"] yaml_body = <<-EOF apiVersion: "secretgenerator.mittwald.de/v1alpha1" @@ -20,12 +20,12 @@ resource "kubectl_manifest" "oauth2-secret" { length: "32" EOF } -data "kubernetes_secret_v1" "oauth2-client-id" { - depends_on = [kubectl_manifest.oauth2-secret] +data "kubernetes_secret_v1" "oauth2_client_id" { + depends_on = [kubectl_manifest.oauth2_secret] metadata { - name = kubectl_manifest.oauth2-secret.name + name = kubectl_manifest.oauth2_secret.name namespace = var.namespace - labels = local.oauth2_labels + labels = local.oauth2_labels } } @@ -40,18 +40,18 @@ data "authentik_scope_mapping" "oauth2" { "goauthentik.io/providers/oauth2/scope-profile" ] } -data "authentik_flow" "default-authorization-flow" { +data "authentik_flow" "default_authorization_flow" { slug = "default-provider-authorization-implicit-consent" } -data "authentik_flow" "default-authentication-flow" { +data "authentik_flow" "default_authentication_flow" { slug = "default-authentication-flow" } resource "authentik_provider_oauth2" "oauth2" { - name = "${local.app_slug}" - client_id = data.kubernetes_secret_v1.oauth2-client-id.data["client-id"] - authentication_flow = data.authentik_flow.default-authentication-flow.id - authorization_flow = data.authentik_flow.default-authorization-flow.id + name = local.app_slug + client_id = data.kubernetes_secret_v1.oauth2_client_id.data["client-id"] + authentication_flow = data.authentik_flow.default_authentication_flow.id + authorization_flow = data.authentik_flow.default_authorization_flow.id client_type = "confidential" sub_mode = "user_username" signing_key = data.authentik_certificate_key_pair.ca.id @@ -61,7 +61,7 @@ resource "authentik_provider_oauth2" "oauth2" { ] } -resource "kubernetes_secret_v1" "oauth2-client-secret" { +resource "kubernetes_secret_v1" "oauth2_client_secret" { metadata { name = "${local.app_slug}-secret" namespace = var.namespace @@ -72,10 +72,10 @@ resource "kubernetes_secret_v1" "oauth2-client-secret" { } } -data "kubernetes_secret_v1" "oauth2-client-secret" { - depends_on = [kubernetes_secret_v1.oauth2-client-secret] +data "kubernetes_secret_v1" "oauth2_client_secret" { + depends_on = [kubernetes_secret_v1.oauth2_client_secret] metadata { - name = kubernetes_secret_v1.oauth2-client-secret.metadata[0].name + name = kubernetes_secret_v1.oauth2_client_secret.metadata[0].name namespace = var.namespace } } diff --git a/oauth2/outputs.tf b/oauth2/outputs.tf index c7cc20c..f07c264 100644 --- a/oauth2/outputs.tf +++ b/oauth2/outputs.tf @@ -1,4 +1,4 @@ -output "provider-id" { +output "provider_id" { value = authentik_provider_oauth2.oauth2.id } @@ -18,17 +18,17 @@ output "sso_token_url" { value = "https://${data.kubernetes_ingress_v1.authentik.spec[0].rule[0].host}/application/o/token/" } output "client_id" { - value = data.kubernetes_secret_v1.oauth2-client-id.data["client-id"] + value = data.kubernetes_secret_v1.oauth2_client_id.data["client-id"] } output "client_secret" { - value = data.kubernetes_secret_v1.oauth2-client-secret.data["client-secret"] + value = data.kubernetes_secret_v1.oauth2_client_secret.data["client-secret"] } output "secret_client_id_name" { - value = kubectl_manifest.oauth2-secret.name + value = kubectl_manifest.oauth2_secret.name } output "secret_client_secret_name" { - value = kubernetes_secret_v1.oauth2-client-secret.metadata[0].name + value = kubernetes_secret_v1.oauth2_client_secret.metadata[0].name } output "secret_client_id_key" { value = "client-id" diff --git a/oauth2/providers.tf b/oauth2/providers.tf index 9424f6f..fd4545c 100644 --- a/oauth2/providers.tf +++ b/oauth2/providers.tf @@ -2,16 +2,16 @@ terraform { required_providers { kubernetes = { - source = "hashicorp/kubernetes" - version = "~> 2.20.0" + source = "hashicorp/kubernetes" + version = "~> 2.20.0" } kubectl = { - source = "gavinbunney/kubectl" - version = "~> 1.14.0" + source = "gavinbunney/kubectl" + version = "~> 1.14.0" } authentik = { - source = "goauthentik/authentik" - version = "~> 2023.5.0" + source = "goauthentik/authentik" + version = "~> 2023.5.0" } } } diff --git a/postgresql/outputs.tf b/postgresql/outputs.tf index d4d88df..542e8e5 100644 --- a/postgresql/outputs.tf +++ b/postgresql/outputs.tf @@ -1,3 +1,23 @@ -output "host" { - value = "${var.app_slug}-redis.${var.namespace}.svc" +output "conn_string" { + value = "postgres://${urlencode(data.kubernetes_secret_v1.credentials.data["username"])}:${urlencode(data.kubernetes_secret_v1.credentials.data["password"])}@${local.app_slug}-pg-rw.${var.namespace}.svc:5432/${var.component}" } + +output "service" { + value = "${local.app_slug}-pg-rw.${var.namespace}.svc" +} + +output "db_host" { + value = "${local.app_slug}-pg-rw" +} + +output "db_name" { + value = var.component +} + +output "db_port" { + value = "5432" +} + +output "secret_name" { + value = "${local.app_slug}-pg-app" +} \ No newline at end of file diff --git a/postgresql/postgresql.tf b/postgresql/postgresql.tf index 63341dc..9aa5594 100644 --- a/postgresql/postgresql.tf +++ b/postgresql/postgresql.tf @@ -1,21 +1,21 @@ locals { - app_slug = (var.component == var.instance || var.component=="") ? var.instance : format("%s-%s", var.component, var.instance) - pg-labels = merge(local.labels, { + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" + pg_labels = merge(var.labels, { "app.kubernetes.io/component" = "pg" }) - pool-labels = merge(local.labels, { + pool_labels = merge(var.labels, { "app.kubernetes.io/component" = "pg-pool" }) } -resource "kubectl_manifest" "prj_pg" { +resource "kubectl_manifest" "pg" { yaml_body = join("", concat([<<-EOF apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: "${local.app_slug}-pg" namespace: "${var.namespace}" - labels: ${jsonencode(local.pg-labels)} + labels: ${jsonencode(local.pg_labels)} annotations: "k8up.io/backupcommand": "pg_dump -U postgres -d ${var.component} --clean" "k8up.io/file-extension": ".sql" @@ -34,7 +34,7 @@ resource "kubectl_manifest" "prj_pg" { ], var.backups.enable&&var.backups.use_barman?[<<-EOF backup: barmanObjectStore: - destinationPath: "s3://${var.app_slug}-${var.namespace}/" + destinationPath: "s3://${local.app_slug}-${var.namespace}/" endpointURL: "${var.backups.endpoint}/barman" s3Credentials: accessKeyId: @@ -47,7 +47,7 @@ resource "kubectl_manifest" "prj_pg" { ]:[""])) } -resource "kubectl_manifest" "prj_pg_backup" { +resource "kubectl_manifest" "pg_backup" { count = var.backups.enable ? 1:0 yaml_body = <<-EOF apiVersion: postgresql.cnpg.io/v1 @@ -55,7 +55,7 @@ resource "kubectl_manifest" "prj_pg_backup" { metadata: name: "${local.app_slug}-pg" namespace: "${var.namespace}" - labels: ${jsonencode(local.pg-labels)} + labels: ${jsonencode(local.pg_labels)} spec: schedule: "${var.backups.schedule.db}" backupOwnerReference: self @@ -64,15 +64,15 @@ resource "kubectl_manifest" "prj_pg_backup" { EOF } -resource "kubectl_manifest" "prj_pg_pool" { - depends_on = [kubectl_manifest.prj_pg] +resource "kubectl_manifest" "pg_pool" { + depends_on = [kubectl_manifest.pg] yaml_body = <<-EOF apiVersion: postgresql.cnpg.io/v1 kind: Pooler metadata: name: "${local.app_slug}-pool" namespace: "${var.namespace}" - labels: ${jsonencode(local.pool-labels)} + labels: ${jsonencode(local.pool_labels)} spec: cluster: name: "${local.app_slug}-pg" @@ -85,3 +85,11 @@ resource "kubectl_manifest" "prj_pg_pool" { default_pool_size: "10" EOF } + +data "kubernetes_secret_v1" "credentials" { + depends_on = [ kubectl_manifest.pg ] + metadata { + name = "${local.app_slug}-pg-app" + namespace = var.namespace + } +} diff --git a/postgresql/providers.tf b/postgresql/providers.tf index 45aaada..852127e 100644 --- a/postgresql/providers.tf +++ b/postgresql/providers.tf @@ -1,8 +1,8 @@ terraform { required_providers { kubectl = { - source = "gavinbunney/kubectl" - version = "~> 1.14.0" + source = "gavinbunney/kubectl" + version = "~> 1.14.0" } } } diff --git a/postgresql/variables.tf b/postgresql/variables.tf index 51ef389..d9908ca 100644 --- a/postgresql/variables.tf +++ b/postgresql/variables.tf @@ -12,52 +12,52 @@ variable "labels" { } variable "backups" { - default = { - "enable" = false - "endpoint" = "" + default = { + "enable" = false + "endpoint" = "" "key_id_key" = "s3-id" "restic_key" = "bck-password" "schedule" = { "db" = "30 3 * * *" } - "secret_key" = "s3-secret" + "secret_key" = "s3-secret" "secret_name" = "backup-settings" - "use_barman" = false + "use_barman" = false } - type = object({ - enable = optional(bool), - endpoint = optional(string), + type = object({ + enable = optional(bool), + endpoint = optional(string), key_id_key = optional(string), restic_key = optional(string), schedule = optional(object({ db = optional(string), })), - secret_key = optional(string), + secret_key = optional(string), secret_name = optional(string), - use_barman = optional(bool) + use_barman = optional(bool) }) } variable "images" { - type = object({ - postgresql = optional(object({registry = optional(string), repository = optional(string), tag = optional(number)})), + type = object({ + postgresql = optional(object({ registry = optional(string), repository = optional(string), tag = optional(number) })), }) - default = { + default = { "postgresql" = { - "registry" = "ghcr.io" + "registry" = "ghcr.io" "repository" = "cloudnative-pg/postgresql" - "tag" = 15.3 + "tag" = 15.3 } } } variable "replicas" { - type = number - default = 1 + type = number + default = 1 } variable "storage" { - type = object({ + type = object({ size = optional(string) }) - default = { + default = { "size" = "5Gi" } -} \ No newline at end of file +} diff --git a/pvc/providers.tf b/pvc/providers.tf index 45aaada..852127e 100644 --- a/pvc/providers.tf +++ b/pvc/providers.tf @@ -1,8 +1,8 @@ terraform { required_providers { kubectl = { - source = "gavinbunney/kubectl" - version = "~> 1.14.0" + source = "gavinbunney/kubectl" + version = "~> 1.14.0" } } } diff --git a/pvc/pvc.tf b/pvc/pvc.tf index 485bb3d..d37353f 100644 --- a/pvc/pvc.tf +++ b/pvc/pvc.tf @@ -1,27 +1,30 @@ locals { - app_slug = (var.component == var.instance || var.component=="") ? var.instance : format("%s-%s", var.component, var.instance) + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" + pvc_labels = merge(var.labels, { + "app.kubernetes.io/component" = "pvc" + }) pvc_spec = merge({ - "accessModes" = [var.storage.accessMode] - "volumeMode" = var.storage.type + "accessModes" = [var.storage.access_mode] + "volumeMode" = var.storage.type "resources" = { "requests" = { "storage" = "${var.storage.size}" } } - }, var.storage.volume.class != "" ?{ + }, var.storage.class != "" ? { "storageClassName" = var.storage.class - }:{}) + } : {}) } resource "kubectl_manifest" "pvc" { - yaml_body = <<-EOF + yaml_body = <<-EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: ${local.app_slug} namespace: "${var.namespace}" annotations: - k8up.io/backup: "true" - labels: ${jsonencode(local.labels)} + k8up.io/backup: "${var.backup}" + labels: ${jsonencode(local.pvc_labels)} spec: ${jsonencode(local.pvc_spec)} EOF } diff --git a/pvc/variables.tf b/pvc/variables.tf index 1e495fa..4fb5eed 100644 --- a/pvc/variables.tf +++ b/pvc/variables.tf @@ -11,16 +11,21 @@ variable "labels" { type = map(string) } variable "storage" { - type = object({ - accessMode = optional(string), - class = optional(string), - size = optional(string), - type = optional(string) + type = object({ + access_mode = optional(string), + class = optional(string), + size = optional(string), + type = optional(string) }) - default = { - "accessMode" = "ReadWriteOnce" - "class" = "" - "size" = "10Gi" - "type" = "Filesystem" + default = { + "access_mode" = "ReadWriteOnce" + "class" = "" + "size" = "10Gi" + "type" = "Filesystem" } -} \ No newline at end of file +} + +variable "backup" { + type = bool + default = true +} diff --git a/redis/outputs.tf b/redis/outputs.tf index e151de7..7ea2064 100644 --- a/redis/outputs.tf +++ b/redis/outputs.tf @@ -1,6 +1,15 @@ -output "host" { - value = "${local.app_slug}-redis.${var.namespace}.svc" -} -output "url" { +output "conn_string" { value = "redis://${local.app_slug}-redis.${var.namespace}.svc:6379" } + +output "service" { + value = "${local.app_slug}-redis.${var.namespace}.svc" +} + +output "db_host" { + value = "${local.app_slug}-redis" +} + +output "secret_name" { + value = lookup(var.password, "name", "") +} diff --git a/redis/providers.tf b/redis/providers.tf index 45aaada..852127e 100644 --- a/redis/providers.tf +++ b/redis/providers.tf @@ -1,8 +1,8 @@ terraform { required_providers { kubectl = { - source = "gavinbunney/kubectl" - version = "~> 1.14.0" + source = "gavinbunney/kubectl" + version = "~> 1.14.0" } } } diff --git a/redis/redis.tf b/redis/redis.tf index aef4b54..1eceab0 100644 --- a/redis/redis.tf +++ b/redis/redis.tf @@ -1,27 +1,27 @@ locals { - app_slug = (var.component == var.instance || var.component=="") ? var.instance : format("%s-%s", var.component, var.instance) - redis-labels = merge(var.labels, { + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" + redis_labels = merge(var.labels, { "app.kubernetes.io/component" = "redis" }) cfg = merge({ - "image" = "${var.images.redis.registry}/${var.images.redis.repository}:${var.images.redis.tag}" - "imagePullPolicy" = "${var.images.redis.pullPolicy}" - },lookup(var.password, "enabled", false)?{ + "image" = "${var.images.redis.registry}/${var.images.redis.repository}:${var.images.redis.tag}" + "imagePullPolicy" = "${var.images.redis.pull_policy}" + }, lookup(var.password, "enabled", false) ? { redisSecret = { name = lookup(var.password, "name", var.component) key = lookup(var.password, "key", "redis-password") } - }:{}) + } : {}) } resource "kubectl_manifest" "redis" { - yaml_body = <<-EOF + yaml_body = <<-EOF apiVersion: "redis.redis.opstreelabs.in/v1beta1" kind: "Redis" metadata: name: "${local.app_slug}-redis" namespace: "${var.namespace}" - labels: ${jsonencode(local.redis-labels)} + labels: ${jsonencode(local.redis_labels)} spec: kubernetesConfig: ${jsonencode(local.cfg)} storage: diff --git a/redis/variables.tf b/redis/variables.tf index 589b3f3..326b2bd 100644 --- a/redis/variables.tf +++ b/redis/variables.tf @@ -11,55 +11,55 @@ variable "labels" { type = map(string) } variable "annotations" { - type = map(string) + type = map(string) default = {} } variable "images" { - type = object({ - redis = optional(object({pullPolicy = optional(string), registry = optional(string), repository = optional(string), tag = optional(string)})), - redis_exporter = optional(object({pullPolicy = optional(string), registry = optional(string), repository = optional(string), tag = optional(string)})) + type = object({ + redis = optional(object({ pull_policy = optional(string), registry = optional(string), repository = optional(string), tag = optional(string) })), + redis_exporter = optional(object({ pull_policy = optional(string), registry = optional(string), repository = optional(string), tag = optional(string) })) }) - default = { + default = { "redis" = { - "pullPolicy" = "IfNotPresent" - "registry" = "quay.io" - "repository" = "opstree/redis" - "tag" = "v7.0.12" + "pull_policy" = "IfNotPresent" + "registry" = "quay.io" + "repository" = "opstree/redis" + "tag" = "v7.0.12" } "redis_exporter" = { - "pullPolicy" = "IfNotPresent" - "registry" = "quay.io" - "repository" = "opstree/redis-exporter" - "tag" = "v1.44.0" + "pull_policy" = "IfNotPresent" + "registry" = "quay.io" + "repository" = "opstree/redis-exporter" + "tag" = "v1.44.0" } } } variable "exporter" { - type = object({ + type = object({ enabled = optional(bool) }) - default = { + default = { "enabled" = true } } variable "password" { - type = object({ + type = object({ enabled = optional(bool), - name = optional(string), - key = optional(string) + name = optional(string), + key = optional(string) }) - default = { + default = { "enabled" = false - "name" = "" - "key" = "" + "name" = "" + "key" = "" } } variable "storage" { - type = object({ + type = object({ size = optional(string) }) - default = { + default = { "size" = "2Gi" } -} \ No newline at end of file +} diff --git a/saml/outputs.tf b/saml/outputs.tf index 851a91b..e3f31c9 100644 --- a/saml/outputs.tf +++ b/saml/outputs.tf @@ -1,3 +1,3 @@ output "provider-id" { - value = authentik_provider_saml.prj.id -} \ No newline at end of file + value = authentik_provider_saml.prj.id +} diff --git a/saml/providers.tf b/saml/providers.tf index 2e19c92..250b1a1 100644 --- a/saml/providers.tf +++ b/saml/providers.tf @@ -1,12 +1,12 @@ terraform { required_providers { kubectl = { - source = "gavinbunney/kubectl" - version = "~> 1.14.0" + source = "gavinbunney/kubectl" + version = "~> 1.14.0" } authentik = { - source = "goauthentik/authentik" - version = "~> 2023.5.0" + source = "goauthentik/authentik" + version = "~> 2023.5.0" } } } diff --git a/saml/saml.tf b/saml/saml.tf index 7c0e9bf..d69c720 100644 --- a/saml/saml.tf +++ b/saml/saml.tf @@ -1,25 +1,25 @@ -locals{ - app_slug = "${var.instance}${var.component==""?"":"-"}${var.component}" - saml_labels = merge(var.labels, { +locals { + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" + saml_labels = merge(var.labels, { "app.kubernetes.io/component" = "authentik-saml" }) } -data "authentik_flow" "default-authorization-flow" { +data "authentik_flow" "default_authorization_flow" { slug = "default-provider-authorization-implicit-consent" } -data "authentik_flow" "default-authentication-flow" { +data "authentik_flow" "default_authentication_flow" { slug = "default-authentication-flow" } data "authentik_property_mapping_saml" "saml_maps" { managed_list = [ - "goauthentik.io/providers/saml/email", - "goauthentik.io/providers/saml/groups", - "goauthentik.io/providers/saml/name", - "goauthentik.io/providers/saml/upn", - "goauthentik.io/providers/saml/uid", - "goauthentik.io/providers/saml/username", - "goauthentik.io/providers/saml/ms-windowsaccountname", + "goauthentik.io/providers/saml/email", + "goauthentik.io/providers/saml/groups", + "goauthentik.io/providers/saml/name", + "goauthentik.io/providers/saml/upn", + "goauthentik.io/providers/saml/uid", + "goauthentik.io/providers/saml/username", + "goauthentik.io/providers/saml/ms-windowsaccountname", ] } @@ -32,7 +32,7 @@ data "authentik_certificate_key_pair" "generated" { } resource "kubectl_manifest" "saml_certificate" { - yaml_body = <<-EOF + yaml_body = <<-EOF apiVersion: "cert-manager.io/v1" kind: "Certificate" metadata: @@ -51,8 +51,8 @@ resource "kubectl_manifest" "saml_certificate" { resource "authentik_provider_saml" "prj" { name = "${local.app_slug}-saml" - authentication_flow = data.authentik_flow.default-authentication-flow.id - authorization_flow = data.authentik_flow.default-authorization-flow.id + authentication_flow = data.authentik_flow.default_authentication_flow.id + authorization_flow = data.authentik_flow.default_authorization_flow.id acs_url = "https://${var.dns_names[0]}/${var.acs_path}" property_mappings = data.authentik_property_mapping_saml.saml_maps.ids name_id_mapping = data.authentik_property_mapping_saml.saml_name.id diff --git a/saml/variables.tf b/saml/variables.tf index 73e08ed..36f86cd 100644 --- a/saml/variables.tf +++ b/saml/variables.tf @@ -1,22 +1,22 @@ variable "component" { - type = string + type = string } variable "instance" { - type = string + type = string } variable "issuer" { type = string } variable "dns_names" { - type = list(string) + type = list(string) } variable "acs_path" { - type = string + type = string } variable "binding" { - type = string - default = "post" + type = string + default = "post" } variable "labels" { - type = map(string) + type = map(string) } diff --git a/service/outputs.tf b/service/outputs.tf index 6cd0e72..2fae9ea 100644 --- a/service/outputs.tf +++ b/service/outputs.tf @@ -1,11 +1,11 @@ output "name" { - value = "${local.app_slug}" + value = local.app_slug } output "default_definition" { value = { - "name" = "${local.app_slug}" + "name" = "${local.app_slug}" "port" = { "number" = var.ports[0] } } -} \ No newline at end of file +} diff --git a/service/providers.tf b/service/providers.tf index 45aaada..852127e 100644 --- a/service/providers.tf +++ b/service/providers.tf @@ -1,8 +1,8 @@ terraform { required_providers { kubectl = { - source = "gavinbunney/kubectl" - version = "~> 1.14.0" + source = "gavinbunney/kubectl" + version = "~> 1.14.0" } } } diff --git a/service/svc.tf b/service/svc.tf index 5b23ae0..66c8b3d 100644 --- a/service/svc.tf +++ b/service/svc.tf @@ -1,5 +1,5 @@ locals { - app_slug = "${var.instance}${var.component==""?"":"-"}${var.component}" + app_slug = "${var.instance}${var.component == "" ? "" : "-"}${var.component}" cluster_ports = var.svc_type == "ClusterIP" ? [for idx, target in var.targets : { "name" = target "port" = var.ports[idx] @@ -12,9 +12,10 @@ locals { "protocol" = var.protocols[idx] "targetPort" = var.ports[idx] }] : [] - lb_ports = var.svc_type == "LoadBalancer" ? [for idx, port in var.lb_ports : { - "port" = port - "targetPort" = var.ports[idx] + lb_ports = var.svc_type == "LoadBalancer" ? [for port in var.lb_ports : { + "port" = port.port.number + "name" = port.name + "targetPort" = port.port.number }] : [] node_ports = var.svc_type == "NodePort" ? [for idx, port in var.ports : { "port" = port @@ -23,35 +24,38 @@ locals { }] : [] metadata = merge( { - "name"= "${local.app_slug}" - "namespace"= var.namespace - "labels"= var.labels + "name" = local.app_slug + "namespace" = var.namespace + "labels" = var.labels }, length(var.annotations) > 0 ? { - "annotations"= var.annotations + "annotations" = var.annotations } : {} ) spec = { "ClusterIP" = { - type = "ClusterIP" - ports = local.cluster_ports - selector = var.labels + type = "ClusterIP" + ports = local.cluster_ports + selector = var.labels + ipFamilyPolicy = var.ip_family }, "ExternalName" = { - type = "ExternalName" - externalName = var.target_host - ports = local.ext_ports + type = "ExternalName" + externalName = var.target_host + ports = local.ext_ports }, "NodePort" = { - type = "NodePort" - selector = var.labels - ports = local.node_ports + type = "NodePort" + selector = var.labels + ports = local.node_ports + ipFamilyPolicy = var.ip_family }, "LoadBalancer" = { - type = "LoadBalancer" - selector = var.labels - ports = local.lb_ports + type = "LoadBalancer" + selector = var.labels + ports = local.lb_ports externalTrafficPolicy = var.lb_policy + ipFamilyPolicy = var.ip_family } } } @@ -63,3 +67,18 @@ resource "kubectl_manifest" "service" { spec: ${jsonencode(local.spec[var.svc_type])} EOF } +resource "kubectl_manifest" "endpoint" { + count = var.svc_type == "ExternalName" ? 1 : 0 + yaml_body = <<-EOF + apiVersion: v1 + kind: Endpoints + metadata: + name: "${local.app_slug}" + namespace: "${var.namespace}" + labels: ${jsonencode(var.labels)} + subsets: + - addresses: + - ip: ${var.target_host} + ports: ${jsonencode([for port in var.ports : { "port" = port }])} + EOF +} diff --git a/service/variables.tf b/service/variables.tf index 18b46bb..c99ca92 100644 --- a/service/variables.tf +++ b/service/variables.tf @@ -11,7 +11,7 @@ variable "labels" { type = map(string) } variable "annotations" { - type = map(string) + type = map(string) default = {} } variable "svc_type" { @@ -22,6 +22,16 @@ variable "svc_type" { error_message = "Only ClusterIP, ExternalName, NodePort or LoadBalancer is allowed" } } + +variable "ip_family" { + type = string + default = "PreferDualStack" + validation { + condition = contains(["SingleStack", "PreferDualStack"], var.ip_family) + error_message = "Only SingleStack or PreferDualStack is allowed" + } +} + variable "ports" { type = list(number) default = [80] @@ -51,8 +61,13 @@ variable "node_ports" { } } variable "lb_ports" { - type = list(number) - default = [8080] + type = list(object({ + name = string + port = object({ + number = number + }) + })) + default = [] } variable "lb_policy" { type = string