Introduction
Cet outil offert par AWS permet de créer des lambdas facilement et de tester le tout localement.
Ce tutoriel ne va pas en détail dans l’implémentation, je prend pour acquis que vous avez de bonne connaissance dans l’environnement AWS, docker et Linux/MacOS/Windows
Installation
Je vous recommande de suivre la documentation officielle, disponible ici : https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install-windows.html
- Avoir un compte AWS
- Installer / Configurer le AWS CLI
- Installer Docker
- Installer le SAM CLI
Usage
Pour cet article, je vais utiliser Windows 10
Normalement j’utilise Mac OS, par contre c’est très similaire.
Donc pour le terminal, je vais utiliser PowerShell
Pour vous assurer que le tout est bien installé,
sam --version
Pour une démo / tutoriel avec du code offert par AWS : https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started-hello-world.html
Démo
Je n’ai malheureusement pas d’exemple concret à partager pour le moment. Voir les sources plus bas pour des exemples disponibles sur Github.
Voici ma structure:
C’est simplifié…
backend/
lambda1/
src/
actions/
get.js
post.js
index.js
test/
feature1.spec.js
package.json
infrastructure/
application.yaml
db.yaml
storage.yaml
infra.yaml
deploy-app.sh
start-api.sh
layers/
layer1/
nodejs/
package.json
package.sh
utils/
ci.js
frontend/
index.html
package.json
Le fichier application.yaml
contient la définition du API Gateway, des lambdas et de la layer.
Tout doit être dans le même fichier, car pour utiliser un seul API Gateway nous devons utiliser cette stratégie. De plus, la structure Monorepo facilite cette implémentation. Pour plus de détails / spécifications, demandez-moi dans les commentaires, ça va me faire plaisir de répondre
Puis les autres YAML contiennent la définition pour la base de données, la configuration du S3, et l’infrastructure (IAM, S3, et autres)
Ensuite le répertoire backend/ contient chaque lambda / service de l’application, le fichier index.js
recoit la requête et chaque méthode est définie dans un fichier spécifique dans le répertoire src/actions/
La layer doit avoir cette structure (nodejs/
) pour fonctionner. Les modules qui sont partagés peuvent facilement être ajouté dans la layer. Ou les dépendences qui ont une grande taille.
Le zip pour importer la lambda doit faire maximum 50MB et une fois extrait, la taille doit être maximum 250MB (vérifiez la documentation officielle, au cas où ça change, https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html)
Tester l’application localement
Structure simplifié du application.yaml
Ne pas copier/coller le yaml ci-dessous, il manque des informations ! C’est seulement pour donner une idée
Le CodeUri
est le répertoire contenant le code source de la lambda
AWSApiGateway:
Type: AWS::Serverless::Api
Properties:
Name: !Ref ApiGatewayName
StageName: !Ref ApiGatewayStageName
EndpointConfiguration:
Type: !Ref APIEndpointType
TracingEnabled: !Ref APITracing
Cors:
AllowMethods: !Ref CorsMethods
AllowHeaders: !Ref CorsHeaders
AllowOrigin: !Ref CorsOrigin
MaxAge: !Ref CorsMaxAge
AllowCredentials: !Ref CorsAllowCredentials
Auth:
Authorizers:
CognitoAuthorizer:
UserPoolArn: "ARN..."
InvokeRole: CALLER_CREDENTIALS
Models:
User:
type: object
required:
- username
properties:
username:
type: string
refreshToken:
type: string
password:
type: string
name:
type: string
AuthLambdaFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: auth-aws-auth
CodeUri: ../backend/authentication/aws-auth
Description: Authenticate the user using Cognito User Pool.
Environment:
Variables:
COGNITO_POOL_ID: !Ref CognitoPoolId
IDENTITY_POOL_ID: !Ref IdentityPoolId
CLIENT_ID: !Ref CognitoClientId
Events:
Api:
Type: Api
Properties:
Path: /auth
Method: POST
RestApiId: !Ref AWSApiGateway
RequestModel:
Model: User
Required: true
Policies:
- AWSLambdaBasicExecutionRole
- !Sub arn:aws:iam::${AWS::AccountId}:policy/Cognito-user
### Upload image to S3 Bucket
imageUploadLambdaFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: upload-aws-image-upload
CodeUri: ../backend/upload/aws-image-upload
Description: Upload an image to S3 Bucket
Environment:
Variables:
S3_BUCKET_DATA: !Ref S3BucketData
IDENTITY_POOL_ID: !Ref IdentityPoolId
COGNITO_POOL_ID: !Ref CognitoPoolId
Events:
Api:
Type: Api
Properties:
Path: /upload/image
Method: POST
RestApiId: !Ref AWSApiGateway
Auth:
Authorizer: CognitoAuthorizer
RequestParameters:
- method.request.header.Authorization:
Required: true
Policies:
- AWSLambdaBasicExecutionRole
Donc avec une configuration comme ci-dessus,
vous pouvez lancer :
cd infrastructure/
sam build -t application.yaml
Le résultat attendu
...
Build Succeeded
Built Artifacts : .aws-sam\build
Built Template : .aws-sam\build\template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
Lancer le serveur local
sam local start-api --region "ca-central-1" \
--parameter-override \
param1=value1 \
param2=value2
Le résultat attendu
...
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2021-01-17 16:06:00 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
Le premier coup, Docker va télécharger l’image pour faire en sorte que le tout fonctionne.
Par la suite, vous aller être en mesure de tester le code localement tout en utilisant les services AWS qui sont dans le cloud. Les messages vont apparaitre directement sur votre console et donc faciliter le développement.
Il faut garder en tête que quelques fonctionnalités ne sont pas 100% supportées en local. (voir la documentation officielle) J’ai eu plusieurs problèmes avec le API Gateway qui ne répondait pas comme le “vrai”. Ceci reste un excellent outil pour développer localement et plus rapidement.
Le code source est disponible dans le répertoire .aws-sam
, pour appliquer les changements au code sans rebuild, vous pouvez modifier le code dans ce répertoire, les fichiers sont lus à chaque exécution, donc pas besoin de redémarrer le serveur.
IMPORTANT Les modifications effectuées dans
.aws-sam
sont écrasées à chaque build !
Sinon vous devez à chaque fois build et start-api. Ces deux actions deviennent longues quand il y a beaucoup de lambda dans le fichier application.yaml
Conclusion
Voici comment je testes localement mon application avec SAM CLI.
je vais ajouter plus de contenu au fur et à mesure que j’ajoutes de nouvelle fonctionnalitée.
Améliorations (To do)
- Ajouter l’usage de la layer localement, je n’ai pas encore pris le temps d’intégrer cette partie, dès que je fais le tout je vais mettre à jour l’article !
- Ajouter DynamoDB localement avec Docker
Sources
Documentation officielle de AWS pour les lambdas, dynamoDB, SAM CLI, Layer et autres.
Il y a plusieurs exemples sur Github pour la structure,