Dieser Leitfaden führt Sie durch die Bereitstellung mehrerer AWS Lambda-Funktionen mit Pulumi, einem Infrastruktur-als-Code-Tool, mit dem Sie Cloud-Ressourcen mit vertrauten Programmiersprachen wie JavaScript, TypeScript, Python, Go und anderen definieren und verwalten können.
Bevor Sie beginnen, stellen Sie sicher, dass Sie die folgenden Voraussetzungen installiert haben:
- Pulumi CLI: Installieren Sie die Pulumi CLI, indem Sie den Anweisungen auf der offiziellen Pulumi-Website folgen.
- AWS-Konto: Sie benötigen ein AWS-Konto mit entsprechenden Berechtigungen, um Lambda-Funktionen, IAM-Rollen und andere erforderliche Ressourcen zu erstellen.
- Programmiersprache: Wählen Sie eine Programmiersprache, die von Pulumi unterstützt wird. In diesem Beispiel verwenden wir TypeScript, aber Sie können auch JavaScript, Python, Go usw. verwenden.
I. AWS-Profil konfigurieren
Wenn Sie ein lokales AWS-Profil konfigurieren, können Sie mehrere AWS-Anmeldeinformationen auf Ihrem lokalen Computer verwalten, was besonders nützlich ist, wenn Sie mit verschiedenen AWS-Konten oder Rollen arbeiten. Hier erfahren Sie, wie Sie ein lokales AWS-Profil konfigurieren können:
- Wenn Sie die AWS-Befehlszeilenschnittstelle (CLI) noch nicht installiert haben, können Sie dies tun, indem Sie die Anweisungen in der AWS CLI-Dokumentation befolgen.
- Führen Sie den folgenden Befehl in Ihrem Terminal aus:
aws configure --profile <profile-name>
Ersetzen Sie den Namen durch den gewünschten Namen für Ihr Profil. Geben Sie zum Beispiel die folgenden Informationen ein, wenn Sie dazu aufgefordert werden:
- AWS-Zugangsschlüssel-ID: Dies ist Ihre AWS Access Key ID, die Sie in der AWS Management Console unter IAM (Identity and Access Management) > Users > Security credentials erhalten.
- AWS Secret Access Key: Dies ist Ihr geheimer AWS-Zugangsschlüssel, den Sie erhalten, wenn Sie einen Zugangsschlüssel in der AWS Management Console generieren.
- Specify Default Region and Output Format
Sie werden auch aufgefordert, die Standardregion und das Standardausgabeformat anzugeben. Diese Angaben sind optional, aber es wird empfohlen, sie aus Gründen der Bequemlichkeit festzulegen.
- Standardregionsname: Geben Sie die AWS-Region ein, die Sie verwenden möchten, z. B. eu-west-1.
- Standardausgabeformat: Sie können das Ausgabeformat wählen, z. B. json.
- Confirm Configuration - Überprüfen Sie die auf dem Terminal angezeigten Konfigurationsdetails und bestätigen Sie, dass sie korrekt sind. Nach der Bestätigung wird das AWS-Profil lokal auf Ihrem Rechner konfiguriert.
- Verify Configuration - Um zu überprüfen, ob Ihr Profil erfolgreich konfiguriert wurde, können Sie die auf Ihrem lokalen Rechner gespeicherten AWS CLI-Konfigurationsdateien überprüfen.
- Unter Linux oder macOS überprüfen Sie die Dateien ~/.aws/config und ~/.aws/credentials.
- Unter Windows überprüfen Sie die Dateien C:\Users\USERNAME.aws\config und C:\Users\USERNAME.aws\credentials.
II. Erstellen eines privaten Buckets zum Speichern der Pulumi-Statusdateien
Um einen privaten S3-Bucket über die AWS-Befehlszeilenschnittstelle (CLI) zu erstellen, können Sie den Befehl AWS s3api create-bucket verwenden und die entsprechenden ACL-Einstellungen (Access Control List) angeben. Hier erfahren Sie, wie Sie einen privaten Bucket erstellen:
aws s3api create-bucket --bucket --region --profile --acl private
Ersetzen Sie durch den gewünschten Namen für Ihren S3-Bucket und durch die AWS-Region, in der Sie den Bucket erstellen möchten. Dieser Befehl erstellt einen S3-Bucket mit dem angegebenen Namen in der angegebenen Region und setzt seine ACL auf privat, d. h. nur der Bucket-Besitzer hat standardmäßig Zugriff darauf.
III. Klonen und Einrichten
Erstellen Sie ein neues Verzeichnis und klonen Sie unser offizielles Repository https://github.com/joto2itgix/lambda_deploy. Und initialisieren Sie das Pulumi-Projekt:
mkdir lambda_deploy
cd lambda_deploy
git clone
npm install
npm install @pulumi/archive
IV. Überprüfung des Pulumi Code
Öffnen Sie die Datei index.ts in Ihrem bevorzugten Editor
import * as aws from "@pulumi/aws";
import * as ELEMENTS from "./elements"
(async () => {
var clientName = "lambdas"
var env = clientName+"-dev"
var CONFIG: any;
CONFIG = await ELEMENTS.readFile(env+".yaml");
const vpc_main = ELEMENTS.createVPC(env, CONFIG["vpc"]["name"], CONFIG["vpc"]["cidr"], CONFIG["vpc"]["tenancy"], CONFIG["default_tags"])
const gw1 = ELEMENTS.createGW(env, "gw", vpc_main, CONFIG["default_tags"])
const subnets:any = []
CONFIG["subnets"].forEach(function (subnet: any) {
subnets.push(
ELEMENTS.createSubnet (env, subnet["name"], vpc_main, subnet["cidr"], CONFIG["region"], subnet["zone"], gw1, CONFIG["default_tags"])
)
});
var ingress_public = [
{ protocol: "tcp", fromPort: 80, toPort: 80, cidrBlocks: ["0.0.0.0/0"] },
{ protocol: "tcp", fromPort: 443, toPort: 443, cidrBlocks: ["0.0.0.0/0"] },
]
var egress = [
{ protocol: "-1", fromPort: 0, toPort: 0, cidrBlocks: ["0.0.0.0/0"] },
]
const webSecurityGroup = ELEMENTS.createNSG (env, "-sg-web", vpc_main, ingress_public, egress)
//SECRETS
const secretManager1 = new aws.secretsmanager.Secret(env+"-sm", {
forceOverwriteReplicaSecret: false,
});
// Store a new secret version
const secretVersion1 = new aws.secretsmanager.SecretVersion(env+"-secrets", {
secretId: secretManager1.id,
secretString: '{"test_var1":"test_valu1","test_valu2":"asd","test_var3":"test_valu3"}',
});
const secretManagerEndpoint = new aws.ec2.VpcEndpoint(env+"-sm-endpoint", {
vpcId: vpc_main.id,
serviceName: "com.amazonaws."+CONFIG["region"]+".secretsmanager",
vpcEndpointType: "Interface",
privateDnsEnabled: true,
subnetIds: subnets,
securityGroupIds: [],
});
//Hello World Lambda
var recipe = {
src: "helloworld",
runtime: "python3.12",
handler: "lambda_handler"
}
var actions = [
"ec2:CreateNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface"
]
const lambdaHW = ELEMENTS.createLambda(env, "hw-py", recipe, actions, [subnets[0].id], [webSecurityGroup.id], {foo: "bar"})
const lambdaHWDistribution = ELEMENTS.createCF(env, "hw-py", lambdaHW.functionUrl)
//Print env Lambda
var recipe = {
src: "printenv",
runtime: "python3.12",
handler: "lambda_handler"
}
var actions = [
"ec2:CreateNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface"
]
const lambdaPE = ELEMENTS.createLambda(env, "pe-py", recipe, actions, [subnets[0].id], [webSecurityGroup.id], {foo2: "bar2"})
})()
Dieser Code nutzt die Pulumi Infrastructure as Code (IaC)-Bibliothek zur Definition und Bereitstellung von AWS-Ressourcen. Schauen wir uns die wichtigsten Komponenten und Aktionen im Skript an:
- Importe: Das Skript importiert die erforderlichen Module aus der Bibliothek @pulumi/aws von Pulumi und ein benutzerdefiniertes Modul ./elements.
- Asynchrone Funktion: Das Skript definiert eine asynchrone Funktion unter Verwendung eines sofort aufgerufenen Funktionsausdrucks (IIFE). Diese Funktion scheint der Haupteinstiegspunkt für die Bereitstellung von AWS-Ressourcen zu sein.
- Umgebungskonfiguration: Lädt die umgebungsspezifische Konfiguration aus YAML-Dateien mithilfe der Funktion ELEMENTS.readFile.
- Erstellung von VPC und Subnetzen: Das Skript erstellt eine Virtual Private Cloud (VPC) und die zugehörigen Subnetze mithilfe der Funktionen ELEMENTS.createVPC und ELEMENTS.createSubnet.
- Netzwerksicherheitsgruppen: Es wird eine Netzwerksicherheitsgruppe (NSG) für den Webverkehr erstellt (webSecurityGroup).
- Verwaltung von Geheimnissen: Es werden Secret Manager-Ressourcen erstellt (secretManager1, secretVersion1, secretManagerEndpoint), um Geheimnisse im AWS Secrets Manager zu verwalten.
- Lambda-Funktionen: Das Skript definiert zwei Lambda-Funktionen (lambdaHW, lambdaPE) mithilfe der Funktion ELEMENTS.createLambda. Jede Lambda-Funktion ist mit bestimmten Aktionen und Sicherheitsgruppen verbunden.
- CloudFront: Es wird eine CloudFront-Verteilung (lambdaHWDistribution) für die Lambda-Funktion lambdaHW erstellt.
- Skriptausführung: Das Skript wird bei der Ausführung sofort ausgeführt.
V. Lambda-Funktionscode vorbereiten
In diesem Beispiel sind die Lambda-Funktionen einfache und separate Python-Dateien. Aber mit Leichtigkeit kann auf komplexe, oder diejenigen mit unterschiedlichen Laufzeit erweitert werden.
VI. Bereitstellung von
Führen Sie den folgenden Befehl aus, um Ihren Pulumi-Stack einzusetzen:
pulumi login 's3://itgix-lambdas-pulumi-state?region=eu-west-1&profile=itgix'
export PULUMI_CONFIG_PASSPHRASE=
pulumi stack select lambdas --create --non-interactive
pulumi config set aws:region eu-west-1
pulumi config set aws:profile itgix
pulumi preview
pulumi up --yes --non-interactive
- pulumi Anmeldung: Dieser Befehl wird zur Authentifizierung beim Pulumi-Dienst verwendet. Er gibt einen Speicherort für den Status (s3://itgix-lambdas-pulumi-state?region=eu-west-1&profile=itgix) an, an dem der Status des Pulumi-Stacks gespeichert wird. Die Optionen -region und -profile geben die AWS-Region bzw. das AWS-Profil an, die für die Authentifizierung verwendet werden sollen.
- export PULUMI_CONFIG_PASSPHRASE=: Dieser Befehl exportiert eine leere Passphrase in die Umgebungsvariable PULUMI_CONFIG_PASSPHRASE. Diese Variable wird für die Verschlüsselung von sensiblen Konfigurationswerten im Pulumi-Stack verwendet.
- pulumi stack select lambdas -create -non-interactive: Dieser Befehl wählt den Pulumi-Stack namens lambdas aus. Wenn der Stack nicht existiert, wird er erstellt (-create). Die Option -non-interactive gibt an, dass der Befehl nicht nach Benutzereingaben fragen soll, was für die Automatisierung nützlich ist.
- pulumi config set aws:region eu-west-1: Dieser Befehl setzt die AWS-Regionalkonfiguration für den ausgewählten Pulumi-Stack auf eu-west-1. Diese Region wird für die Bereitstellung von AWS-Ressourcen verwendet.
- pulumi config set aws:profile itgix: Dieser Befehl setzt die AWS-Profilkonfiguration für den ausgewählten Pulumi-Stack auf itgix. Dieses Profil wird für die Authentifizierung bei der Interaktion mit AWS-Diensten verwendet.
- pulumi preview: Dieser Befehl zeigt eine Vorschau der Änderungen an, die auf die Infrastruktur angewendet werden. Er zeigt die Ressourcen an, die basierend auf dem aktuellen Pulumi-Programm erstellt, aktualisiert oder gelöscht werden.
- pulumi up -yes -non-interactive: Dieser Befehl wendet die Änderungen auf die Infrastruktur an. Mit der Option -yes werden die Änderungen automatisch genehmigt und angewendet, ohne dass eine Bestätigung verlangt wird. Mit der Option -non-interactive wird sichergestellt, dass der Befehl keine Benutzereingaben abfragt.
Insgesamt meldet sich dieses Skript beim Pulumi-Service an, wählt oder erstellt einen Pulumi-Stack, konfiguriert AWS-Regionen- und Profileinstellungen, zeigt eine Vorschau der Infrastrukturänderungen an und wendet die Änderungen an, um die im Pulumi-Programm definierten AWS-Ressourcen bereitzustellen.
The output will look something like this.
vladimir.dimitrov@localhost:~/github/PROJECTS/lambda_deploy> pulumi login 's3://itgix-lambdas-pulumi-state?region=eu-west-1&profile=itgix'
Logged in to localhost.localdomain as vladimir.dimitrov (s3://itgix-lambdas-pulumi-state?region=eu-west-1&profile=itgix)
vladimir.dimitrov@localhost:~/github/PROJECTS/lambda_deploy>
vladimir.dimitrov@localhost:~/github/PROJECTS/lambda_deploy> export PULUMI_CONFIG_PASSPHRASE=
vladimir.dimitrov@localhost:~/github/PROJECTS/lambda_deploy> pulumi stack select lambdas --create --non-interactive
vladimir.dimitrov@localhost:~/github/PROJECTS/lambda_deploy> pulumi config set aws:region eu-west-1
vladimir.dimitrov@localhost:~/github/PROJECTS/lambda_deploy> pulumi config set aws:profile itgix
vladimir.dimitrov@localhost:~/github/PROJECTS/lambda_deploy>
vladimir.dimitrov@localhost:~/github/PROJECTS/lambda_deploy> pulumi preview
Previewing update (lambdas):
Type Name Plan
pulumi:pulumi:Stack lambdas-lambdas create
├─ aws:iam:Policy lambdas-dev-pe-py-policy create
├─ aws:iam:Policy lambdas-dev-hw-py-policy create
├─ aws:secretsmanager:Secret lambdas-dev-sm create
├─ aws:ec2:Vpc lambdas-dev-vpc create
├─ aws:secretsmanager:SecretVersion lambdas-dev-secrets create
├─ aws:iam:Role lambdas-dev-pe-py-iam create
├─ aws:iam:Role lambdas-dev-hw-py-iam create
├─ aws:ec2:RouteTable lambdas-dev-rt1 create
├─ aws:ec2:Subnet lambdas-dev-subnet create
├─ aws:ec2:InternetGateway lambdas-dev-gw create
├─ aws:ec2:SecurityGroup lambdas-dev-sg-web create
├─ aws:ec2:VpcEndpoint lambdas-dev-sm-endpoint create
├─ aws:ec2:RouteTableAssociation lambdas-dev-rt1a create
├─ aws:lambda:Function lambdas-dev-pe-py-printenv create
├─ aws:lambda:FunctionUrl lambdas-dev-pe-py-url create
├─ aws:lambda:Function lambdas-dev-hw-py-helloworld create
└─ aws:lambda:FunctionUrl lambdas-dev-hw-py-url create
Resources:
18 to create
vladimir.dimitrov@localhost:~/github/PROJECTS/lambda_deploy>
vladimir.dimitrov@localhost:~/github/PROJECTS/lambda_deploy> pulumi up --yes --non-interactive
Previewing update (lambdas):
pulumi:pulumi:Stack lambdas-lambdas create
@ previewing update….
aws:secretsmanager:Secret lambdas-dev-sm create
aws:iam:Policy lambdas-dev-hw-py-policy create
aws:ec2:Vpc lambdas-dev-vpc create
aws:iam:Policy lambdas-dev-pe-py-policy create
aws:secretsmanager:SecretVersion lambdas-dev-secrets create
aws:iam:Role lambdas-dev-hw-py-iam create
aws:iam:Role lambdas-dev-pe-py-iam create
aws:ec2:Subnet lambdas-dev-subnet create
aws:ec2:InternetGateway lambdas-dev-gw create
aws:ec2:SecurityGroup lambdas-dev-sg-web create
aws:ec2:RouteTable lambdas-dev-rt1 create
aws:ec2:VpcEndpoint lambdas-dev-sm-endpoint create
aws:lambda:Function lambdas-dev-pe-py-printenv create
aws:lambda:Function lambdas-dev-hw-py-helloworld create
aws:ec2:RouteTableAssociation lambdas-dev-rt1a create
aws:lambda:FunctionUrl lambdas-dev-pe-py-url create
aws:lambda:FunctionUrl lambdas-dev-hw-py-url create
pulumi:pulumi:Stack lambdas-lambdas create
Resources:
18 to create
Updating (lambdas):
pulumi:pulumi:Stack lambdas-lambdas creating (0s)
@ updating……
aws:iam:Policy lambdas-dev-pe-py-policy creating (0s)
@ updating….
aws:iam:Policy lambdas-dev-pe-py-policy created (1s)
aws:iam:Policy lambdas-dev-hw-py-policy creating (0s)
aws:secretsmanager:Secret lambdas-dev-sm creating (0s)
aws:ec2:Vpc lambdas-dev-vpc creating (0s)
aws:iam:Role lambdas-dev-pe-py-iam creating (0s)
@ updating….
aws:iam:Policy lambdas-dev-hw-py-policy created (1s)
@ updating….
aws:secretsmanager:Secret lambdas-dev-sm created (1s)
aws:iam:Role lambdas-dev-hw-py-iam creating (0s)
@ updating….
aws:iam:Role lambdas-dev-pe-py-iam created (2s)
aws:secretsmanager:SecretVersion lambdas-dev-secrets creating (0s)
@ updating….
aws:iam:Role lambdas-dev-hw-py-iam created (1s)
@ updating….
aws:secretsmanager:SecretVersion lambdas-dev-secrets created (1s)
@ updating…………
aws:ec2:Vpc lambdas-dev-vpc created (13s)
aws:ec2:InternetGateway lambdas-dev-gw creating (0s)
aws:ec2:Subnet lambdas-dev-subnet creating (0s)
aws:ec2:SecurityGroup lambdas-dev-sg-web creating (0s)
@ updating…..
aws:ec2:InternetGateway lambdas-dev-gw created (1s)
aws:ec2:Subnet lambdas-dev-subnet created (1s)
aws:ec2:RouteTable lambdas-dev-rt1 creating (0s)
@ updating….
aws:ec2:VpcEndpoint lambdas-dev-sm-endpoint creating (0s)
@ updating….
aws:ec2:SecurityGroup lambdas-dev-sg-web created (3s)
aws:ec2:RouteTable lambdas-dev-rt1 created (2s)
@ updating….
aws:lambda:Function lambdas-dev-hw-py-helloworld creating (0s)
aws:lambda:Function lambdas-dev-pe-py-printenv creating (0s)
aws:ec2:RouteTableAssociation lambdas-dev-rt1a creating (0s)
@ updating…..
aws:ec2:RouteTableAssociation lambdas-dev-rt1a created (1s)
@ updating…………………………………..
aws:ec2:VpcEndpoint lambdas-dev-sm-endpoint created (42s)
@ updating…………………………………………………………………………………………………………………………………………
aws:lambda:Function lambdas-dev-hw-py-helloworld created (192s)
aws:lambda:FunctionUrl lambdas-dev-hw-py-url creating (0s)
@ updating….
aws:lambda:FunctionUrl lambdas-dev-hw-py-url created (1s)
@ updating….
aws:cloudfront:Distribution lambdas-dev-hw-py-cf creating (0s)
@ updating…….
aws:lambda:Function lambdas-dev-pe-py-printenv created (199s)
@ updating….
aws:lambda:FunctionUrl lambdas-dev-pe-py-url creating (0s)
@ updating….
aws:lambda:FunctionUrl lambdas-dev-pe-py-url created (0.93s)
@ updating……………………………………………………………………………………………………………………………………………………………………………….
aws:cloudfront:Distribution lambdas-dev-hw-py-cf created (201s)
@ updating….
pulumi:pulumi:Stack lambdas-lambdas created (1s)
Resources:
19 created
Duration: 7m2s
VII. Test
Nach Abschluss der Bereitstellung können Sie Ihre Lambda-Funktionen über die AWS Management Console, AWS CLI oder durch programmgesteuerte Aufrufe testen.

Wir werden unsere beiden Lambda-Funktionen über ihre URLs testen. Die URL kann innerhalb des Lambdas selbst gefunden werden.

Die erste gibt einen einfachen Hallo-Welt-Text zurück.

Mit demselben Code haben wir eine CloudFront-Verteilung erstellt, die mit dem Lambda verbunden ist. Wir können also auch von dort aus darauf zugreifen.

Die Ausführung der CF-Domain führt zum gleichen Ergebnis, da die Anfrage an die Lambda-URL weitergeleitet wird.

Das zweite Lambda ist ebenfalls einfach. Aber dieses Mal ist es so konfiguriert, dass es eine Umgebungsvariable liest und sie als Ausgabe ausgibt, anstatt des Hallo-Welt-Textes.

VIII. Aktualisierung des Lambda-Codes
Das Aktualisieren und Bereitstellen des Lambda-Codes ist einfacher, als es klingt.
Öffnen Sie ein beliebiges Lambda-Skript, aktualisieren Sie es, und speichern Sie den Code. Für unser Beispiel ändern wir den Hallo-Welt-Text von "Hello from Lambda!" in "I just made an update!"
import json
def lambda_handler(event, context):
#TODO implement
return {
'statusCode': 200,
'body': json.dumps('I just made an update!')
}
Dann laufen Sie:
pulumi preview
pulumi up --yes --non-interactive
Lambda wird in weniger als 10 Sekunden aktualisiert und die Ausgabe sieht in etwa so aus. Sie können sehen, dass Pulumi Änderungen innerhalb des Lambda-Codes erkennt und die Aktualisierung auslöst.
vladimir.dimitrov@localhost:~/github/PROJECTS/lambda_deploy> pulumi preview
Previewing update (lambdas):
Type Name Plan Info
pulumi:pulumi:Stack lambdas-lambdas
~ └─ aws:lambda:Function lambdas-dev-hw-py-helloworld update [diff: ~code]
Resources:
~ 1 to update
17 unchanged
vladimir.dimitrov@localhost:~/github/PROJECTS/lambda_deploy> pulumi up --yes --non-interactive
Previewing update (lambdas):
pulumi:pulumi:Stack lambdas-lambdas running
@ previewing update….
.
.
.
Resources:
~ 1 updated
17 unchanged
Duration: 9s

IX. Schlussfolgerung
Herzlichen Glückwunsch! Sie haben erfolgreich mehrere AWS Lambda-Funktionen mit Pulumi bereitgestellt. Sie können diese Einrichtung erweitern, um zusätzliche Ressourcen einzubeziehen, Ereignisauslöser zu konfigurieren und Ihre gesamte Infrastruktur als Code zu verwalten. Weitere Anpassungen und erweiterte Funktionen finden Sie in der Pulumi-Dokumentation.

