19796bec70
Kustomize- och Argo CD-vägen är borttagen. Den beskrev samma system en
gång till och kunde inte köras samtidigt som Terraform utan att de
motarbetade varandra — selfHeal återställde det Terraform ändrade och
prune tog bort det Terraform skapade. Kvar utanför Terraform är bara
postgres-init.sql, som läses av både definitionen och integrationstestet
så att schemat inte kan glida isär från det som testas.
Säkerhetskopieringen var en förhoppning: en StatefulSet med en volym och
ingen kopia. Går volymen förlorad är det inte "data" som försvinner utan
varje ärendes bevisvärde — vad som kontrollerades, av vem, när, med
vilken evidens — och det går inte att återskapa i efterhand.
databas_lage är därför ett obligatoriskt val utan standardvärde:
extern managerad Postgres, leverantörens backup och PITR
(rekommenderat i produktion)
cnpg CloudNativePG i klustret: basbackup 02:30, kontinuerlig
WAL-arkivering till objektlagring, PITR och failover
inbyggd en volym, ingen backup — spärras av en precondition när
miljön är produktion
Preconditions fångar felkonfiguration vid plan i stället för vid drift:
extern utan anslutning, cnpg utan backupmål eller nycklar, inbyggd i
produktion.
Driftsättningen är nu två åtskilda flöden. Publicera bygger och taggar
bilderna vid varje main-push; Driftsätt startas för hand med en tagg mot
en GitHub-miljö som kan kräva godkännande, kör fmt/init/validate/plan/
apply, skriver ut kartan och rökkontrollerar hälsa och API-spec. En bild
i registret är inte samma sak som en bild som kör. Rollback är att köra
Driftsätt igen med en tidigare tagg. CI kör dessutom terraform validate
på varje PR — den kontroll jag inte kunde köra själv.
Två fel hittade vid egengranskning av definitionen: schemafilen delades
på semikolon, vilket hade klippt itu plpgsql-funktionen med
append-only-triggern (nu hela filen via postInitApplicationSQLRefs), och
null-satta fält i kubernetes_manifest utelämnas nu i stället.
Verifierat: 87 vitest-tester, typkontroll, eslint, OpenAPI-validering,
terraform fmt, statisk referenskontroll av modulen och integrationstest
mot riktig Postgres. terraform validate kunde inte köras här —
registry.terraform.io är blockerad av sessionens egress-policy, därav
CI-jobbet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
110 lines
4.3 KiB
Markdown
110 lines
4.3 KiB
Markdown
# Infrastrukturen
|
|
|
|
Hela systemet i Terraform. Filerna är numrerade i den ordning de är
|
|
begripliga att läsa:
|
|
|
|
| Fil | Vad |
|
|
| --- | --- |
|
|
| `versions.tf` | Leverantörer och tillståndsbackend |
|
|
| `variables.tf` | Allt som skiljer en installation från en annan |
|
|
| `karta.tf` | **Systemet som data** — tjänster, portar, routing, hemligheter, dataflöden, gränser |
|
|
| `10-namnrymd.tf` | Namnrymd, hemligheten, databasschemat |
|
|
| `20-databas.tf` | Händelseloggen — tre lägen, se nedan |
|
|
| `30-plattform.tf` | Backend: auth, händelse-API, delning, integrationer |
|
|
| `40-orkester.tf` | AI-orkestern |
|
|
| `50-web.tf` | Klienten |
|
|
| `60-ingress.tf` | Trafiken utifrån |
|
|
| `70-natverk.tf` | Nätverkspolicyer — vem får prata med vem |
|
|
| `outputs.tf` | Kartan utskriven |
|
|
|
|
Börja i `karta.tf`. Den beskriver systemet en gång, som data; resten av
|
|
filerna läser därifrån i stället för att upprepa portar och namn.
|
|
|
|
## Kom igång
|
|
|
|
```sh
|
|
cp terraform.tfvars.exempel terraform.tfvars # fyll i domän, register, nycklar
|
|
terraform init
|
|
terraform plan
|
|
terraform apply
|
|
terraform output karta # hela systemet i klartext
|
|
```
|
|
|
|
`terraform output karta` svarar på frågorna "vad kör var", "vem ser
|
|
vilken hemlighet", "vad pratar med vad" och "vad ingår inte" — utan att
|
|
någon behöver läsa .tf-filerna.
|
|
|
|
## Kontroll utan kluster
|
|
|
|
```sh
|
|
terraform fmt -check -diff # formatering
|
|
terraform init -backend=false # hämtar leverantörer
|
|
terraform validate # typer och referenser
|
|
```
|
|
|
|
`terraform validate` kräver att leverantörerna hämtats från
|
|
registry.terraform.io.
|
|
|
|
## Databasen: tre lägen
|
|
|
|
`var.databas_lage` saknar standardvärde med flit. Valet avgör om det
|
|
finns säkerhetskopiering, och det ska inte kunna bli fel av slentrian.
|
|
|
|
| Läge | Backup | Failover | Använd när |
|
|
| --- | --- | --- | --- |
|
|
| `extern` | Leverantörens, med PITR | Leverantörens | **Produktion.** Cloud SQL, RDS, Neon, Azure Flexible Server |
|
|
| `cnpg` | Basbackup 02:30 + WAL-arkiv → objektlagring, PITR | Ja, `databas_instanser` styr | Produktion när databasen måste ligga i klustret |
|
|
| `inbyggd` | **Ingen** | Nej | Prov och demo. Blockeras av en precondition när `miljo = "produktion"` |
|
|
|
|
Går händelseloggen förlorad är det inte "data" som försvinner utan varje
|
|
ärendes bevisvärde: vad som kontrollerades, av vem, när, med vilken
|
|
evidens. Det går inte att återskapa i efterhand.
|
|
|
|
`cnpg` kräver att CloudNativePG-operatorn redan är installerad —
|
|
Terraform slår upp dess CRD vid plan:
|
|
|
|
```sh
|
|
kubectl apply --server-side -f \
|
|
https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.25/releases/cnpg-1.25.0.yaml
|
|
```
|
|
|
|
I `extern` läge ansvarar ni själva för att köra
|
|
`infra/postgres-init.sql` mot databasen. Det är samma fil som
|
|
integrationstestet kör, så schemat kan inte glida isär från det som
|
|
testas.
|
|
|
|
## Driftsättning
|
|
|
|
Bilderna byggs av `publicera.yml` vid varje push till main och taggas med
|
|
git-SHA:t. Driftsättningen är ett eget flöde, `driftsatt.yml`, som
|
|
startas för hand med en tagg och kör mot GitHub-miljön `produktion` — den
|
|
kan kräva godkännande. Rollback är att köra flödet igen med en tidigare
|
|
tagg.
|
|
|
|
Kustomize- och Argo CD-vägen är borttagen. Den beskrev samma system en
|
|
gång till och kunde inte köras samtidigt som Terraform utan att de
|
|
motarbetade varandra (`selfHeal` återställde det Terraform ändrade,
|
|
`prune` tog bort det Terraform skapade).
|
|
|
|
## Det som medvetet inte ingår
|
|
|
|
Står också i `terraform output karta` under `avgränsningar`:
|
|
|
|
- **Objektlagring.** Foton och video ligger som data-URL:er i
|
|
händelseloggen. Det gör loggen till systemets enda sanningskälla, men
|
|
också stor och tung att säkerhetskopiera.
|
|
- **Observability.** Ingen metrikexport, ingen tracing.
|
|
- **Takt-begränsning på inloggning.** Bara den publika beslutsvägen är
|
|
begränsad, och bara per pod.
|
|
- **Återkallelse av JWT.** En utfärdad token gäller sina 12 timmar ut
|
|
även om användaren tagits bort.
|
|
|
|
## Krav på klustret
|
|
|
|
- En CNI som tillämpar NetworkPolicy (Cilium, Calico, Antrea). Utan det
|
|
är `70-natverk.tf` dokumentation, inte skydd.
|
|
- ingress-nginx, med kontrollern i namnrymden `var.ingress_namnrymd`.
|
|
- cert-manager med en ClusterIssuer.
|
|
- En metrics-server för autoskalningen.
|
|
- En StorageClass som klarar `ReadWriteOnce`.
|