diff --git a/apps/traefik-ui/forward.tf b/apps/traefik-ui/forward.tf deleted file mode 100644 index 55f8ec7..0000000 --- a/apps/traefik-ui/forward.tf +++ /dev/null @@ -1,160 +0,0 @@ -locals { - authentik-token = data.kubernetes_secret_v1.authentik.data["AUTHENTIK_BOOTSTRAP_TOKEN"] - request_headers = { - "Content-Type" = "application/json" - Authorization = "Bearer ${local.authentik-token}" - } - 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-name = var.component == var.instance ? var.instance : format("%s-%s", var.component, var.instance) - app-icon = "dashboard/statics/icons/favicon-96x96.png" - main-group = format("app-%s", local.app-name) - sub-groups = [] - access-token-validity = "minutes=10" - rules-icons = [ for v in local.dns-names : { - "host" = "${v}" - "http" = { - "paths" = [{ - "backend" = { - "service" = local.service - } - "path" = "/${local.app-icon}" - "pathType" = "Prefix" - }] - } - }] -} - -resource "kubectl_manifest" "prj_ingress_icon" { - force_conflicts = true - yaml_body = <<-EOF - apiVersion: "networking.k8s.io/v1" - kind: "Ingress" - metadata: - name: "${var.instance}-icons" - namespace: "${var.namespace}" - labels: ${jsonencode(local.common-labels)} - spec: - ingressClassName: "${var.ingress-class}" - rules: ${jsonencode(local.rules-icons)} - tls: - - hosts: ${jsonencode(local.dns-names)} - secretName: "${var.instance}-cert" - EOF -} - -data "authentik_flow" "default-authorization-flow" { - depends_on = [authentik_group.prj_users] - slug = "default-provider-authorization-implicit-consent" -} - -resource "authentik_provider_proxy" "prj_forward" { - name = local.app-name - external_host = format("https://%s.%s", var.sub-domain, var.domain-name) - authorization_flow = data.authentik_flow.default-authorization-flow.id - mode = "forward_single" - access_token_validity = local.access-token-validity -} - - -resource "authentik_application" "prj_application" { - name = "${var.component}" - slug = "${var.component}-${var.instance}" - group = var.app-group - protocol_provider = authentik_provider_proxy.prj_forward.id - meta_launch_url = format("https://%s.%s", var.sub-domain, var.domain-name) - meta_icon = format("https://%s.%s/%s", var.sub-domain, var.domain-name, local.app-icon) -} - -resource "authentik_group" "prj_users" { - name = local.main-group - attributes = jsonencode({"${local.app-name}" = true}) -} - -resource "authentik_group" "subgroup" { - count = length(local.sub-groups) - name = format("%s-%s", local.app-name, local.sub-groups[count.index]) - parent = authentik_group.prj_users.id -} - -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 -} - -data "authentik_group" "vynil-admin" { - depends_on = [authentik_group.prj_users] # fake dependency so it is not evaluated at plan stage - name = "vynil-forward-admins" -} - -resource "authentik_policy_binding" "prj_access_users" { - target = authentik_application.prj_application.uuid - policy = authentik_policy_expression.policy.id - order = 0 -} -resource "authentik_policy_binding" "prj_access_vynil" { - target = authentik_application.prj_application.uuid - group = data.authentik_group.vynil-admin.id - order = 1 -} - -data "http" "get_forward_outpost" { - depends_on = [authentik_provider_proxy.prj_forward] - url = "http://authentik.${var.domain}-auth.svc/api/v3/outposts/instances/?name__iexact=forward" - method = "GET" - request_headers = local.request_headers - lifecycle { - postcondition { - condition = contains([200], self.status_code) - error_message = "Status code invalid" - } - } -} - -provider "restapi" { - uri = "http://authentik.${var.domain}-auth.svc/api/v3/" - headers = local.request_headers - create_method = "PATCH" - update_method = "PATCH" - destroy_method = "PATCH" - write_returns_object = true - id_attribute = "name" -} - -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]) - }) -} - -resource "kubectl_manifest" "prj_middleware" { - yaml_body = <<-EOF - apiVersion: traefik.containo.us/v1alpha1 - kind: Middleware - metadata: - name: "forward-${local.app-name}" - namespace: "${var.namespace}" - labels: ${jsonencode(local.common-labels)} - spec: - forwardAuth: - address: http://ak-outpost-forward.${var.domain}-auth.svc:9000/outpost.goauthentik.io/auth/traefik - trustForwardHeader: true - authResponseHeaders: - - X-authentik-username - # - X-authentik-groups - # - X-authentik-email - # - X-authentik-name - # - X-authentik-uid - # - X-authentik-jwt - # - X-authentik-meta-jwks - # - X-authentik-meta-outpost - # - X-authentik-meta-provider - # - X-authentik-meta-app - # - X-authentik-meta-version - EOF -} diff --git a/apps/traefik-ui/index.yaml b/apps/traefik-ui/index.yaml index e5630b6..9cc8cfe 100644 --- a/apps/traefik-ui/index.yaml +++ b/apps/traefik-ui/index.yaml @@ -6,30 +6,30 @@ metadata: name: traefik-ui description: Access to the Traefik UI options: - ingress-class: - default: traefik - examples: - - traefik - type: string domain-name: default: your_company.com examples: - your_company.com type: string - sub-domain: - default: traefik + app-group: + default: infra examples: - - traefik + - infra type: string domain: default: your-company examples: - your-company type: string - app-group: - default: infra + sub-domain: + default: traefik examples: - - infra + - traefik + type: string + ingress-class: + default: traefik + examples: + - traefik type: string issuer: default: letsencrypt-prod @@ -47,4 +47,5 @@ providers: postgresql: null restapi: true http: true + gitea: null tfaddtype: null diff --git a/apps/traefik-ui/ingress.tf b/apps/traefik-ui/ingress.tf deleted file mode 100644 index 383aa97..0000000 --- a/apps/traefik-ui/ingress.tf +++ /dev/null @@ -1,75 +0,0 @@ -locals { - dns-names = ["${var.sub-domain}.${var.domain-name}"] - middlewares = ["${var.instance}-https", "forward-${local.app-name}"] - service = { - "name" = "${var.component}-${var.instance}" - "port" = { - "number" = 80 - } - } - rules = [ for v in local.dns-names : { - "host" = "${v}" - "http" = { - "paths" = [{ - "backend" = { - "service" = local.service - } - "path" = "/" - "pathType" = "Prefix" - }] - } - }] -} - -resource "kubectl_manifest" "prj_certificate" { - yaml_body = <<-EOF - apiVersion: "cert-manager.io/v1" - kind: "Certificate" - metadata: - name: "${var.instance}" - namespace: "${var.namespace}" - labels: ${jsonencode(local.common-labels)} - spec: - secretName: "${var.instance}-cert" - dnsNames: ${jsonencode(local.dns-names)} - issuerRef: - name: "${var.issuer}" - kind: "ClusterIssuer" - group: "cert-manager.io" - EOF -} - -resource "kubectl_manifest" "prj_https_redirect" { - yaml_body = <<-EOF - apiVersion: "traefik.containo.us/v1alpha1" - kind: "Middleware" - metadata: - name: "${var.instance}-https" - namespace: "${var.namespace}" - labels: ${jsonencode(local.common-labels)} - spec: - redirectScheme: - scheme: "https" - permanent: true - EOF -} - -resource "kubectl_manifest" "prj_ingress" { - force_conflicts = true - yaml_body = <<-EOF - apiVersion: "networking.k8s.io/v1" - kind: "Ingress" - metadata: - name: "${var.instance}" - namespace: "${var.namespace}" - labels: ${jsonencode(local.common-labels)} - annotations: - "traefik.ingress.kubernetes.io/router.middlewares": "${join(",", [for m in local.middlewares : format("%s-%s@kubernetescrd", var.namespace, m)])}" - spec: - ingressClassName: "${var.ingress-class}" - rules: ${jsonencode(local.rules)} - tls: - - hosts: ${jsonencode(local.dns-names)} - secretName: "${var.instance}-cert" - EOF -} diff --git a/apps/traefik-ui/presentation.tf b/apps/traefik-ui/presentation.tf new file mode 100644 index 0000000..fb30b46 --- /dev/null +++ b/apps/traefik-ui/presentation.tf @@ -0,0 +1,76 @@ +locals { + dns-name = "${var.sub-domain}.${var.domain-name}" + dns-names = [local.dns-name] + app-name = var.component == var.instance ? var.instance : format("%s-%s", var.component, var.instance) + icon = "dashboard/statics/icons/favicon-96x96.png" + request_headers = { + "Content-Type" = "application/json" + Authorization = "Bearer ${data.kubernetes_secret_v1.authentik.data["AUTHENTIK_BOOTSTRAP_TOKEN"]}" + } + service = { + "name" = "${var.component}-${var.instance}" + "port" = { + "number" = 80 + } + } +} + +module "ingress" { + source = "/dist/modules/ingress" + component = var.component + instance = var.instance + namespace = var.namespace + issuer = var.issuer + ingress-class = var.ingress-class + labels = local.common-labels + dns-names = local.dns-names + middlewares = ["${var.instance}-https", "forward-${local.app-name}"] + service = local.service + providers = { + kubectl = kubectl + } +} + +module "application" { + source = "/dist/modules/application" + component = var.component + instance = var.instance + app-group = var.app-group + sub-domain = var.sub-domain + domain-name = var.domain-name + icon = local.icon + protocol_provider = module.forward.provider-id + providers = { + authentik = authentik + } +} + +provider "restapi" { + uri = "http://authentik.${var.domain}-auth.svc/api/v3/" + headers = local.request_headers + create_method = "PATCH" + update_method = "PATCH" + destroy_method = "PATCH" + write_returns_object = true + id_attribute = "name" +} + +module "forward" { + source = "/dist/modules/forward" + component = var.component + instance = var.instance + domain = var.domain + namespace = var.namespace + ingress-class = var.ingress-class + labels = local.common-labels + dns-names = local.dns-names + service = local.service + icon = local.icon + request_headers = local.request_headers + providers = { + restapi = restapi + http = http + kubectl = kubectl + authentik = authentik + } +}