Comment automatiser les déploiements Safe Lambda à partir de Git
Lambda dispose d'un éditeur de texte Web que vous avez probablement utilisé auparavant pour écrire vos fonctions. C'est génial pour les débutants qui apprennent la plate-forme, mais ce n'est pas la meilleure façon de gérer les mises à jour. Voici comment suivre vos fonctions Lambda sur Git.
Sommaire
Fonctionnement de CI / CD pour Lambda
Au lieu d'utiliser l'éditeur manuel, vous devez développer vos fonctions localement, valider et pousser les modifications dans un référentiel Git, et faire en sorte que CodePipeline gère la construction et le déploiement pour vous.
CodePipeline s'exécute automatiquement chaque fois qu'il détecte des modifications dans votre contrôle de code source et envoie les modifications à CodeBuild (ou Jenkins) pour la construction. Cette étape est facultative et vous ne l’utiliserez peut-être pas pour Lambda, mais si vous utilisez quelque chose comme TypeScript, vous aurez besoin de cette étape. Après la construction, les modifications sont poussées vers CodeDeploy, qui gère le déploiement.
CodeDeploy mettra automatiquement à jour vos fonctions Lambda et lancera une nouvelle version. Pour rendre le processus de déploiement plus fluide, il peut déplacer progressivement le trafic à l'aide d'un alias, jusqu'à ce que 100% du trafic soit dirigé vers la nouvelle fonction.
Pour gérer le déploiement réel, CodeDeploy utilise le modèle d'application sans serveur (SAM) d'AWS. SAM est une extension de CloudFormation, un service d'infrastructure en tant que code. Il s'agit essentiellement d'un modèle de langage de sérialisation des données (YAML) lisible par l'homme qui est utilisé pour gérer toute la configuration associée au déploiement des fonctions Lambda et leurs prérequis, et est un élément essentiel pour pouvoir déployer en utilisant uniquement du code.
Configuration du contrôle de source
Cette étape est assez simple. Vous souhaiterez créer un nouveau répertoire de projet pour contenir tout votre code et l'initialiser avec Git. Le modèle SAM ira à la racine de ce répertoire, nommé template.yml
. Chaque fonction ira dans son propre dossier, la racine étant index.js pour chacune. Cela sépare clairement tout et facilite la gestion
ProjectDirectory |--template.yml |--Function | |--index.js |--AnotherFunction |--index.js
CodePipeline prend en charge Github et BitBucket pour le contrôle des sources. Si vous utilisez l'un ou l'autre de ces éléments, il vous suffit de créer une nouvelle branche pour les déploiements (ou simplement d'utiliser master, si cela vous convient). Si vous utilisez un autre service, vous souhaiterez utiliser le propre contrôle de code CodeCommit d'AWS comme référentiel secondaire, en y apportant des modifications chaque fois que vous souhaitez effectuer des mises à jour.
Écriture d'un modèle SAM
Cette étape sera la plus compliquée et la plus spécifique à votre fonction et à ses exigences. Vous devrez créer un modèle SAM qui configurera votre fonction Lambda et toutes ses ressources requises.
Un modèle de base ressemble à ceci:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: An AWS Serverless Specification template describing your function Resources: HelloWorld: Type: AWS::Serverless::Function Properties: Handler: HelloWorld/index.handler Runtime: nodejs8.10
Cela enregistre une ressource, une fonction Lambda, qui s'exécute sur NodeJS, et a son gestionnaire dans HelloWorld/index.js
.
Vous pouvez également déployer d'autres ressources à partir du modèle SAM. Par exemple, pour donner à API Gateway l'autorisation d'invoquer votre fonction et configurer votre fonction pour qu'elle s'exécute sur un chemin API spécifique, vous devez ajouter ce qui suit:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: An AWS Serverless Specification template describing your function Resources: HelloWorld: Type: AWS::Serverless::Function Properties: Handler: HelloWorld/index.handler Runtime: nodejs8.10 Events: HelloWorldApi: Type: Api Properties: Path: /helloworld Method: GET HelloWorldPermission: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunction FunctionName: Fn::GetAtt: - HelloWorld - Arn Principal: apigateway.amazonaws.com SourceArn: Fn::Sub: arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:*/*/*/*
Vous aurez certainement besoin d'utilisations plus spécifiques que celles qui peuvent être répertoriées ici. Pour plus d'informations sur SAM, vous pouvez lire notre guide d'utilisation, les guides du développeur AWS ou le schéma complet sur Github.
Une fois que vous avez un modèle de travail, vous pouvez tester le déploiement en installant la CLI SAM:
pip install aws-sam-cli
Ensuite, vous emballerez votre projet et stockerez les artefacts dans un compartiment S3:
sam package --template-file template.yml --output-template-file package.yml --s3-bucket bucket-name
Et vous exécuterez manuellement le déploiement:
sam deploy --template-file package.yml --stack-name sam-hello-world --capabilities CAPABILITY_IAM
Si tout fonctionnait correctement, vous devriez voir une nouvelle pile CloudFormation et une application dans Lambda avec vos fonctions.
Empaquetage et déploiement du projet avec CodePipeline
Cette étape n'est pas facultative, même si vous ne travaillez pas avec un langage compilé. En utilisant le modèle SAM, CodeBuild sera utilisé ici pour gérer l'empaquetage du projet dans quelque chose qui peut être déployé avec CodeDeploy très facilement. Facultativement, vous pouvez exécuter d'autres commandes avant l'empaquetage, telles que npm run build
et npm install
.
Tout d'abord, vous aurez besoin d'un rôle d'exécution capable de gérer les mises à jour de CloudFormation. Ouvrez la console de gestion IAM pour ajouter un nouveau rôle. Sélectionnez "CloudFormation" comme ressource qui utilisera ce rôle, puis attachez le "AWSLambdaExecute
politique d'autorisation.
Enregistrez le rôle, ouvrez-le et joignez la stratégie en ligne suivante:
{ "Statement": ( { "Action": ( "apigateway:*", "codedeploy:*", "lambda:*", "cloudformation:CreateChangeSet", "iam:GetRole", "iam:CreateRole", "iam:DeleteRole", "iam:PutRolePolicy", "iam:AttachRolePolicy", "iam:DeleteRolePolicy", "iam:DetachRolePolicy", "iam:PassRole", "s3:GetObject", "s3:GetObjectVersion", "s3:GetBucketVersioning" ), "Resource": "*", "Effect": "Allow" } ), "Version": "2012-10-17" }
Créez un nouveau pipeline à partir de la console CodePipeline. Choisissez les paramètres par défaut de création d'un nouveau rôle de service. Ce sera configuré automatiquement.
Pour l'étape de contrôle de source, choisissez le type de contrôle de source, le référentiel et la branche de publication.
Pour l'étape de génération, vous souhaiterez créer un nouveau projet dans CodeBuild. La configuration par défaut est correcte, choisissez simplement Amazon Linux 2 comme système d'exploitation de build, et sélectionnez le runtime standard et l'image standard.
La principale chose dont vous aurez besoin pour codePipeline est votre buildspec.yml
, placé à la racine du répertoire de votre projet. Cela configure CodeBuild avec les commandes dont il a besoin pour s'exécuter. La configuration suivante est un exemple qui installe TypeScript, tous les packages NPM, s'exécute npm run build
, puis regroupe tout pour CloudFormation.
version: 0.2 phases: install: runtime-versions: nodejs: 10 commands: - npm install -g typescript build: commands: - echo Build started on `date` - npm install time - npm run build - export BUCKET=typescript-lambda - aws cloudformation package --template-file template.yml --s3-bucket $BUCKET --output-template-file outputtemplate.yml artifacts: type: zip files: - template.yml - outputtemplate.yml
Vous devrez probablement le modifier en fonction de votre projet.
Une fois cela fait, vous pouvez configurer la dernière étape. Plutôt que d'utiliser CodeDeploy, nous utiliserons CloudFormation pour mettre à jour les choses directement, car tout le package s'est produit dans la phase de construction de toute façon. Choisissez «CloudFormation» comme fournisseur de déploiement et définissez le mode d'action sur «Créer ou remplacer un ensemble de modifications». Saisissez un nouveau nom et modifiez le nom du jeu.
Pour le modèle, sélectionnez «BuildArtifact» et entrez outputtemplate.yml
de l'étape précédente. Ajoutez «Capability IAM» aux capacités et sélectionnez le rôle de service que vous avez créé manuellement précédemment.
Cliquez sur "Créer" et votre pipeline devrait fonctionner sans erreur. Cependant, l'étape CloudFormation fait un ensemble de changement, qui est comme un aperçu des modifications. Pour déployer réellement les modifications, nous devons exécuter l'ensemble de modifications.
Cliquez sur "Modifier" sur votre pipeline créé. Sous «Déployer», cliquez sur «Modifier», puis sur «Ajouter un groupe d'actions» après l'action déjà créée. Si vous créez la nouvelle action avant celle-ci, cela ne fonctionnera pas.
Choisissez «CloudFormation» comme fournisseur. Sélectionnez «BuildArtifact» comme artefact d'entrée. Pour le mode d'action et le nom de l'ensemble de modifications, entrez les mêmes valeurs que vous avez créées pour la première action de déploiement.
Cliquez sur "Enregistrer" et vous serez ramené à l'écran principal du pipeline. Cliquez sur «Release Change» pour réexécuter manuellement le pipeline. Il devrait maintenant se terminer et les modifications devraient être visibles dans la console Lambda.
Si vous obtenez des erreurs, il est assez facile de les retrouver, car vous pouvez cliquer sur "Plus de détails" à côté du message d'erreur dans CodePipeline. Il s'agit probablement d'une génération ayant échoué, d'un modèle SAM incomplet ou d'autorisations insuffisantes pour CodeBuild ou CloudFormation.
Si vous validez des modifications de votre contrôle de code source, il devrait être détecté par CodePipeline et recommencer tout ce processus.