Serverless Framework und AWS: Tipps und Plugins aus der Praxis
June 4, 2018Das Serverless Framework erfreut sich großer Beliebtheit und kommt auch bei uns und unseren Kunden häufig zum Einsatz. Nicht zuletzt wegen des großen Plugin Ökosystems und der guten AWS Unterstützung.
In diesem Artikel wollen wir euch ein paar Tipps sowie Plugins vorstellen, die wir im bisherigen Praxiseinsatz als sehr hilfreich empfunden haben.
IAM Variablen in der serverless.yml
Ab und zu kann es vorkommen, dass ihr IAM Rollen/Policies in der serverless.yml
definieren müsst, die spezielle Bedingungen haben, z. B. mit IAM Variablen. Diese sehen z. B. so aus: ${aws:username}
- genau das ist aber die Variablen Syntax in der serverless.yml
!
Dafür gibt es folgenden Workaround: Ihr definiert die Variablensyntax in der serverless.yml
um:
provider:
...
variableSyntax: "\\${{([ ~:a-zA-Z0-9._\\'\",\\-\\/\\(\\)]+?)}}"
Jetzt ist die ${blah}
Syntax für IAM “frei” und ihr könnt serverless.yml
Variablen mit ${{myvar}}
referenzieren.
Sprechende Domains für AWS API Gateways
Aus der Tüte fallen bei AWS API Gateways keine schoenen Domainnamen, sondern sowas wie tkuvma5x55.execute-api.us-east-1.amazonaws.com
. Allerdings bietet AWS alle Bausteine, um auch sprechende Domains, die ggf. bestehenden Namenschemata wie <service>.<enviroment>.mycompany.com
entsprechen. Dafür braucht es zumindest die Dienste ACM, Route53, und das API Gateway Domain Mapping.
Der serverless-domain-manager vereinfacht den Prozess. Bis auf die Einrichtung des TLS Zertifikats in ACM und die Route53 Zone nimmt er euch die Arbeit ab.
Lambda Python Projekte ohne Probleme paketieren und deployen
Falls es Probleme beim Paketieren von Python Projekten gibt, weil z. B. Python Versionen nicht übereinstimmen oder irgendetwas mit pip
nicht geht, dann hilft das serverless-python-requirements Plugin. Es nimmt euch das Handling von requirements.txt
ab und kann auch isoliert in einer Docker Umgebung paketieren (mit dockerizePip
). Das funktioniert übrigens auch in CodeBuild, dem Build Service von AWS, denn dieser unterstützt ‘Docker in Docker’.
Harte Kodierung von AWS Account Ids oder Region verhindern
Des öfteren muss man bestehende Resourcen referenzieren, und dafür z. B. deren ARN synthetisieren. Beispiel könnte eine Referenz auf einen bestehenden Kinesis Stream sein, der außerhalb der serverless.yml
angelegt wurde:
functions:
hello:
handler: handler.hello
events:
- stream:
- arn: arn:aws:kinesis:eu-central-3:1234567012:stream/mystream
type: kinesis
Hier sind jetzt die Region eu-central-3
und die AWS Account ID 1234567012
hard kodiert, was die Wiederverwendbarkeit der serverless.yml
zunichte macht.
Abhilfe schafft das serverless-pseudo-parameters Plugin, was er erlaubt, die sogenannten CloudFormation Pseudo Parameter innerhalb der serverless.yml
zu verwenden.
Das Beispiel von oben können wir nun so umschreiben:
plugins:
- serverless-pseudo-parameters
functions:
compute:
handler: handler.compute
events:
- stream:
- arn: arn:aws:kinesis:#{AWS::Region}:#{AWS::AccountId}:stream/mystream
type: kinesis
Lambda Kaltstarts vorbeugen
Eines der aktuell größten Herausforderungen für Serverless Anwendungen scheinen derzeit Kaltstarts zu sein, zumindest bei synchronen Request/Response Aufrufen, wie z. B. über das API Gateway. Das bedeutet, dass beim Aufruf einer Lambdafunktion diese erst intern auf der AWS Infrastruktur hochgefahren werden muss - wenn diese einige Zeit nicht aufgerufen wurde - was einige 100ms bis zu einigen Sekunden dauern kann. Gerade bei Services, die nur sporadisch aufgerufen werden, kann dies also zu signifikanter Latenz oder sogar zu Timeouts bei aggressiv eingestellten Aufrufern führen.
Gerade für Sprachen mit “Class Loaders” (z. B. JVM oder .NET basierte Sprachen) schlagen Kaltstarts besonders zu. Hierfür gibt es das Warmup Plugin, welches dafür sorgt, dass Lambda Funktionen “vorgewärmt” werden. Das ist sicher nur ein Workaround, aber erkauft uns Zeit, bis die Cloud Provider hier besser werden. Solange hilft es auch, den Lambdafunktionen mehr RAM zu geben.
API Gateway Logging und Metriken programmatisch aktivieren
Das AWS API Gateway kann Metriken und Logs an CloudWatch senden, allerdings gibt es bisher noch keine native Funktion im Serverless Framework, um dies programmatisch zu lösen.
Ein Workaround geht über “Custom Resources”, wo wir “low level” an die CloudFormation Resourcen herankommen, die das Serverless Framework verwaltet. Weiterhin braucht ihr das serverless-plugin-bind-deployment-id
Plugin.
plugins:
- serverless-plugin-bind-deployment-id
resources:
Resources:
__deployment__:
Properties:
Description: This is my deployment
ApiGatewayStage:
Type: AWS::ApiGateway::Stage
Properties:
DeploymentId:
Ref: __deployment__
RestApiId: !
Ref: ApiGatewayRestApi
StageName: dev
MethodSettings:
- HttpMethod: "*"
ResourcePath: "/*"
MetricsEnabled: true
LoggingLevel: INFO
DataTraceEnabled: true
In diesem Beispiel setzen wir das Log Level auf INFO
und aktivieren CloudWatch Metriken per MetricsEnabled: true
.
(Quelle: Dieser GitHub Issue)
Fazit
In diesem Artikel haben wir in der Praxis wiederkehrende Probleme und Lösungen oder zumindest Workarounds im Zusammenhang mit dem Serverless Framework für euch gesammelt.
Ihr habt weitere schöne Plugins oder Tricks? Schreibt sie gerne in die Kommentare!