[ci skip] Move Terraform modules into stack directories
Move all 88 service modules (66 individual + 22 platform) from modules/kubernetes/<service>/ into their corresponding stack directories: - Service stacks: stacks/<service>/module/ - Platform stack: stacks/platform/modules/<service>/ This collocates module source code with its Terragrunt definition. Only shared utility modules remain in modules/kubernetes/: ingress_factory, setup_tls_secret, dockerhub_secret, oauth-proxy. All cross-references to shared modules updated to use correct relative paths. Verified with terragrunt run --all -- plan: 0 adds, 0 destroys across all 68 stacks.
This commit is contained in:
parent
73cb696f12
commit
e225e81ebf
614 changed files with 12075 additions and 352 deletions
243
stacks/platform/modules/traefik/middleware.tf
Normal file
243
stacks/platform/modules/traefik/middleware.tf
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
# Shared Traefik Middleware CRDs
|
||||
# These are referenced by ingress resources via annotations like:
|
||||
# "traefik.ingress.kubernetes.io/router.middlewares" = "traefik-rate-limit@kubernetescrd"
|
||||
|
||||
# Rate limiting middleware
|
||||
resource "kubernetes_manifest" "middleware_rate_limit" {
|
||||
manifest = {
|
||||
apiVersion = "traefik.io/v1alpha1"
|
||||
kind = "Middleware"
|
||||
metadata = {
|
||||
name = "rate-limit"
|
||||
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||
}
|
||||
spec = {
|
||||
rateLimit = {
|
||||
average = 5
|
||||
burst = 250
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [helm_release.traefik]
|
||||
}
|
||||
|
||||
# Authentik forward auth middleware
|
||||
resource "kubernetes_manifest" "middleware_authentik_forward_auth" {
|
||||
manifest = {
|
||||
apiVersion = "traefik.io/v1alpha1"
|
||||
kind = "Middleware"
|
||||
metadata = {
|
||||
name = "authentik-forward-auth"
|
||||
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||
}
|
||||
spec = {
|
||||
forwardAuth = {
|
||||
address = "http://ak-outpost-authentik-embedded-outpost.authentik.svc.cluster.local:9000/outpost.goauthentik.io/auth/traefik"
|
||||
trustForwardHeader = true
|
||||
authResponseHeaders = [
|
||||
"X-authentik-username",
|
||||
"X-authentik-uid",
|
||||
"X-authentik-email",
|
||||
"X-authentik-name",
|
||||
"X-authentik-groups",
|
||||
"Set-Cookie",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [helm_release.traefik]
|
||||
}
|
||||
|
||||
# IP allowlist for local-only access
|
||||
resource "kubernetes_manifest" "middleware_local_only" {
|
||||
manifest = {
|
||||
apiVersion = "traefik.io/v1alpha1"
|
||||
kind = "Middleware"
|
||||
metadata = {
|
||||
name = "local-only"
|
||||
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||
}
|
||||
spec = {
|
||||
ipAllowList = {
|
||||
sourceRange = [
|
||||
"192.168.1.0/24",
|
||||
"10.0.0.0/8",
|
||||
"fc00::/7",
|
||||
"fe80::/10",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [helm_release.traefik]
|
||||
}
|
||||
|
||||
# HTTPS redirect middleware
|
||||
resource "kubernetes_manifest" "middleware_redirect_https" {
|
||||
manifest = {
|
||||
apiVersion = "traefik.io/v1alpha1"
|
||||
kind = "Middleware"
|
||||
metadata = {
|
||||
name = "redirect-https"
|
||||
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||
}
|
||||
spec = {
|
||||
redirectScheme = {
|
||||
scheme = "https"
|
||||
permanent = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [helm_release.traefik]
|
||||
}
|
||||
|
||||
# CSP headers middleware (default)
|
||||
resource "kubernetes_manifest" "middleware_csp_headers" {
|
||||
manifest = {
|
||||
apiVersion = "traefik.io/v1alpha1"
|
||||
kind = "Middleware"
|
||||
metadata = {
|
||||
name = "csp-headers"
|
||||
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||
}
|
||||
spec = {
|
||||
headers = {
|
||||
contentSecurityPolicy = "frame-ancestors 'self' *.viktorbarzin.me viktorbarzin.me"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [helm_release.traefik]
|
||||
}
|
||||
|
||||
# CrowdSec bouncer plugin middleware
|
||||
resource "kubernetes_manifest" "middleware_crowdsec" {
|
||||
manifest = {
|
||||
apiVersion = "traefik.io/v1alpha1"
|
||||
kind = "Middleware"
|
||||
metadata = {
|
||||
name = "crowdsec"
|
||||
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||
}
|
||||
spec = {
|
||||
plugin = {
|
||||
crowdsec-bouncer = {
|
||||
crowdsecLapiKey = var.crowdsec_api_key
|
||||
crowdsecLapiHost = "crowdsec-service.crowdsec.svc.cluster.local:8080"
|
||||
crowdsecMode = "stream"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [helm_release.traefik]
|
||||
}
|
||||
|
||||
# TLS option for mTLS (client certificate auth)
|
||||
resource "kubernetes_manifest" "tls_option_mtls" {
|
||||
manifest = {
|
||||
apiVersion = "traefik.io/v1alpha1"
|
||||
kind = "TLSOption"
|
||||
metadata = {
|
||||
name = "mtls"
|
||||
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||
}
|
||||
spec = {
|
||||
clientAuth = {
|
||||
secretNames = ["ca-secret"]
|
||||
clientAuthType = "RequireAndVerifyClientCert"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [helm_release.traefik]
|
||||
}
|
||||
|
||||
# ServersTransport for backends with self-signed certificates
|
||||
resource "kubernetes_manifest" "servers_transport_insecure" {
|
||||
manifest = {
|
||||
apiVersion = "traefik.io/v1alpha1"
|
||||
kind = "ServersTransport"
|
||||
metadata = {
|
||||
name = "insecure-skip-verify"
|
||||
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||
}
|
||||
spec = {
|
||||
insecureSkipVerify = true
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [helm_release.traefik]
|
||||
}
|
||||
|
||||
# Strip Authentik auth headers/cookies before forwarding to backend
|
||||
# Useful for backends (iDRAC, TP-Link) that break when receiving extra headers
|
||||
resource "kubernetes_manifest" "middleware_strip_auth_headers" {
|
||||
manifest = {
|
||||
apiVersion = "traefik.io/v1alpha1"
|
||||
kind = "Middleware"
|
||||
metadata = {
|
||||
name = "strip-auth-headers"
|
||||
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||
}
|
||||
spec = {
|
||||
headers = {
|
||||
customRequestHeaders = {
|
||||
"X-authentik-username" = ""
|
||||
"X-authentik-uid" = ""
|
||||
"X-authentik-email" = ""
|
||||
"X-authentik-name" = ""
|
||||
"X-authentik-groups" = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [helm_release.traefik]
|
||||
}
|
||||
|
||||
# Immich-specific rate limit (higher limits for photo uploads)
|
||||
resource "kubernetes_manifest" "middleware_immich_rate_limit" {
|
||||
manifest = {
|
||||
apiVersion = "traefik.io/v1alpha1"
|
||||
kind = "Middleware"
|
||||
metadata = {
|
||||
name = "immich-rate-limit"
|
||||
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||
}
|
||||
spec = {
|
||||
rateLimit = {
|
||||
average = 100
|
||||
burst = 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [helm_release.traefik]
|
||||
}
|
||||
|
||||
# Strip Accept-Encoding header so backends send uncompressed responses.
|
||||
# Used alongside rewrite-body plugin (rybbit analytics) which fails to
|
||||
# decompress certain gzip responses (flate: corrupt input before offset 5).
|
||||
resource "kubernetes_manifest" "middleware_strip_accept_encoding" {
|
||||
manifest = {
|
||||
apiVersion = "traefik.io/v1alpha1"
|
||||
kind = "Middleware"
|
||||
metadata = {
|
||||
name = "strip-accept-encoding"
|
||||
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||
}
|
||||
spec = {
|
||||
headers = {
|
||||
customRequestHeaders = {
|
||||
"Accept-Encoding" = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [helm_release.traefik]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue