Deployments mit serverless.com, AWS CDK oder AWS SAM?
January 30, 2020Damit Infrastruktur sinnvoll verwaltet werden kann und zuverlässig reproduzierbar bleibt, empfehlen wir immer den Einsatz von Infrastructure as Code. Für Infrastruktur mit AWS gibt es hierzu einige Tools zur Auswahl: Das serverless.com Framework, das AWS Cloud Development Kit oder das AWS Serverless Application Model.
Neben diesen drei gibt es natürlich noch eine Vielzahl an Alternativen. In unserer täglichen Arbeit haben sich die genannten als zuverlässige Werkzeuge erwiesen, daher möchten wir den jeweiligen Einsatz an Hand einer kleiner Infrastruktur vorstellen.
Infrastruktur
Als Basis für die Infrastruktur dient eine AWS Lambda Funktion und eine Amazon DynamoDB Tabelle. Die Lambda Funktion soll Zugriff auf die DynamoDB Tabelle erhalten und Einträge auslesen können. Der rudimentäre Quellcode der Lambda Funktion sieht wie folgt aus und ist als ./src/handler.js
im Projektordner gespeichert:
// ./src/handler.js
const AWS = require("aws-sdk");
const client = new AWS.DynamoDB({ apiVersion: "2012-08-10" });
exports.run = async event => {
const params = {
TableName: process.env.TABLE_NAME,
Key: {
key: { S: event.key }
}
};
return client.getItem(params).promise();
};
Wer bereits Erfahrung mit dem Einsatz von AWS Lambda und Amazon DynamoDB hat, erkennt dass die DynamoDB Tabelle einen Primärschlüssel mit dem Namen key
besitzt und der Name der DynamoDB Tabelle an die AWS Lambda Funktion mittels der Umgebungsvariable TABLE_NAME
übergeben wird. Diese grundlegende Architektur ist für alle drei Beispiele identisch.
Es geht in den kommenden Absätzen nun darum wie man die notwendige Infrastruktur mit dem serverless.com Framework, dem AWS Cloud Development Kit und AWS Serverless Application Model abbildet.
Beispiele
Alle Beispiele sind natürlich auf GitHub zu finden und können ausprobiert, heruntergeladen, und weiterverwendet werden.
- Deployment mit dem serverless.com Framework
- Deployment mit dem AWS Serverless Application Model
- Deployment mit dem AWS Cloud Development Kit
Nachfolgend werden die interessanten Eigenheiten jeder Implementierung kurz vorgestellt.
serverless.com Framework
Das Framework von serverless.com lässt sich über eine Datei im YAML-Format konfigurieren. Standardmäßig heißt die Datei serverless.yml
und liegt direkt im Hauptverzeichnis eines Projekts. Die Konfigurationsdatei beinhaltet einen frei wählbaren Namen für das Projekt und den zu erstellenden CloudFormation Stack, ebenso wie eine Vielzahl an grundlegenden Werten für das Deployment. So nutzen wir natürlich den AWS provider
, konfigurieren die AWS Lambda runtime
mit node12.x
und definieren eine AWS Lambda Funktion ExampleFunction
.
Im Abschnitt resources
kann die bekannte CloudFormation Funktionalität genutzt werden um weitere Bauteile der Infrastruktur in AWS zu konfiguriere. Die benötigte DynamoDB Tabelle wird hier als ExampleTable
angelegt:
# ./serverless.yaml
service:
name: iac-example-serverless
provider:
name: aws
runtime: nodejs12.x
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:GetItem
Resource: !GetAtt ExampleTable.Arn
functions:
ExampleFunction:
handler: src/handler.run
environment:
TABLE_NAME: !Ref ExampleTable
resources:
Resources:
ExampleTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: key
AttributeType: S
KeySchema:
- AttributeName: key
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
Die interessanten und wichtigen Verknüpfungen der beiden AWS Ressourcen geschehen bei der Definition der Umgebungsvariablen für die AWS Lambda Funktion und bei der Konfiguration der erlaubten Zugriffsrechte, der sogenannten IAM Role:
# Referenz auf die DynamoDB Tabelle für die AWS Lambda Umgebungsvariable
environment:
TABLE_NAME: !Ref ExampleTable
# Referenz auf die DynamoDB Tabelle für die AWS Lambda Zugriffsrechte
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:GetItem
Resource: !GetAtt ExampleTable.Arn
Diese einfache Konfiguration der Infrastruktur kann nun mit dem Kommandozeilenprogramm des serverless.com Frameworks deployt werden:
$ > serverless deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service iac-example-serverless.zip file to S3 (87.06 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
Serverless: Stack update finished...
In der AWS Management Console existiert nun eine neue AWS Lambda Funktion, eine DynamoDB Tabelle und der konfigurierte Lesezugriff der AWS Lambda Funktion auf die DynamoDB Tabelle. Zum sauberen Entfernen aller Bestandteile kann der Befehl serverless remove
genutzt werden. Da alle AWS Ressourcen innerhalb eines CloudFormation Stacks erstellt wurden, lassen sie sich durch das einfache Löschen des CloudFormation Stacks wieder entfernen. Das Kommandozeilenprogramm macht mit dem genannten Befehl genau dies.
AWS Serverless Application Model
Das Serverless Application Model (kurz: AWS SAM) ist eine von AWS angebotene Erweiterung für CloudFormation inklusive einem zusätzlichen Kommandozeilenprogramms für die typischen Arbeitsschritte. Mit AWS CloudFormation kann nahezu jegliche AWS Infrastruktur mit einer Konfigurationsdatei im YAML- oder JSON-Format beschrieben und erstellt werden.
Für das vorhandene Beispiel, bestehend aus einer AWS Lambda Funktion und einer DynamoDB Tabelle, sieht eine YAML-Datei mit dem AWS Serverless Application Model wie folgt aus:
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Resources:
ExampleFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handler.run
Runtime: nodejs12.x
Policies:
- DynamoDBReadPolicy:
TableName: !Ref ExampleTable
Environment:
Variables:
TABLE_NAME: !Ref ExampleTable
ExampleTable:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: key
Type: String
Neben dem speziellen CloudFormation Typ AWS::Serverless::Function
für das Anlegen einer AWS Lambda Funktion bietet das AWS Serverless Application Model mit AWS::Serverless::SimpleTable
ebenfalls eine vereinfachte Variante zum Anlegen einer DynamoDB Tabelle mit CloudFormation an.
Identisch zum Einsatz des serverless.com Frameworks kann einfach eine Referenz auf den Namen der DynamoDB Tabelle als Umgebungsvariable an die Lambda Funktion übergeben werden:
# Referenz auf die DynamoDB Tabelle für die AWS Lambda Umgebungsvariable
Environment:
Variables:
TABLE_NAME: !Ref ExampleTable
Damit die Verwaltung von Zugriffsrechten möglichst einfach abgebildet werden kann, bietet das AWS Serverless Application Model sogenannte Policy Templates mit den gängigsten Einsatzzwecken. Damit die AWS Lambda Funktion auf die DynamoDB Tabelle zugreifen darf, enthält DynamoDBReadPolicy
die notwendige Konfiguration.
# Referenz auf die DynamoDB Tabelle für die AWS Lambda Zugriffsrechte
Policies:
- DynamoDBReadPolicy:
TableName: !Ref ExampleTable
Die Konfiguration wird als template.yml
im Hauptverzeichnis des Projekts abgelegt und kann danach mit dem Kommandozeilenprogramm des AWS Serverless Application Model deployt werden:
# Deployment mit AWS Serverless Application Model
$ > sam deploy --guided
Initiating deployment
=====================
Uploading to iac-example-sam/193ed86290516b0d78a51d78b286b401 23105227 / 23105227.0 (100.00%)
Uploading to iac-example-sam/ab516db1052bf0b95fb4a6653874e5d5.template 745 / 745.0 (100.00%)
Successfully created/updated stack - iac-example-sam in us-east-1
Anders als das serverless.com Framework bietet das Kommandozeilenprogramm des AWS Serverless Application Model jedoch keinen Befehl um die Infrastruktur aus dem AWS Account wieder zu entfernen. Dies muss über die AWS Management Console geschehen; da aber alle Bestandteile in einem CloudFormation Stack angelegt werden, können sie durch das Entfernen des CloudFormation Stacks gelöscht werden. Neben dem Löschen über die Management Console kann ein CloudFormation Stack natürlich auch über das AWS Kommandozeilprogramm mit dem Befehl aws cloudformation delete-stack
gelöscht werden.
AWS Cloud Development Kit
Das AWS Cloud Development Kit ist die jüngste Variante von AWS um die Konfiguration von Infrastruktur einfach zu gestalten. Anders als mit dem serverless.com Framework und AWS Serverless Application Model wird mit dem AWS Cloud Development Kit die Infrastruktur nicht beschreiben, sondern programmiert. Aktuell wird das AWS CDK in den Sprachen TypeScript, JavaScript, Python, Java, und C#/.Net angeboten.
Da die anfangs beschriebene AWS Lambda Funktion in Node.js bzw. JavaScript erstellt wurde, bietet sich für dieses Beispiel auch die Verwendung des AWS CDK in JavaScript bzw. TypeScript an:
// ./infrastructure.ts
import * as Lambda from "@aws-cdk/aws-lambda";
import * as DynamoDB from "@aws-cdk/aws-dynamodb";
import * as cdk from "@aws-cdk/core";
import * as path from "path";
class ExampleStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const exampleTable = new DynamoDB.Table(this, "ExampleTable", {
partitionKey: { name: "key", type: DynamoDB.AttributeType.STRING }
});
const exampleFunction = new Lambda.Function(this, "ExampleFunction", {
runtime: Lambda.Runtime.NODEJS_12_X,
code: Lambda.Code.fromAsset(path.resolve(__dirname, "src")),
handler: "handler.run",
environment: {
TABLE_NAME: exampleTable.tableName
}
});
exampleTable.grantReadData(exampleFunction);
}
}
const app = new cdk.App();
new ExampleStack(app, "ExampleStack", { env: { region: "us-east-1" } });
app.synth();
Damit dem AWS Cloud Development Kit alle notwendigen Abhängigkeiten zur Verfügung stehen um den CloudFormation Stack zu erstellen, muss einmalig für die Verwendung des CDK ein bootstrap
Befehl für die jeweilige AWS Region ausgeführt werden:
# Das AWS CDK für die Region us-east-1 konfigurieren
$ > cdk bootstrap --region us-east-1
Danach kann nun wie gewohnt ein Kommandozeilenbefehl genutzt werden um das Deployment der Infrastruktur in AWS zu starten.
# Deployment mit AWS Cloud Development Kit
$ > cdk deploy
ExampleStack: deploying...
Updated: asset.3e5f73c2beb802451ef3bd69a62d0982189da43d8f8537d07ae0cfc20071e44e (zip)
✅ ExampleStack
Stack ARN: arn:aws:cloudformation:us-east-1:420048798477:stack/ExampleStack/b69c1d60-435f-11ea-8522-0a200f00c284
✨ Done in 137.97s.
Wie auch bei dem serverless.com Framework kann mit dem AWS CDK eine erstellte Infrastruktur einfach mittels dem Kommandozeilenprogramm wieder entfernt werden. Ein cdk delete
entfernt alle angelegten Bausteine aus AWS wieder rückstandslos.
Fazit
Es gibt bei der Auswahl des Werkzeugs für die Verwaltung von Infrastruktur auf AWS kein richtig oder falsch. Der Einsatz des serverless.com Frameworks klingt für viele Kunden interessant, da man die Basisfunktionalität mit Plugins erweitern kann und neben AWS auch andere Cloud-Anbieter unterstützt werden. Das Framework wird jedoch von einem Drittanbieter gepflegt, dies kann Vor- und Nachteile bringen.
Sowohl das Cloud Development Kit wie auch das Serverless Application Model stammen direkt von AWS. Eine dauerhafte Weiterentwicklung, Support und auch Kompatibilität sind somit gewährleistet. Der Einsatz von AWS-eigenen Werkzeugen kann sich lohnen um einen tieferen Einblick in die Konfiguration und Verzahnung der Komponenten bei AWS zu erlangen. Ebenfalls wird kein Aufwand betrieben um zusätzlich zur Expertise bzgl. AWS auch noch ein Werkzeug eines Drittanbieters erlernen zu müssen.