ac24938108
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
107 lines
4.6 KiB
Markdown
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.
|