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
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user