CloudFront-Cache leeren: Invalidierungen erstellen wenn S3-Inhalte nicht aktualisiert werden

Du hast eine Datei in S3 ersetzt, aber CloudFront liefert weiterhin die alte Version aus — dieses Problem trifft jeden, der zum ersten Mal mit CloudFront-Caching arbeitet, und der Grund liegt nicht in einem Fehler, sondern im normalen Verhalten des Edge-Caches.

TL;DR: CloudFront-Invalidierung auf einen Blick

SchrittAktionErgebnis
1Datei in S3 ersetzenOrigin hat neue Version, Edge-Cache noch nicht
2Invalidierung erstellen (/* oder Pfad)CloudFront markiert gecachte Objekte als veraltet
3Edge-Nodes holen neue Version bei nächstem RequestBesucher erhalten aktuellen Inhalt

Wie CloudFront-Caching funktioniert

CloudFront speichert Objekte an seinen Edge-Locations für die Dauer des TTL-Werts (Time to Live), der entweder aus den Cache-Control-Headern des Origin stammt oder über das CloudFront-Verhalten konfiguriert wird. Wenn du eine Datei in S3 ersetzt, weiß CloudFront davon nichts — der Edge-Node hat noch eine gültige Kopie im Cache und liefert diese aus, bis der TTL abläuft oder du eine Invalidierung erzwingst.

Eine Invalidierung teilt CloudFront mit, dass bestimmte Pfade aus dem Edge-Cache entfernt werden sollen. Beim nächsten Request für diesen Pfad holt der Edge-Node die aktuelle Version vom Origin (S3) und cached sie neu. Die Invalidierung selbst ist asynchron — sie breitet sich über alle Edge-Locations aus, was typischerweise einige Minuten dauert.

sequenceDiagram participant B as Browser participant E as Edge-Node participant S as S3 Origin Note over E: Alter Cache (TTL aktiv) B->>E: GET /logo.png E-->>B: 200 OK (alte Version, Cache-Hit) Note over S: Datei in S3 ersetzt B->>E: GET /logo.png E-->>B: 200 OK (immer noch alte Version) Note over E: Invalidierung empfangen B->>E: GET /logo.png E->>S: Origin-Fetch (Cache-Miss) S-->>E: 200 OK (neue Version) E-->>B: 200 OK (neue Version, neu gecacht)
  1. Normaler Cache-Hit: Der Browser fragt den Edge-Node, der die gecachte alte Datei direkt zurückgibt — S3 wird nicht kontaktiert.
  2. Nach S3-Update ohne Invalidierung: Der Edge-Node kennt die neue S3-Version nicht und liefert weiterhin die alte Kopie aus.
  3. Nach Invalidierung: CloudFront markiert das Objekt als ungültig. Der nächste Request löst einen Origin-Fetch aus, S3 liefert die neue Version, der Edge-Node cached sie neu.

CloudFront-Invalidierung erstellen: Schritt-für-Schritt

Schritt 1: Distribution-ID ermitteln

Bevor du eine Invalidierung erstellst, brauchst du die ID deiner CloudFront-Distribution. Alle aktiven Distributionen lassen sich direkt auflisten — das ist der schnellste Weg, wenn du die ID nicht parat hast.

aws cloudfront list-distributions \
  --query 'DistributionList.Items[*].{ID:Id,Domain:DomainName,Status:Status}' \
  --output table

Notiere die ID der Ziel-Distribution (Format: E1XXXXXXXXXX).

Schritt 2: Invalidierung für einen bestimmten Pfad erstellen

Wenn du weißt, welche Datei geändert wurde, invalidiere nur diesen Pfad. Das ist präziser und verursacht weniger unnötige Origin-Fetches als eine Wildcard-Invalidierung.

aws cloudfront create-invalidation \
  --distribution-id E1XXXXXXXXXX \
  --paths '/bilder/logo.png'

CloudFront gibt eine Invalidierungs-ID und den Status InProgress zurück. Der Pfad muss mit einem / beginnen und exakt dem URL-Pfad entsprechen, den Besucher aufrufen.

Schritt 3: Alle Objekte invalidieren (Wildcard)

Wenn du mehrere Dateien gleichzeitig aktualisiert hast oder nicht sicher bist, welche Pfade betroffen sind, ist eine Wildcard-Invalidierung die pragmatische Lösung — sie invalidiert alle Objekte in der Distribution auf einmal.

aws cloudfront create-invalidation \
  --distribution-id E1XXXXXXXXXX \
  --paths '/*'
Eine Wildcard-Invalidierung (/*) zählt als eine einzige Invalidierungsanfrage, invalidiert aber alle Objekte. AWS berechnet die ersten 1.000 Invalidierungspfade pro Monat kostenlos — danach fallen Gebühren an. Aktuelle Preise findest du in der offiziellen AWS-Dokumentation.

Schritt 4: Invalidierungsstatus prüfen

Die Invalidierung ist abgeschlossen, wenn der Status von InProgress auf Completed wechselt. Bis dahin können einige Edge-Locations noch die alte Version ausliefern — das ist kein Fehler, sondern die normale Ausbreitungszeit.

aws cloudfront get-invalidation \
  --distribution-id E1XXXXXXXXXX \
  --id IXXXXXXXXXXXXXXXX

Die Invalidierungs-ID (IXXXXXXXXXXXXXXXX) erhältst du aus der Ausgabe von Schritt 2 oder 3.

stateDiagram-v2 [*] --> InProgress : create-invalidation InProgress --> Completed : Alle Edge-Locations aktualisiert Completed --> [*] InProgress : Ausbreitung läuft InProgress : Einige Edges noch alt Completed : Alle Edges invalidiert Completed : Nächster Request = Origin-Fetch
  1. InProgress: Die Invalidierung wurde akzeptiert und breitet sich über alle Edge-Locations aus.
  2. Completed: Alle Edge-Nodes haben die Invalidierung verarbeitet. Neue Requests holen die aktuelle Version von S3.

IAM-Berechtigungen für CloudFront-Invalidierungen

Der aufrufende IAM-Principal benötigt explizite Berechtigungen für CloudFront-Invalidierungsoperationen. Ohne diese Berechtigungen schlägt der API-Aufruf mit einem AccessDenied-Fehler fehl.

🔽 IAM-Policy für CloudFront-Invalidierungen (klicken zum Ausklappen)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CloudFrontInvalidationAllow",
      "Effect": "Allow",
      "Action": [
        "cloudfront:CreateInvalidation",
        "cloudfront:GetInvalidation",
        "cloudfront:ListInvalidations"
      ],
      "Resource": "arn:aws:cloudfront::123456789012:distribution/E1XXXXXXXXXX"
    },
    {
      "Sid": "CloudFrontListDistributions",
      "Effect": "Allow",
      "Action": "cloudfront:ListDistributions",
      "Resource": "*"
    }
  ]
}

cloudfront:ListDistributions erfordert "Resource": "*", da diese Aktion keine ressourcenspezifische Einschränkung unterstützt. Die Invalidierungsaktionen können auf eine einzelne Distribution eingeschränkt werden.

Der häufigste Denkfehler — und warum er passiert

Viele gehen davon aus, dass das Ersetzen einer Datei in S3 automatisch dazu führt, dass CloudFront die neue Version ausliefert. Das ist verständlich — S3 hat die neue Datei, also sollte CloudFront sie auch haben, oder?

Das Missverständnis: CloudFront fragt S3 nicht aktiv nach Änderungen. Der Edge-Node cached das Objekt und liefert es aus, bis der TTL abläuft — unabhängig davon, was in S3 passiert. S3-Events lösen keine automatische Cache-Invalidierung aus.

Der tatsächliche Auslöser für einen Origin-Fetch ist entweder ein abgelaufener TTL oder eine explizite Invalidierung. Wer das erste Mal eine Produktionsseite mit CloudFront betreibt und eine dringende Korrektur deployt, erlebt genau diesen Moment: Die Datei ist in S3, die Seite zeigt noch die alte Version, und im AWS-Konsolen-Log ist alles grün.

CloudFront ist kein transparenter Proxy, der bei jeder Anfrage den Origin prüft — es ist ein Cache, der aktiv verwaltet werden muss. Die Invalidierung ist das Werkzeug dafür.

Langfristige Strategie: Cache-Busting statt Invalidierung

Invalidierungen sind das richtige Werkzeug für sofortige Korrekturen, aber für reguläre Deployments gibt es eine bessere Methode: Versionierte Dateinamen. Statt app.js zu ersetzen, deployst du app.v2.js und aktualisierst die Referenz im HTML. CloudFront cached beide Versionen, und du brauchst keine Invalidierung — der neue Pfad ist automatisch ein Cache-Miss.

Diese Methode funktioniert besonders gut in Kombination mit Build-Tools, die automatisch Content-Hashes in Dateinamen einbetten (z.B. app.3f8a2c.js). Der Vorteil: kein Invalidierungsaufwand, keine Ausbreitungszeit, keine Kosten für Invalidierungspfade.

# Beispiel: Alle Dateien mit Content-Hash deployen und dann nur HTML invalidieren
aws s3 sync ./dist s3://mein-bucket/ --cache-control 'max-age=31536000,immutable'
aws cloudfront create-invalidation \
  --distribution-id E1XXXXXXXXXX \
  --paths '/index.html'

Statische Assets erhalten einen langen TTL (immutable), während nur die HTML-Einstiegspunkte invalidiert werden — das minimiert sowohl Invalidierungskosten als auch Origin-Last.

Alle Invalidierungen einer Distribution auflisten

Wenn du nachvollziehen willst, wann zuletzt invalidiert wurde oder ob eine laufende Invalidierung den aktuellen Zustand erklärt, liefert dieser Befehl die vollständige Historie.

aws cloudfront list-invalidations \
  --distribution-id E1XXXXXXXXXX \
  --query 'InvalidationList.Items[*].{ID:Id,Status:Status,CreateTime:CreateTime}' \
  --output table

Nächste Schritte und weiterführende Ressourcen

Für einmalige Korrekturen ist die AWS CLI der schnellste Weg. Für automatisierte Deployments empfiehlt sich die Integration der Invalidierung in die CI/CD-Pipeline — direkt nach dem S3-Sync-Schritt. Die offizielle Dokumentation zu CloudFront-Invalidierungen findest du unter docs.aws.amazon.com/AmazonCloudFront.

Verwandte Themen auf diesem Blog: CloudFront-Cache-Verhalten konfigurieren, S3-Bucket als CloudFront-Origin einrichten.

Glossar: Schlüsselbegriffe für CloudFront-Invalidierungen

BegriffBedeutung
InvalidierungAPI-Aufruf, der CloudFront anweist, gecachte Objekte an Edge-Locations zu entfernen, sodass beim nächsten Request die aktuelle Version vom Origin geholt wird.
TTL (Time to Live)Zeitspanne, für die CloudFront ein Objekt im Cache hält, bevor es erneut beim Origin nachfragt. Wird durch Cache-Control-Header oder CloudFront-Verhaltensregeln gesteuert.
Edge-LocationGeografisch verteilter CloudFront-Serverstandort, der Inhalte näher beim Endnutzer cached und ausliefert.
Cache-BustingStrategie, bei der Dateinamen versioniert werden, um Cache-Invalidierungen zu vermeiden — neue Dateinamen sind automatisch Cache-Misses.
Origin-FetchAnfrage eines Edge-Nodes an den Origin (z.B. S3), um ein Objekt zu holen, das nicht im Cache ist oder dessen TTL abgelaufen ist.

Kommentare

Beliebte Posts aus diesem Blog

EC2 ohne Internetzugang im eigenen VPC – Internet Gateway und Route Table korrekt einrichten

LSI vs. GSI in DynamoDB: Den richtigen Sekundärindex wählen

ElastiCache Redis einsetzen: Wann ein Caching-Layer deine RDS-Datenbank entlastet