Files
AFC-Demo/terraform/ingress.tf
T

231 lines
4.9 KiB
Terraform
Raw Normal View History

# Install nginx-ingress-controller via Helm
resource "helm_release" "nginx_ingress" {
count = var.ingress_enabled ? 1 : 0
name = "ingress-nginx"
repository = "https://kubernetes.github.io/ingress-nginx"
chart = "ingress-nginx"
version = "4.11.3"
namespace = "ingress-nginx"
create_namespace = true
set {
name = "controller.service.type"
value = "LoadBalancer"
}
set {
name = "controller.service.annotations.service\\.beta\\.kubernetes\\.io/azure-load-balancer-health-probe-request-path"
value = "/healthz"
}
set {
name = "controller.metrics.enabled"
value = "true"
}
set {
name = "controller.podAnnotations.prometheus\\.io/scrape"
value = "true"
}
set {
name = "controller.podAnnotations.prometheus\\.io/port"
value = "10254"
}
# Resource limits
set {
name = "controller.resources.requests.cpu"
value = "100m"
}
set {
name = "controller.resources.requests.memory"
value = "128Mi"
}
set {
name = "controller.resources.limits.cpu"
value = "500m"
}
set {
name = "controller.resources.limits.memory"
value = "512Mi"
}
# Enable rate limiting
set {
name = "controller.config.limit-req-status-code"
value = "429"
}
timeout = 600
}
# Wait for nginx-ingress to be ready and get LoadBalancer IP
data "kubernetes_service" "ingress_nginx" {
count = var.ingress_enabled ? 1 : 0
metadata {
name = "ingress-nginx-controller"
namespace = "ingress-nginx"
}
depends_on = [
helm_release.nginx_ingress
]
}
# Install cert-manager for SSL/TLS (optional)
resource "helm_release" "cert_manager" {
count = var.ssl_enabled ? 1 : 0
name = "cert-manager"
repository = "https://charts.jetstack.io"
chart = "cert-manager"
version = "v1.16.2"
namespace = "cert-manager"
create_namespace = true
set {
name = "crds.enabled"
value = "true"
}
set {
name = "global.leaderElection.namespace"
value = "cert-manager"
}
timeout = 600
}
# ClusterIssuer for Let's Encrypt (production)
resource "kubernetes_manifest" "letsencrypt_prod" {
count = var.ssl_enabled && var.ssl_issuer_email != "" ? 1 : 0
manifest = {
apiVersion = "cert-manager.io/v1"
kind = "ClusterIssuer"
metadata = {
name = "letsencrypt-prod"
}
spec = {
acme = {
server = "https://acme-v02.api.letsencrypt.org/directory"
email = var.ssl_issuer_email
privateKeySecretRef = {
name = "letsencrypt-prod"
}
solvers = [
{
http01 = {
ingress = {
class = "nginx"
}
}
}
]
}
}
}
depends_on = [
helm_release.cert_manager
]
}
# ClusterIssuer for Let's Encrypt (staging) - for testing
resource "kubernetes_manifest" "letsencrypt_staging" {
count = var.ssl_enabled && var.ssl_issuer_email != "" ? 1 : 0
manifest = {
apiVersion = "cert-manager.io/v1"
kind = "ClusterIssuer"
metadata = {
name = "letsencrypt-staging"
}
spec = {
acme = {
server = "https://acme-staging-v02.api.letsencrypt.org/directory"
email = var.ssl_issuer_email
privateKeySecretRef = {
name = "letsencrypt-staging"
}
solvers = [
{
http01 = {
ingress = {
class = "nginx"
}
}
}
]
}
}
}
depends_on = [
helm_release.cert_manager
]
}
# Kubernetes Ingress for Laravel Application
resource "kubernetes_ingress_v1" "app" {
count = var.ingress_enabled ? 1 : 0
metadata {
name = "${var.app_name}-ingress"
namespace = kubernetes_namespace.app.metadata[0].name
labels = local.common_labels
annotations = merge(
{
"kubernetes.io/ingress.class" = "nginx"
"nginx.ingress.kubernetes.io/rewrite-target" = "/"
"nginx.ingress.kubernetes.io/ssl-redirect" = var.ssl_enabled ? "true" : "false"
},
var.ssl_enabled && var.ingress_host != "" ? {
"cert-manager.io/cluster-issuer" = "letsencrypt-prod"
} : {}
)
}
spec {
dynamic "tls" {
for_each = var.ssl_enabled && var.ingress_host != "" ? [1] : []
content {
hosts = [var.ingress_host]
secret_name = "${var.app_name}-tls"
}
}
rule {
host = var.ingress_host != "" ? var.ingress_host : null
http {
path {
path = "/"
path_type = "Prefix"
backend {
service {
name = kubernetes_service.app.metadata[0].name
port {
number = 80
}
}
}
}
}
}
}
depends_on = [
helm_release.nginx_ingress,
kubernetes_service.app
]
}