Files
Claude ac24938108 AWS-basen: allt eget, inget GitHub
Guidad Felsökning får en egen AWS-grund i felsokning/infra/aws — nät,
kluster, databas, objektlagring, register, hemligheter, domän och
observation. Inget GHCR, ingen extern byggtjänst.

Två lager i ordning, och uppdelningen ä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,
eftersom kubernetes-leverantören måste konfigureras med uppgifter som
inte finns förrän klustret existerar.

Nätet ligger i tre lager. Publikt bara för lastbalanserare och NAT,
privat för noderna, och ett eget datalager för Aurora utan routing ut
alls — att databasen inte kan nå internet hänger då inte på att en
säkerhetsgrupp är rätt konfigurerad. VPC-endpoints för S3, ECR, loggar,
Secrets Manager, STS och ELB gör att bilddragningar och loggar aldrig
lämnar nätet, vilket både är säkrare och sänker NAT-notan rejält.

IRSA i stället för nodroller: plattformens tjänstekonto har en roll
bunden till exakt en namnrymd och ett tjänstekonto, så grannpodden på
samma nod får ingenting på köpet. IMDSv2 med hoppgräns 1 hindrar
dessutom en pod från att låna nodens roll via metadatatjänsten.

Bygge och drift har delade rättigheter. Byggrollen får publicera till
ECR men inte röra klustret; driftrollen tvärtom. Ett komprometterat
bygge kan därför inte driftsätta.

Aurora PostgreSQL Serverless v2 med 30 dagars säkerhetskopiering och
PITR ned till sekunden — det som gör den duglig för händelseloggen är
inte prestandan utan att förlorad logg annars hade tagit varje ärendes
bevisvärde med sig. S3-hinken för bilagor har versionshantering,
SSE-KMS, TLS-krav och blockerad publik åtkomst; plattformens roll får
läsa och skriva men aldrig radera, eftersom bilagorna hör till en
append-only logg.

Larmen är fyra och ett av dem larmar på saknad data: uteblir mätvärdet
för säkerhetskopiering finns ingen backup, och en backup man tror finns
är värre än ingen.

Verifierat: terraform fmt och en statisk referenskontroll (88 resurser,
5 datakällor, inga dinglande referenser). terraform validate kunde inte
köras här — registry.terraform.io är blockerad av sessionens
egress-policy — så CI-jobbet kör den i stället.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012EQg3rJsrQ1ZNTvkzmQAtt
2026-08-04 12:39:42 +00:00

107 lines
4.6 KiB
Markdown

# AWS-basen
Allt Guidad Felsökning behöver, i eget AWS-konto. Inget GitHub, inget
GHCR, ingen extern byggtjänst.
| Fil | Vad |
| --- | --- |
| `versions.tf` | Leverantörer och tillståndsbackend |
| `variables.tf` | Allt som skiljer en installation från en annan |
| `10-natverk.tf` | VPC, tre subnätlager, NAT, VPC-endpoints, flödesloggar |
| `20-eks.tf` | Klustret, noderna, IRSA, tillägg |
| `30-data.tf` | KMS, Aurora PostgreSQL, S3 för bilagor, ECR |
| `40-hemligheter.tf` | Secrets Manager och rollerna som får läsa dem |
| `50-doman-observation.tf` | Route 53, ACM, CloudWatch, larm |
| `outputs.tf` | Kartan i klartext + värdena arbetslastlagret behöver |
## Två lager, i ordning
```sh
cd felsokning/infra/aws
terraform init && terraform apply # basen
terraform output karta # hela AWS-sidan i klartext
cd ../terraform
terraform init && terraform apply # arbetslasten i klustret
```
Anledningen till uppdelningen ä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.
## Vad som gör det till "efter bästa praxis"
**Nätet i tre lager.** Publikt bara för lastbalanserare och NAT, privat
för noderna, och ett eget datalager för Aurora *utan routing ut alls*.
Att databasen inte kan nå internet är ett skydd som inte hänger på att
en säkerhetsgrupp är rätt konfigurerad.
**VPC-endpoints** för S3, ECR, loggar, Secrets Manager, STS och ELB.
Bilddragningar och loggar lämnar aldrig nätet — och NAT-notan sjunker
rejält, eftersom bilddragningar annars dominerar den.
**IRSA i stället för nodroller.** Plattformens tjänstekonto har en egen
roll bunden till exakt en namnrymd och ett tjänstekonto. Grannpodden på
samma nod får ingenting på köpet. `IMDSv2` obligatoriskt med hoppgräns 1
gör dessutom att en pod inte kan låna nodens roll via metadatatjänsten.
**Delade rättigheter mellan bygge och drift.** Byggrollen får publicera
till ECR men inte röra klustret. Driftrollen får röra klustret men inte
publicera bilder. Ett komprometterat bygge kan därför inte driftsätta.
**Egna KMS-nycklar**, tre stycken: en för hemligheter i etcd, en för
databas och bilagor, en för loggar. Åtkomstkontroll och revisionsspår per
nyckel, och möjligheten att rotera en utan att röra de andra.
**Oföränderliga ECR-taggar.** En tagg som pekat på ett bygge kan inte
peka på ett annat, så "vilken kod kör i produktion" har ett entydigt
svar.
**Ingen DeleteObject** för bilagorna. De hör till en append-only
händelselogg, och tjänsten har ingen anledning att kunna radera dem.
**Flödesloggar bara för avvisad trafik.** Allt hade blivit dyrt brus;
avvisningarna är det som säger något när en spärr slår till — eller
borde ha gjort det.
**Larm som betyder något.** Fyra stycken, varav ett larmar på *saknad*
data: uteblir mätvärdet för säkerhetskopiering finns ingen backup, och
en backup man tror finns är värre än ingen.
## Efter första apply
`terraform output karta` listar det under `kvar_att_gora`:
1. **Claude-nyckeln.** Terraform ska inte känna den.
```sh
aws secretsmanager put-secret-value \
--secret-id felsokning-produktion/app \
--secret-string "$(aws secretsmanager get-secret-value --secret-id felsokning-produktion/app \
--query SecretString --output text | jq '.anthropic_api_key = "sk-ant-…"')"
```
2. **Schemat.** Kör `felsokning/infra/postgres-init.sql` mot Aurora — det
är den som lägger in append-only-triggarna. Samma fil som
integrationstestet kör, så de kan inte glida isär.
3. **Begränsa `tillatna_api_cidr`.** Standard är öppet mot internet
eftersom klustret annars inte går att nå från en ny miljö. Snäva in
till kontorets och runnernas adresser.
4. **Sätt `larm_epost`.** Utan den går larmen ingenstans.
## Kostnad — det som faktiskt kostar
NAT-gateways (en per zon), Auroras minsta kapacitet och EKS
kontrollplan är golvet och löper oavsett last. `nat_per_zon = false`
halverar nätkostnaden i test men gör en zon till enskild felkälla för
all utgående trafik — fel avvägning i produktion.
## Verifiering
`terraform validate` kunde inte köras i utvecklingsmiljön —
registry.terraform.io är blockerad av sessionens egress-policy, så
leverantörerna gick inte att hämta. Det som kontrollerats är
`terraform fmt` och en statisk referenskontroll (88 resurser, 5
datakällor, inga dinglande referenser, alla `count`-resurser indexerade).
Kör `terraform init -backend=false && terraform validate` innan första
apply.