Lambda Environment Variables: Konfiguration, KMS-Verschlüsselung und Best Practices
Du hast einen Datenbankendpunkt, der sich je nach Umgebung ändert — Entwicklung, Staging, Produktion — und willst ihn nicht direkt in den Funktionscode schreiben. Lambda Environment Variables lösen genau dieses Problem, aber der Teufel steckt im Detail: Wann reichen die Standard-Verschlüsselung aus, wann brauchst du einen eigenen KMS-Schlüssel, und wie liest du die Werte zur Laufzeit korrekt aus?
TL;DR: Lambda Environment Variables auf einen Blick
| Aspekt | Detail |
|---|---|
| Speicherort | Funktionskonfiguration, nicht im Deployment-Paket |
| Standard-Verschlüsselung | AWS-verwalteter Schlüssel (aws/lambda) — automatisch, kein Setup nötig |
| Eigener KMS-Schlüssel | Kundenverwalteter CMK — explizite IAM-Berechtigung erforderlich |
| Laufzeitzugriff | Über Betriebssystem-Umgebungsvariablen (z. B. process.env, os.environ) |
| Maximale Größe | 4 KB gesamt für alle Variablen — Limits und Preise immer in der offiziellen AWS-Dokumentation prüfen |
| Sichtbarkeit im Klartext | Standardmäßig im Konsolenbereich sichtbar — Hilfsverschlüsselung mit eigenem CMK empfohlen |
Wie Lambda Environment Variables funktionieren
Lambda injiziert die konfigurierten Schlüssel-Wert-Paare als Betriebssystem-Umgebungsvariablen in den Ausführungskontext, bevor dein Handler-Code aufgerufen wird. Das bedeutet: Die Werte sind bereits vorhanden, wenn deine init-Phase läuft — du kannst sie also sicher außerhalb des Handlers lesen, um teure Initialisierungen zu cachen.
Wichtig zu verstehen: Lambda verschlüsselt alle Environment Variables im Ruhezustand. Ohne eigene Konfiguration verwendet der Dienst einen AWS-verwalteten Schlüssel im Namespace aws/lambda. Dieser Schlüssel liegt vollständig unter AWS-Kontrolle — du hast keine Möglichkeit, Schlüsselrichtlinien anzupassen oder die Nutzung in CloudTrail granular zu verfolgen. Sobald du einen kundenverwalteten CMK (Customer Managed Key) konfigurierst, dreht sich das Verhältnis um: Du kontrollierst den Schlüssel, die Rotation und die Zugriffsrichtlinie.
Environment Variables"] --> B["KMS-Verschlüsselung
at rest"] B --> C["Execution Context
Kaltstart"] C --> D["KMS Decrypt
kms:Decrypt"] D --> E["OS-Umgebungsvariablen
injiziert"] E --> F["Handler-Code
os.environ / process.env"] style A fill:#232F3E,color:#FF9900 style B fill:#232F3E,color:#FF9900 style C fill:#1A6B3C,color:#ffffff style D fill:#8B0000,color:#ffffff style E fill:#1A6B3C,color:#ffffff style F fill:#232F3E,color:#FF9900
- Konfigurationszeit: Environment Variables werden in der Funktionskonfiguration gespeichert und mit dem gewählten KMS-Schlüssel verschlüsselt.
- Deployment: Lambda entschlüsselt die Variablen beim Start des Execution Context und injiziert sie als OS-Umgebungsvariablen.
- Handler-Aufruf: Dein Code liest die Werte über die Standard-Laufzeit-API (z. B.
os.environ['DB_ENDPOINT']). - KMS-Aufruf (nur bei CMK): Lambda ruft
kms:Decryptauf — dieser Aufruf erscheint in CloudTrail und kann über die Schlüsselrichtlinie eingeschränkt werden.
Environment Variables setzen — CLI und Konsole
Der direkteste Weg ist die AWS CLI. Hier setzt du eine Variable beim Erstellen der Funktion:
aws lambda create-function \
--function-name meine-funktion \
--runtime python3.12 \
--role arn:aws:iam::123456789012:role/MeineLambdaRole \
--handler app.handler \
--zip-file fileb://function.zip \
--environment 'Variables={DB_ENDPOINT=db.example.internal,APP_ENV=production}'
Für eine bereits existierende Funktion verwendest du update-function-configuration. Achtung: Dieser Befehl ersetzt alle bestehenden Environment Variables vollständig — kein Merge, kein Patch.
aws lambda update-function-configuration \
--function-name meine-funktion \
--environment 'Variables={DB_ENDPOINT=db.example.internal,APP_ENV=production,LOG_LEVEL=INFO}'
Aktuelle Konfiguration prüfen:
aws lambda get-function-configuration \
--function-name meine-funktion \
--query 'Environment'
KMS-Verschlüsselung mit eigenem CMK konfigurieren
Wenn der Datenbankendpunkt als sensitiv gilt — oder du Compliance-Anforderungen hast, die Schlüsselnachweise in CloudTrail erfordern — brauchst du einen kundenverwalteten CMK. Die Standardverschlüsselung reicht dann nicht aus, weil du weder Schlüsselrotation noch Zugriffsrichtlinien kontrollierst.
Schritt 1: CMK erstellen
aws kms create-key \
--description 'CMK fuer Lambda Environment Variables' \
--key-usage ENCRYPT_DECRYPT \
--origin AWS_KMS
Gib dem Schlüssel einen lesbaren Alias:
aws kms create-alias \
--alias-name alias/lambda-env-key \
--target-key-id <KEY_ID_AUS_VORHERIGEM_BEFEHL>
Schritt 2: Lambda-Ausführungsrolle berechtigen
Die Ausführungsrolle der Lambda-Funktion muss kms:Decrypt auf dem CMK ausführen dürfen. Ohne diese Berechtigung startet die Funktion nicht — Lambda kann die Variablen nicht entschlüsseln.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LambdaKMSDecrypt",
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "arn:aws:kms:us-east-1:123456789012:key/<DEIN-KEY-ID>"
}
]
}
Diese Policy an die Ausführungsrolle anhängen:
aws iam put-role-policy \
--role-name MeineLambdaRole \
--policy-name LambdaKMSDecryptPolicy \
--policy-document file://kms-decrypt-policy.json
Schritt 3: Funktion mit CMK konfigurieren
aws lambda update-function-configuration \
--function-name meine-funktion \
--kms-key-arn arn:aws:kms:us-east-1:123456789012:key/<DEIN-KEY-ID> \
--environment 'Variables={DB_ENDPOINT=db.example.internal,APP_ENV=production}'
--kms-key-arn Lambda->>KMS: kms:Encrypt (Variablen verschlüsseln) KMS-->>Lambda: Verschlüsselte Variablen Lambda-->>Dev: Konfiguration gespeichert Note over Lambda,KMS: Beim Kaltstart Lambda->>Role: Identität annehmen Lambda->>KMS: kms:Decrypt (mit Ausführungsrolle) alt Berechtigung vorhanden KMS-->>Lambda: Entschlüsselte Variablen Lambda->>Lambda: OS-Env injizieren else AccessDenied KMS-->>Lambda: AccessDeniedException Lambda-->>Lambda: Kaltstart schlägt fehl end
- Lambda-Konfiguration: Der CMK-ARN wird in der Funktionskonfiguration gespeichert.
- Verschlüsselung: Lambda ruft
kms:Encryptauf, um die Variablen zu verschlüsseln — dieser Aufruf erfolgt unter der Identität des aufrufenden Principals. - Entschlüsselung beim Start: Lambda ruft
kms:Decryptmit der Ausführungsrolle auf. Fehlt die Berechtigung, schlägt der Kaltstart fehl. - CloudTrail-Audit: Jeder
kms:Decrypt-Aufruf erscheint im CloudTrail-Log mit der Funktions-ARN als Aufrufer-Identität.
Variablen zur Laufzeit lesen
Lambda macht die Variablen als Standard-OS-Umgebungsvariablen verfügbar. Kein SDK-Aufruf nötig — einfache Laufzeit-APIs reichen:
Python:
import os
def handler(event, context):
db_endpoint = os.environ['DB_ENDPOINT']
app_env = os.environ.get('APP_ENV', 'development') # mit Fallback
# ...
Node.js:
exports.handler = async (event) => {
const dbEndpoint = process.env.DB_ENDPOINT;
const appEnv = process.env.APP_ENV || 'development';
// ...
};
Java:
String dbEndpoint = System.getenv("DB_ENDPOINT");
Environment Variables verhalten sich wie jede andere OS-Umgebungsvariable im Prozess. Der Unterschied zu einem normalen Server: Der Execution Context kann zwischen Aufrufen eingefroren und wiederverwendet werden. Variablen, die du außerhalb des Handlers initialisierst, werden beim Warm-Start nicht neu geladen — das ist ein Feature, kein Bug.
Fehlerbild aus der Praxis: Kaltstart schlägt fehl ohne klare Fehlermeldung
Ein typisches Fehlerbild: Du konfigurierst einen CMK, deployest die Funktion, und beim ersten Aufruf kommt ein generischer Fehler zurück — kein Stack-Trace, kein klarer Hinweis auf KMS. CloudWatch Logs zeigen nur Runtime exited with error: signal: killed oder eine knappe Timeout-Meldung.
Die erste Annahme ist meistens: Code-Fehler, falscher Handler-Pfad, zu wenig Memory. Alle drei falsch.
Der tatsächliche Grund: Die Ausführungsrolle hat keine kms:Decrypt-Berechtigung auf dem CMK. Lambda versucht beim Kaltstart die Variablen zu entschlüsseln, schlägt fehl, und der Execution Context startet nie vollständig. Die Fehlermeldung landet nicht im Handler-Log, weil der Handler nie aufgerufen wurde.
Diagnose über CloudTrail — nicht über CloudWatch:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=Decrypt \
--start-time 2024-01-15T10:00:00Z \
--end-time 2024-01-15T10:30:00Z
Dort siehst du einen AccessDenied-Eintrag mit dem genauen Principal und dem betroffenen Schlüssel. Das ist der eigentliche Fehler — CloudWatch zeigt nur das Symptom.
Fix: kms:Decrypt in der Ausführungsrolle ergänzen (siehe Schritt 2 oben) und sicherstellen, dass die KMS-Schlüsselrichtlinie die Rolle nicht explizit ablehnt. Ein Deny in der Schlüsselrichtlinie überschreibt jede IAM-Allow-Regel.
Wann Environment Variables nicht ausreichen
Environment Variables sind für Konfigurationswerte gedacht, nicht für hochsensible Credentials wie Passwörter oder API-Tokens. Für solche Werte ist AWS Secrets Manager oder AWS Systems Manager Parameter Store (SecureString) die bessere Wahl — beide bieten automatische Rotation, feinere Zugriffssteuerung und Audit-Trails auf Wertebene.
Der praktische Unterschied: Mit Environment Variables liegt der entschlüsselte Wert im Speicher des Execution Context und ist über os.environ abrufbar. Mit Secrets Manager rufst du den Wert explizit zur Laufzeit ab — du hast Kontrolle darüber, wann und wie oft der Wert gelesen wird, und kannst Rotation ohne Funktions-Redeployment durchführen.
Zusammenfassung und nächste Schritte mit Lambda Environment Variables
Lambda Environment Variables sind der richtige Weg für Konfigurationswerte wie Datenbankendpunkte, Feature-Flags und Umgebungsbezeichner. Die Standard-Verschlüsselung mit dem AWS-verwalteten Schlüssel ist für die meisten Anwendungsfälle ausreichend. Sobald du Schlüsselkontrolle, CloudTrail-Nachvollziehbarkeit oder Compliance-Anforderungen hast, wechselst du auf einen kundenverwalteten CMK — und stellst sicher, dass die Ausführungsrolle kms:Decrypt besitzt, bevor du deployest.
- Offizielle Dokumentation: Lambda Environment Variables (AWS Docs)
- KMS-Schlüsselrichtlinien: AWS KMS Key Policies
- Für hochsensible Werte: AWS Secrets Manager oder SSM Parameter Store als Alternative evaluieren
Glossar
| Begriff | Bedeutung |
|---|---|
| CMK (Customer Managed Key) | Kundenverwalteter KMS-Schlüssel — du kontrollierst Richtlinie, Rotation und Zugriff |
| Execution Context | Die Laufzeitumgebung einer Lambda-Funktion — wird bei Warm-Starts wiederverwendet |
| Kaltstart (Cold Start) | Erster Start eines neuen Execution Context — beinhaltet Initialisierung und Entschlüsselung der Variablen |
| Ausführungsrolle | IAM-Rolle, die Lambda beim Ausführen der Funktion annimmt — bestimmt alle API-Berechtigungen |
| CloudTrail | AWS-Audit-Log für API-Aufrufe — einzige zuverlässige Quelle für KMS-Zugriffsfehler bei Lambda-Kaltstarts |
Kommentare
Kommentar veröffentlichen