a5e276534c
Andra lagret läser nu basens utdata i stället för att upprepa någonting. 05-aws.tf hämtar klustret, domänen, certifikatet, registret, rollerna, hinken och hemligheternas namn — ändras något i basen slår det igenom här utan att en rad ändras. Autentiseringen mot klustret sker med en färsk EKS-token i stället för en kubeconfig på disk: inget att distribuera, inget som går ut. Hemligheterna bor i Secrets Manager och speglas in av External Secrets var timme. Terraform ser aldrig värdena, och det är själva poängen — en hemlighet som passerar Terraform hamnar i tillståndsfilen. Roteras en hemlighet följer klustret efter av sig självt. Plattformstjänsten kör som ett tjänstekonto med IRSA. Rollen är bunden till exakt det kontot i den namnrymden, så grannpodden på samma nod får ingenting på köpet. Bilagorna signeras mot S3 med samma roll — inga nycklar existerar att läcka. Postgres-podden är borta. Händelseloggen ligger i Aurora utanför klustret, i ett subnätlager utan routing ut, med automatisk säkerhetskopiering och PITR. Ingressen är en ALB med ACM-certifikat i stället för nginx, och alla tre tjänsterna delar den genom samma gruppnamn. Gitea med egna Actions-runners kör i samma kluster. Därmed finns inget externt beroende kvar: källkod, bygge, register och driftsättning ligger allt i vår AWS-miljö. Runnern och driftsättningen har varsitt tjänstekonto med skilda roller — bygget får publicera till ECR men inte röra klustret, driften tvärtom. Ett komprometterat bygge kan inte driftsätta. Gitea kör SQLite på en EBS-volym i stället för en egen Aurora-databas. En verkstadsinstallation har en handfull utvecklare, och ytterligare en databas att säkerhetskopiera och övervaka är kostnad utan motsvarande nytta. Verifierat: 96 vitest-tester, rotens lint och format:check, terraform fmt på båda lagren och statisk referenskontroll av vardera (88 respektive 35 resurser, inga dinglande referenser, alla count-resurser indexerade). terraform validate kunde inte köras här — registry.terraform.io är blockerad av sessionens egress-policy — så CI-jobbet kör den. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
99 lines
2.8 KiB
Terraform
99 lines
2.8 KiB
Terraform
# Trafiken utifrån och in.
|
|
#
|
|
# En ALB, skapad av lastbalanserar-kontrollern ur det här objektet.
|
|
# Certifikatet kommer från ACM och terminerar på lastbalanseraren; all
|
|
# trafik mot :80 skickas vidare till :443.
|
|
#
|
|
# Kroppsgränsen är inte kosmetisk: teknikern dokumenterar med foto och
|
|
# video. En för snäv gräns avvisar dokumentationen redan vid dörren.
|
|
|
|
resource "kubernetes_ingress_v1" "denna" {
|
|
metadata {
|
|
name = local.namn
|
|
namespace = kubernetes_namespace_v1.denna.metadata[0].name
|
|
labels = local.etiketter
|
|
|
|
annotations = {
|
|
"alb.ingress.kubernetes.io/scheme" = "internet-facing"
|
|
"alb.ingress.kubernetes.io/target-type" = "ip"
|
|
"alb.ingress.kubernetes.io/certificate-arn" = local.aws.certifikat_arn
|
|
"alb.ingress.kubernetes.io/listen-ports" = jsonencode([{ HTTP = 80 }, { HTTPS = 443 }])
|
|
"alb.ingress.kubernetes.io/ssl-redirect" = "443"
|
|
"alb.ingress.kubernetes.io/ssl-policy" = "ELBSecurityPolicy-TLS13-1-2-2021-06"
|
|
|
|
# Hälsokontrollen går mot plattformen — den vet om databasen svarar.
|
|
"alb.ingress.kubernetes.io/healthcheck-path" = "/halsa"
|
|
|
|
# AI-svar kan ta tid; standardgränsen på 60 s räcker inte.
|
|
"alb.ingress.kubernetes.io/load-balancer-attributes" = join(",", [
|
|
"idle_timeout.timeout_seconds=180",
|
|
"routing.http.drop_invalid_header_fields.enabled=true",
|
|
"access_logs.s3.enabled=false",
|
|
])
|
|
|
|
# Alla tre tjänsterna delar en lastbalanserare.
|
|
"alb.ingress.kubernetes.io/group.name" = local.namn
|
|
}
|
|
}
|
|
|
|
spec {
|
|
ingress_class_name = "alb"
|
|
|
|
rule {
|
|
host = local.aws.doman
|
|
|
|
http {
|
|
dynamic "path" {
|
|
for_each = local.routing
|
|
|
|
content {
|
|
path = path.value.prefix
|
|
path_type = "Prefix"
|
|
|
|
backend {
|
|
service {
|
|
name = path.value.till
|
|
|
|
port {
|
|
number = local.port_tjanst
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
depends_on = [
|
|
helm_release.lastbalanserare,
|
|
kubernetes_service_v1.web,
|
|
kubernetes_service_v1.plattform,
|
|
kubernetes_service_v1.orkester,
|
|
]
|
|
}
|
|
|
|
# DNS pekar på lastbalanseraren. Alias i stället för CNAME så att
|
|
# domänens rot kan användas om ni vill det senare.
|
|
resource "aws_route53_record" "denna" {
|
|
zone_id = local.aws.zon_id
|
|
name = local.aws.doman
|
|
type = "A"
|
|
|
|
alias {
|
|
name = kubernetes_ingress_v1.denna.status[0].load_balancer[0].ingress[0].hostname
|
|
zone_id = data.aws_lb.denna.zone_id
|
|
evaluate_target_health = true
|
|
}
|
|
}
|
|
|
|
data "aws_lb" "denna" {
|
|
tags = {
|
|
"elbv2.k8s.aws/cluster" = local.aws.kluster
|
|
"ingress.k8s.aws/stack" = local.namn
|
|
"ingress.k8s.aws/resource" = "LoadBalancer"
|
|
}
|
|
|
|
depends_on = [kubernetes_ingress_v1.denna]
|
|
}
|