Archives de
Mois : novembre 2020

Que sont les « Cloudformation Custom Resources » et comment les utiliser

Que sont les « Cloudformation Custom Resources » et comment les utiliser

AWS Cloudformation, qu’est-ce que c’est ?

Cloudformation est un outil très important dans la vie de tous les jours des personnes travaillant sur le cloud AWS. Il permet d’implémenter toutes les ressources AWS d’une manière rapide et efficace. C’est un très bon exemple de IaC : Infrastructure as Code.

Cloudformation facilite donc les déploiements, la maintenance et les évolutions d’environnement entier, mais permet aussi de templatiser ces infrastructures.

Les différents services du catalogue AWS évoluent de manière continue, et totalement indépendante. On peut comparer la plateforme AWS à une immense architecture en micro-services.

Il se peut donc que Cloudformation ne soit pas à jour par rapport aux nouveautés des services. Une fonctionnalité ou un paramètre spécifique peut ne pas être implémenté dans Cloudformation, cela rendra inutilisable la stack Cloudformation pour la ressource en question.

La suite de cet article a pour but de montrer comment contourner cette limitation, et construire toutes les ressources AWS comme on le souhaite.

Les « Custom Resources »

Heureusement, les Custom Resources sont là pour nous aider. Elles permettent de provisionner les ressources AWS à chaque fois qu’une stack Cloudformation est créée, mise à jour ou supprimée.

Alors, comment ça marche ?

De manière très simple, sur un changement, Cloudformation appelle une fonction Lambda avec un event spécifique, et attendra un retour de cette fonction de manière à définir si la ressource a été correctement modifiée, ou non.

Nous remarquons ici la possibilité d’utiliser l’un des SDK proposés par AWS, par le biais de la fonction lambda ( Python, Java, Node.js, … ).

Voici le template de l’event envoyé par Cloudformation à la Lambda :

NB : Le champ ResourceProperties permet de personnaliser les paramètres de la fonction

On remarque aussi que l’event contient une URL qui correspond à l’endpoint qu’il faudra appeler quand le travail de la lambda est terminé. L’endpoint attend un statut des actions menées.

Voici un exemple de ce qu’attends l’URL :

Custom Resources : use case & implémentation

Comme souvent, lorsque je travaille pour un client, je commence par construire la solution « à la main » via la console AWS, ceci me permet d’avoir rapidement une solution exploitable. Une fois cette étape terminée, je construis l’IaC via Cloudformation, afin de fournir des templates qui seront utilsés pour construire les environnements de travail jusqu’à la production.

Travaillant sur un projet AWS AppStream, j’ai eu la surprise de voir qu’il était impossible à ce jour de joindre un rôle IAM ni à l’image builder, ni à la flotte en utilisant les ressources natives Cloudformation.

J’ai pris la décision d’utiliser le SDK et ainsi développer mes propres Customs Resources.

Construire la fonction Lambda

Commençons par construire la fonction Lambda permettant de créer et détruire les ressources.

Nous retrouvons les paramètres personnalisés depuis l’event :

Ensuite, on vérifie dans l’event quelle est l’action à  effectuer :

  • Création :

  • Destruction : Dans cet exemple, la flotte doit être stoppée avant d’être supprimée

Comme expliqué, la Custom Resource attend un statut que je remplacerai par un code retour.

  • Ci-dessous le code permettant de faire cet appel :

Construire le template Cloudformation

Ensuite, nous passons à la création du template Coudformation. On peut voir dans cet exemple que l’Image Builder et la flotte sont une seule et même ressource, de type : Custom::IBAndFleetBuilder, et que le champ ServiceToken correspond  à l’ARN de la Lamda.

Conclusion

Grâce aux Custom Resources, j’ai pu livrer au client un template Cloudformation opérationnel, qu’il peut utiliser pour déployer automatiquement toutes ses ressources AppStream en un clic, mais aussi pour les supprimer lorsqu’il le souhaite.

Il est important de noter que la stack Cloudformation fait un appel à la Custom Resource lorsque celle-ci est mise à jour, ainsi pour éviter ce comportement, nous pourrons donc implémenter une fonction spécifique dans la Lambda qui sera en charge d’effectuer cette partie.

Références : 

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html