Varje produkt äger sitt eget träd — och GitHub-flödena bort

Rot-CI:n föll med 107 lint-fel efter merge:n. Orsaken var inte kod som
blivit sämre: Semantikas rot-eslint började granska felsokning/, ett
träd med egen verktygskedja och andra regler. Felen låg i värdappens
befintliga Supabase-funktioner, oförändrade sedan innan.

Rätt åtgärd är att låta varje produkt äga sitt eget träd, inte att lätta
på någons regler. felsokning/ ignoreras därför av Semantikas eslint och
prettier — den har egen eslint-konfiguration, egna prettier-regler och
eget CI-flöde. Ingen regel är försvagad för någon av produkterna.

Samtidigt: mina GitHub-workflows för publicering och driftsättning är
borttagna. Guidad Felsökning ska inte längre bero på GitHub Actions eller
GHCR — bygge, publicering till eget ECR och terraform apply mot EKS
ligger nu i .gitea/workflows/felsokning.yml och körs av egna runners.
Driftsättningen är fortsatt ett eget, manuellt steg med en bildtagg;
rollback är att köra igen med en tidigare tagg.

.github/workflows/ci.yml är Semantikas och lämnas orörd.

Verifierat: rotens lint, format:check, typecheck och test går igenom, och
Guidad Felsöknings egna 96 tester, typkontroll, bygge och integrationstest
mot riktig Postgres likaså.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
This commit is contained in:
Claude
2026-08-04 12:27:33 +00:00
parent 301c477e25
commit c407aad58a
7 changed files with 301 additions and 165 deletions
+142
View File
@@ -0,0 +1,142 @@
variable "region" {
description = "AWS-region. eu-north-1 (Stockholm) håller fordonsdata inom EU."
type = string
default = "eu-north-1"
}
variable "miljo" {
description = "Miljöns namn — ingår i alla resursnamn och taggar."
type = string
default = "produktion"
}
variable "doman" {
description = "Domänen tjänsten nås på, t.ex. felsokning.exempel.se."
type = string
}
variable "zon_id" {
description = <<-TEXT
Befintlig Route 53-zon att skapa posten i. Lämnas den tom skapas en
ny publik zon för domänens rot — då måste namnservrarna pekas om hos
registraren innan certifikatet kan utfärdas.
TEXT
type = string
default = ""
}
# ---- Nät ---------------------------------------------------------------
variable "vpc_cidr" {
description = "Adressrymd för VPC:n."
type = string
default = "10.42.0.0/16"
validation {
condition = can(cidrsubnet(var.vpc_cidr, 4, 0))
error_message = "vpc_cidr måste vara ett giltigt CIDR med plats för /20-subnät."
}
}
variable "antal_zoner" {
description = "Antal tillgänglighetszoner. Tre ger failover som överlever att en zon försvinner."
type = number
default = 3
validation {
condition = var.antal_zoner >= 2 && var.antal_zoner <= 4
error_message = "antal_zoner måste vara mellan 2 och 4."
}
}
variable "nat_per_zon" {
description = <<-TEXT
En NAT-gateway per zon i stället för en delad. Rätt i produktion —
med en delad blir den zonen en enskild felkälla för all utgående
trafik. Kostar mer, så av i test.
TEXT
type = bool
default = true
}
# ---- Kluster -----------------------------------------------------------
variable "kubernetes_version" {
description = "EKS-version."
type = string
default = "1.31"
}
variable "nod_typer" {
description = "Instanstyper för nodgruppen. Flera ökar chansen att kapacitet finns."
type = list(string)
default = ["m7g.large", "m6g.large"]
}
variable "noder" {
description = "Nodgruppens storlek."
type = object({
minsta = number
onskad = number
hogsta = number
})
default = {
minsta = 3
onskad = 3
hogsta = 10
}
}
variable "tillatna_api_cidr" {
description = <<-TEXT
Varifrån EKS API-server får nås. Standard är öppet eftersom det
annars inte går att komma åt klustret alls från en ny miljö —
begränsa till kontorets och byggrunnernas adresser i produktion.
TEXT
type = list(string)
default = ["0.0.0.0/0"]
}
# ---- Databas -----------------------------------------------------------
variable "databas" {
description = <<-TEXT
Aurora PostgreSQL. Serverless v2 skalar efter last; min_kapacitet
0.5 ACU räcker för en liten verkstad, max sätter taket.
backup_dagar styr både automatisk säkerhetskopiering och hur långt
tillbaka PITR går.
TEXT
type = object({
version = optional(string, "16.6")
min_kapacitet = optional(number, 0.5)
max_kapacitet = optional(number, 8)
instanser = optional(number, 2)
backup_dagar = optional(number, 30)
raderingsskydd = optional(bool, true)
})
default = {}
}
# ---- Larm --------------------------------------------------------------
variable "larm_epost" {
description = "Adress som larm skickas till. Tom = inget SNS-abonnemang skapas."
type = string
default = ""
}
# ---- Självhostad git ---------------------------------------------------
variable "gitea" {
description = <<-TEXT
Självhostad git med egna byggrunners, så varken källkod, bygge eller
register ligger hos någon annan. Slås av om ni tills vidare kör git
någon annanstans.
TEXT
type = object({
aktiv = optional(bool, true)
doman = optional(string, "")
runners = optional(number, 2)
})
default = {}
}
+79
View File
@@ -0,0 +1,79 @@
# Guidad Felsökning — AWS-basen.
#
# Två lager, medvetet åtskilda:
#
# felsokning/infra/aws/ det här — VPC, EKS, Aurora, S3, ECR,
# Secrets Manager, Route 53/ACM, CloudWatch
# felsokning/infra/terraform/ arbetslasten i klustret
#
# Anledningen är inte smak: en enda apply som både skapar ett EKS-kluster
# och schemalägger in i det är en känd fälla — kubernetes-leverantören
# måste konfigureras med uppgifter som inte finns förrän klustret är
# skapat, och planen blir därför opålitlig. Kör basen först, arbetslasten
# sedan. Arbetslasten läser basens utdata.
#
# Läsordning:
# variables.tf alla rattar
# 10-natverk.tf VPC, subnät, NAT, VPC-endpoints
# 20-eks.tf klustret, noderna, IRSA
# 30-databas.tf Aurora PostgreSQL
# 40-lagring.tf S3 för bilagor, ECR för bilder
# 50-hemligheter.tf Secrets Manager + rollerna som får läsa dem
# 60-doman.tf Route 53 och certifikat
# 70-observation.tf CloudWatch: loggar, mätvärden, larm
# 80-gitea.tf självhostad git + byggrunners
# outputs.tf det arbetslastlagret behöver
terraform {
required_version = ">= 1.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.80"
}
random = {
source = "hashicorp/random"
version = "~> 3.6"
}
tls = {
source = "hashicorp/tls"
version = "~> 4.0"
}
}
# Tillståndet innehåller databasens slutpunkt och rollnamn. Lägg det i
# S3 med versionshantering och lås — aldrig lokalt i git.
#
# backend "s3" {
# bucket = "felsokning-tfstate"
# key = "aws/terraform.tfstate"
# region = "eu-north-1"
# encrypt = true
# use_lockfile = true
# }
}
provider "aws" {
region = var.region
default_tags {
tags = local.taggar
}
}
# ACM-certifikat för CloudFront måste ligga i us-east-1. Vi använder inte
# CloudFront i dag, men leverantören står redo så tillägget inte kräver
# en omstrukturering.
provider "aws" {
alias = "us_east_1"
region = "us-east-1"
default_tags {
tags = local.taggar
}
}
data "aws_caller_identity" "denna" {}
data "aws_partition" "denna" {}