resource "kubernetes_namespace" "website" { metadata { annotations = { name = "website" } labels = { name = "website" } name = "website" } } resource "kubernetes_service_account" "website_service_account" { metadata { name = "website-app-sa" namespace = kubernetes_namespace.website.metadata[0].name } automount_service_account_token = false } resource "kubernetes_service" "website" { for_each = local.websites metadata { name = format("website-%s", replace(each.key, ".", "-")) namespace = kubernetes_namespace.website.metadata[0].name } spec { port { port = 80 target_port = "http" } selector = { app = format("website-%s", replace(each.key, ".", "-")) } cluster_ip = "None" } } resource "kubernetes_config_map" "nginx_config" { metadata { name = "nginx-config" namespace = kubernetes_namespace.website.metadata[0].name } data = { "nginx.conf" = file("${path.module}/resources/nginx/nginx.conf") "default.conf" = file("${path.module}/resources/nginx/conf.d/default.conf") } } resource "kubernetes_ingress_v1" "website_ingress" { for_each = local.websites metadata { name = "website-ingress" namespace = kubernetes_namespace.website.metadata[0].name annotations = { "kubernetes.io/ingress.class" = "public" "cert-manager.io/cluster-issuer" = "letsencrypt-prod" } } spec { tls { hosts = each.value.fqdn secret_name = format("website-%s-tls", replace(each.key, ".", "-")) } dynamic "rule" { for_each = each.value.fqdn content { host = rule.value http { path { backend { service { name = format("website-%s", replace(each.key, ".", "-")) port { number = 80 } } } } } } } } } resource "kubernetes_deployment" "website" { for_each = local.websites metadata { name = "website-app" namespace = kubernetes_namespace.website.metadata[0].name } spec { selector { match_labels = { app = format("website-%s", replace(each.key, ".", "-")) } } strategy { type = "RollingUpdate" } template { metadata { labels = { app = format("website-%s", replace(each.key, ".", "-")) } } spec { service_account_name = kubernetes_service_account.website_service_account.metadata[0].name security_context { fs_group = 1000 run_as_user = 1000 } container { name = "website" image = "nginx:${var.tag}" image_pull_policy = "Always" resources { requests = { memory = "100Mi" } limits = { memory = "500Mi" } } readiness_probe { http_get { path = "/" port = 8080 } initial_delay_seconds = 5 period_seconds = 10 } liveness_probe { http_get { path = "/" port = 8080 } initial_delay_seconds = 5 period_seconds = 10 } security_context { allow_privilege_escalation = false } port { container_port = 8080 name = "http" } volume_mount { name = "nginx-config" mount_path = "/etc/nginx/nginx.conf" sub_path = "nginx.conf" read_only = true } volume_mount { name = "nginx-config" mount_path = "/etc/nginx/conf.d/default.conf" sub_path = "default.conf" read_only = true } volume_mount { name = "website" mount_path = "/tmp/site" read_only = true } } volume { name = "nginx-config" config_map { name = kubernetes_config_map.nginx_config.metadata[0].name } } volume { name = "website" host_path { path = format("%s/%s", local.websites_path, each.key) } } } } } }