AWS Free Tier Kostenalarm einrichten: CloudWatch Billing Alarm unter $5

Wer ein neues AWS-Konto anlegt und erste Experimente startet, bemerkt oft erst Wochen später, dass ein vergessener EC2-Instance oder ein NAT Gateway still und leise Kosten verursacht hat — der Free Tier schützt nicht vor allem. Ein CloudWatch Billing Alarm ist die einfachste Absicherung, die du einrichten kannst, bevor du überhaupt die erste Ressource deployest.

TL;DR: Kostenalarm für AWS Free Tier

SchrittAktionWichtiger Hinweis
1Billing Alerts im Root-Account aktivierenMuss einmalig in den Billing Preferences gesetzt werden
2SNS Topic erstellen und E-Mail bestätigenOhne Bestätigung der E-Mail werden keine Alarme zugestellt
3CloudWatch Alarm auf EstimatedCharges setzenMetrik ist nur in us-east-1 verfügbar
4Alarm testenSchwellenwert temporär auf $0.01 setzen zum Verifizieren

Wie AWS Billing Metriken funktionieren

Bevor du den ersten CLI-Befehl ausführst, musst du verstehen, warum dieser Alarm in der falschen Region einfach nicht erscheint. Die CloudWatch-Metrik EstimatedCharges wird von AWS ausschließlich in der Region us-east-1 (N. Virginia) veröffentlicht — unabhängig davon, in welcher Region deine Ressourcen laufen. Das ist kein Bug, sondern das dokumentierte Verhalten des AWS Billing-Systems.

Die Metrik wird alle 6 Stunden aktualisiert und zeigt die kumulierten geschätzten Kosten seit Beginn des aktuellen Kalendermonats. Sie ist kein Echtzeit-Signal — ein Alarm kann also bis zu 6 Stunden verzögert auslösen, nachdem der Schwellenwert tatsächlich überschritten wurde.

Zusätzlich muss die Aktivierung von Billing Alerts einmalig im AWS-Konto vorgenommen werden. Ohne diesen Schritt publiziert AWS die EstimatedCharges-Metrik nicht, und der CloudWatch Alarm kann nicht erstellt werden.

graph LR A["AWS Billing Service"] -->|"alle 6 Stunden
EstimatedCharges"| B["CloudWatch Metrik
us-east-1"] B -->|"Schwellenwert > $5"| C["CloudWatch Alarm
Status: ALARM"] C -->|"Alarm-Aktion"| D["SNS Topic"] D -->|"E-Mail Notification"| E["Empfaenger
bestaetigt"] style A fill:#FF9900,color:#000 style B fill:#1A73E8,color:#fff style C fill:#D93025,color:#fff style D fill:#34A853,color:#fff style E fill:#4285F4,color:#fff
  1. Billing Service aggregiert alle Servicekosten und publiziert alle 6 Stunden die EstimatedCharges-Metrik nach CloudWatch in us-east-1.
  2. CloudWatch Alarm überwacht den Schwellenwert und wechselt in den Zustand ALARM, sobald der Wert $5 überschreitet.
  3. SNS Topic empfängt die Alarm-Benachrichtigung und leitet sie an alle bestätigten Abonnenten weiter.
  4. E-Mail-Empfänger erhält die Benachrichtigung — aber nur, wenn die Subscription zuvor per Klick bestätigt wurde.

Schritt 1: Billing Alerts im AWS-Konto aktivieren

Dieser Schritt wird am häufigsten übersprungen und ist der häufigste Grund, warum der Alarm später nicht funktioniert. Billing Alerts müssen einmalig über die AWS Billing Console aktiviert werden — das geht nicht per CLI, da es sich um eine Account-Präferenz handelt, die über die Billing Console verwaltet wird.

Navigiere in der AWS Console zu: Billing and Cost Management → Billing Preferences → Alert Preferences und aktiviere 'Receive CloudWatch Billing Alerts'. Speichere die Einstellungen. Dieser Schritt ist nur einmal pro AWS-Konto erforderlich und muss vom Root-User oder einem IAM-User mit Billing-Zugriff durchgeführt werden.

Stell dir vor, du bestellst eine Alarmanlage, aber der Stromanschluss ist noch nicht aktiviert. Der CloudWatch Alarm ist die Alarmanlage — die Billing Preferences sind der Stromanschluss.

Schritt 2: SNS Topic erstellen und E-Mail-Subscription einrichten

Der Alarm braucht einen Kanal, über den er dich erreicht. SNS (Simple Notification Service) übernimmt diese Aufgabe. Wichtig: Alle folgenden CLI-Befehle müssen mit --region us-east-1 ausgeführt werden, da die Billing-Metrik nur dort existiert.

SNS Topic erstellen:

aws sns create-topic \
  --name billing-alarm-topic \
  --region us-east-1

Der Befehl gibt die ARN der neuen Topic zurück, zum Beispiel: arn:aws:sns:us-east-1:123456789012:billing-alarm-topic

E-Mail-Subscription hinzufügen (ersetze die E-Mail-Adresse durch deine eigene):

aws sns subscribe \
  --topic-arn arn:aws:sns:us-east-1:123456789012:billing-alarm-topic \
  --protocol email \
  --notification-endpoint deine-email@beispiel.de \
  --region us-east-1

Nach diesem Befehl erhältst du eine Bestätigungs-E-Mail von AWS SNS. Du musst auf den Bestätigungslink klicken — ohne diese Bestätigung bleibt die Subscription im Status PendingConfirmation und du erhältst keine Alarme. Das ist der zweithäufigste Grund für einen stillen Alarm.

Subscription-Status prüfen:

aws sns list-subscriptions-by-topic \
  --topic-arn arn:aws:sns:us-east-1:123456789012:billing-alarm-topic \
  --region us-east-1

Im Output sollte SubscriptionArn einen vollständigen ARN (nicht PendingConfirmation) anzeigen, bevor du weitermachst.

Schritt 3: CloudWatch Billing Alarm erstellen

Jetzt wird der eigentliche Alarm konfiguriert. Der Alarm überwacht die Metrik EstimatedCharges im Namespace AWS/Billing und löst aus, sobald der Wert den Schwellenwert von 5 USD überschreitet.

🔽 CLI-Befehl zum Erstellen des Billing Alarms (klicken zum Ausklappen)
aws cloudwatch put-metric-alarm \
  --alarm-name 'FreeTier-Kostenalarm-5USD' \
  --alarm-description 'Alarm wenn geschaetzte Kosten 5 USD ueberschreiten' \
  --metric-name EstimatedCharges \
  --namespace AWS/Billing \
  --statistic Maximum \
  --dimensions Name=Currency,Value=USD \
  --period 86400 \
  --evaluation-periods 1 \
  --threshold 5 \
  --comparison-operator GreaterThanThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:billing-alarm-topic \
  --treat-missing-data notBreaching \
  --region us-east-1

Einige Parameter verdienen eine Erklärung, weil falsche Werte hier zu einem Alarm führen, der entweder nie auslöst oder dauerhaft im ALARM-Zustand bleibt:

  • --statistic Maximum: Billing-Metriken werden als Einzelwerte publiziert, nicht als Zeitreihen mit Aggregation. Maximum ist der korrekte Statistik-Typ für diese Metrik.
  • --period 86400: 86400 Sekunden = 24 Stunden. Da die Metrik nur alle 6 Stunden aktualisiert wird, ist ein täglicher Evaluierungszeitraum sinnvoll.
  • --treat-missing-data notBreaching: Verhindert, dass der Alarm in den ALARM-Zustand wechselt, wenn zu Beginn eines neuen Monats noch keine Daten vorliegen.
  • --dimensions Name=Currency,Value=USD: Ohne diese Dimension findet CloudWatch die Metrik nicht.

Schritt 4: Alarm-Konfiguration verifizieren

Ein Alarm, den du nie getestet hast, ist kein Alarm — es ist eine Hoffnung. Prüfe den aktuellen Zustand des Alarms direkt nach der Erstellung:

aws cloudwatch describe-alarms \
  --alarm-names 'FreeTier-Kostenalarm-5USD' \
  --region us-east-1

Im Output interessieren dich vor allem zwei Felder: StateValue sollte OK oder INSUFFICIENT_DATA sein (letzteres ist normal, wenn noch keine Billing-Daten für den aktuellen Monat vorliegen), und AlarmActions sollte den SNS-ARN enthalten, den du in Schritt 2 erstellt hast.

Wenn StateValue direkt nach der Erstellung ALARM zeigt, hast du den Schwellenwert bereits überschritten — oder die Metrik-Konfiguration stimmt nicht. Prüfe in diesem Fall, ob die Billing-Metrik überhaupt Daten liefert:

aws cloudwatch list-metrics \
  --namespace AWS/Billing \
  --metric-name EstimatedCharges \
  --region us-east-1

Wenn dieser Befehl eine leere Metrics-Liste zurückgibt, ist Schritt 1 (Billing Alerts aktivieren) noch nicht abgeschlossen.

IAM-Berechtigungen für den Billing Alarm

Falls du diese Schritte nicht als Root-User, sondern als IAM-User oder über eine IAM-Rolle ausführst, benötigst du die folgenden Mindestberechtigungen. Das Prinzip der minimalen Rechtevergabe gilt auch hier — gib nicht einfach cloudwatch:* oder sns:*.

🔽 Minimale IAM-Policy für Billing Alarm Setup (klicken zum Ausklappen)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CloudWatchBillingAlarm",
      "Effect": "Allow",
      "Action": [
        "cloudwatch:PutMetricAlarm",
        "cloudwatch:DescribeAlarms",
        "cloudwatch:ListMetrics"
      ],
      "Resource": "*"
    },
    {
      "Sid": "SNSBillingTopic",
      "Effect": "Allow",
      "Action": [
        "sns:CreateTopic",
        "sns:Subscribe",
        "sns:ListSubscriptionsByTopic"
      ],
      "Resource": "arn:aws:sns:us-east-1:123456789012:billing-alarm-topic"
    }
  ]
}

Hinweis: cloudwatch:ListMetrics und cloudwatch:DescribeAlarms erfordern "Resource": "*", da diese Read/List-Aktionen keine ressourcenspezifische ARN-Einschränkung unterstützen. Das ist dokumentiertes Verhalten im AWS Service Authorization Reference.

Zusätzlich benötigt ein IAM-User Zugriff auf die Billing Console, um Schritt 1 (Billing Alerts aktivieren) durchführen zu können. Dafür muss der Root-User im IAM-Dashboard die Option 'IAM user and role access to Billing information' aktiviert haben.

Häufige Fehler und warum sie auftreten

graph TD A["Start: Billing Alarm einrichten"] --> B{"Billing Alerts
aktiviert?"} B -->|"Nein"| C["Billing Preferences:
Alerts aktivieren"] C --> D{"Region korrekt?
us-east-1?"} B -->|"Ja"| D D -->|"Falsche Region"| E["CLI mit
--region us-east-1"] E --> F{"SNS E-Mail
bestaetigt?"} D -->|"us-east-1"| F F -->|"PendingConfirmation"| G["Bestaetigungs-E-Mail
pruefen und klicken"] G --> H["Alarm funktioniert"] F -->|"Bestaetigt"| H style A fill:#FF9900,color:#000 style H fill:#34A853,color:#fff style C fill:#D93025,color:#fff style E fill:#D93025,color:#fff style G fill:#D93025,color:#fff
  1. Billing Alerts nicht aktiviert: Die Metrik EstimatedCharges wird nicht publiziert. Symptom: list-metrics gibt eine leere Liste zurück.
  2. Falsche Region: Alarm in eu-west-1 erstellt, aber die Metrik existiert nur in us-east-1. Symptom: Alarm bleibt dauerhaft in INSUFFICIENT_DATA.
  3. E-Mail nicht bestätigt: SNS Subscription bleibt in PendingConfirmation. Symptom: Alarm löst aus, aber keine E-Mail kommt an.
  4. Alarm funktioniert korrekt: Alle Schritte abgeschlossen, E-Mail bestätigt, Alarm im Zustand OK.

Der klassische Fehlerpfad sieht so aus: Alarm erstellt, eine Woche gewartet, keine E-Mail erhalten, Kosten bereits $12. Rückblickend war die SNS-Subscription nie bestätigt worden — die Bestätigungs-E-Mail landete im Spam-Ordner. Der Alarm hatte korrekt ausgelöst, aber niemanden erreicht.

Billing Alarm für einzelne AWS-Services

Der Alarm auf EstimatedCharges ohne weitere Dimensions-Filter überwacht die Gesamtkosten des Accounts. Du kannst zusätzlich servicespezifische Alarme erstellen, indem du eine zweite Dimension hinzufügst. Das ist nützlich, wenn du wissen willst, ob speziell EC2 oder RDS die Kosten treibt.

aws cloudwatch put-metric-alarm \
  --alarm-name 'EC2-Kostenalarm-3USD' \
  --alarm-description 'Alarm wenn EC2 Kosten 3 USD ueberschreiten' \
  --metric-name EstimatedCharges \
  --namespace AWS/Billing \
  --statistic Maximum \
  --dimensions Name=Currency,Value=USD Name=ServiceName,Value=AmazonEC2 \
  --period 86400 \
  --evaluation-periods 1 \
  --threshold 3 \
  --comparison-operator GreaterThanThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:billing-alarm-topic \
  --treat-missing-data notBreaching \
  --region us-east-1

Die verfügbaren ServiceName-Werte entsprechen den Service-Namen, wie sie in der Billing Console erscheinen (z.B. AmazonEC2, AmazonRDS, AWSLambda). Prüfe die exakten Namen über list-metrics mit dem Namespace AWS/Billing, bevor du den Alarm erstellst.

Nächste Schritte und weiterführende Ressourcen

Ein Billing Alarm auf $5 ist ein guter Anfang, aber kein vollständiges Kostenmanagement. Für produktive Workloads empfiehlt sich zusätzlich:

  • AWS Budgets: Ermöglicht komplexere Budgetregeln, prozentuale Schwellenwerte und Forecasting-basierte Alarme — über die Billing Console oder die AWS Budgets API.
  • AWS Cost Explorer: Für die nachträgliche Analyse, welcher Service oder welche Region die Kosten verursacht hat.
  • AWS Free Tier Usage Alerts: In den Billing Preferences kann zusätzlich ein automatischer Alert aktiviert werden, der warnt, wenn du dich dem Free-Tier-Limit näherst — unabhängig vom CloudWatch Alarm.

Offizielle Dokumentation: Monitoring Estimated Charges with CloudWatch

Glossar: Schlüsselbegriffe

BegriffBedeutung
EstimatedChargesCloudWatch-Metrik im Namespace AWS/Billing, die die kumulierten geschätzten Kosten des aktuellen Kalendermonats anzeigt. Nur in us-east-1 verfügbar.
SNS TopicSimple Notification Service — ein Pub/Sub-Kanal, über den CloudWatch Alarm-Benachrichtigungen an E-Mail, SMS oder andere Endpunkte weiterleitet.
Billing AlertsAccount-Einstellung in den Billing Preferences, die aktiviert werden muss, damit AWS die EstimatedCharges-Metrik in CloudWatch publiziert.
treat-missing-dataCloudWatch Alarm-Parameter, der definiert, wie fehlende Datenpunkte bewertet werden. notBreaching verhindert Fehlalarme bei fehlenden Daten.
Free TierAWS-Programm, das neuen Accounts für 12 Monate bestimmte Ressourcenkontingente kostenlos zur Verfügung stellt. Nicht alle Services und Nutzungsarten sind abgedeckt.

Kommentare

Beliebte Posts aus diesem Blog

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

EC2 SSH Verbindungs-Timeout: Security Group Inbound-Regeln richtig konfigurieren