Publié par
Il y a 2 semaines · 10 minutes · DevOps

Pourquoi ansible n’est pas un bon choix pour créer son infra AWS ?

Ansible

Bien que le titre de cet article soit propice aux trolls et aux débats enflammés, mon but ici est d’expliquer en quoi Ansible a induit une complexité de gestion de l’infrastructure AWS sur mon projet. C’est en quelque sorte une déclinaison opérationnelle de l’article d’Aurélien Maury sur le mariage Ansible & AWS.

Le fonctionnel du projet est assez simple puisqu’il consiste en une refonte d’une chaîne de traitement de Point d’intérêts (POI). Les POI sont acquis chez des partenaires à travers des API REST, subissent des traitements (mapping, normalisation, conversion, réconciliation) et sont mis à disposition dans un moteur de recherche. Concernant la partie infrastructure, le choix s’est porté sur une architecture cloud AWS avec des lambdas pour le code métier, RDS pour le stockage en base de données et Elasticsearch pour la mise à disposition. À ces briques principales s’ajoutent Step Functions, CloudWatch Events et SQS.

À travers ce retour d’expérience, je vous propose de vous exposer les difficultés induites par le choix d’Ansible pour créer l’infrastructure. Ayant utilisé AWS Cloudformation dans une précédente mission, je me permettrai la comparaison pour étayer mon propos.

/!\ Les difficultés rencontrées ont été expérimentées avec la version 2.2 d’Ansible.

Pourquoi Ansible ?

La première question est en effet, pourquoi avoir choisi Ansible pour créer l’infrastructure ? Cette décision n’appartenait pas à l’équipe du projet, mais au service “Industrialisation” du client. Les arguments avancés pour choisir Ansible étaient pragmatiques et concernaient principalement la maîtrise de l’outil par les équipes existantes. À ceci, s’ajoutait une forte envie d’homogénéisation interne pour faciliter l’intervention des OPS sur différents projets. Ansible était déjà utilisé pour la gestion de configuration d’instances AWS et remplissait parfaitement son rôle.

Difficultés rencontrées

Sans tergiverser, passons directement aux difficultés que nous avons dû surmonter pour la création de l’infrastructure AWS.

Suppression des ressources

L’organisation de l’équipe veut que chaque feature soit déployée dans une chaîne de traitement dédiée. Une fois les tests passés et le merge réalisé, les ressources allouées sont détruites. Contrairement à un outil comme CloudFormation qui propose nativement la suppression de toutes les ressources liées à une stack (méthode clouformation.deleteStack), avec Ansible la suppression est à implémenter soi-même.  Sur chaque ressource, il faut variabiliser le “state” pour que sa valeur prenne “absent”. Sur des playbooks conséquents, il en résulte des éléments fantômes restant dans le compte AWS par simple oubli. Nous avons rencontré ce cas sur des security group et des policies IAM.

Vision globale de l’infra

En tant que nouvel arrivant sur un projet cloud, l’un des premiers besoins est d’avoir une vision globale des briques métiers et techniques déployées. Avec des ressources managées via un outil de gestion de configuration, il faut explorer chaque service AWS pour comprendre leurs interdépendances et se forger une vision. Un outil dédié tel que CloudFormation propose quant à lui de regrouper les ressources liées au sein d’une “stack” et offre à travers son IHM une vue centralisée de toutes les stacks utilisées et des détails associés (historiques des modifications, paramètres, sorties, etc.).

Traçabilité des modifications

Ce point rejoint la notion d’historique du précédent item. CloudFormation recense tous les événements qui ont lieu sur une stack. Il est ainsi possible de retracer les évolutions en regardant l’onglet “Events” pour savoir quelles ressources ont été supprimées, ajoutées et modifiées. Quand une configuration incorrecte de l’infrastructure provoque des comportements inattendus sur l’application il est très facile de retrouver l’origine en analysant les événements de la stack pour voir si l’erreur provient d’une mise à jour.

Avec Ansible, la notion de stack n’existe pas. Sur notre projet, l’historique de déploiement et les potentielles erreurs sont portées par Jenkins qui orchestre Ansible. Cela suppose que personne ne lance de playbook hors de Jenkins, ce qui je vous l’accorde, ne doit jamais arriver en production, mais qui est chose courante sur des comptes de développement. De ce fait, quand un comportement suspect se produit en développement il est difficile de retrouver la cause si ce n’est en allant voir les heures de modification de chaque ressource dans la console AWS.

Renommage

En phase de développement, il est courant de tâtonner sur le nommage des ressources. Cependant, Ansible gère très mal ce besoin car la clé d’unicité est le nom. Par exemple, si vous renommez une fonction Lambda vous allez vous retrouver avec deux Lambda : une portant le nouveau nom et une avec l’ancien. Nous avons rencontré le même problème, pour les filles SQS et les Scheduled Events. Sur un compte de développement il est facile de “corriger” en supprimant manuellement les éléments non désirés. Mais une fois en production, il faut sérieusement penser à automatiser le processus en ajoutant un traitement particulier de suppression des ressources ayant les anciens noms.

Dry Run

Quand une modification d’infra doit être effectuée sur un élément critique, il est rassurant de connaître à l’avance les changements qui vont être opérés (modification d’un security group, suppression d’une instance, etc.).

En fournissant l’argument “–check” à la ligne de commande, Ansible propose le “Check Mode”, qui indique les changements qui vont être opérés. D’une part, tous les modules ne le supportent pas et d’autre part, quand l’équipe est amenée à développer ses propres modules pour palier le manque de l’offre (voir point “Complétude de l’offre”), il est impératif de gérer soi-même ce mode au risque de ne pas pouvoir utiliser sereinement l’argument “–check”.

CloudFormation fournit nativement la notion de Change Set qui permet de lister les mutations qui vont se produire. L’équipe bénéficie de cette capacité sans avoir à implémenter quoi que ce soit. Pour se faire, CloudFormation se base sur son état interne pour faire la différence avec le nouveau template fourni.

Gestion du rollback

À l’instar des Change Set, la gestion automatique du rollback dans Ansible est inexistante. Quand une erreur survient au milieu d’un playbook, c’est à vous de traiter le cas. Soit en supprimant les ressources dans le bon ordre, soit en appliquant l’ancienne configuration qu’il aura fallu conserver, soit en ne faisant rien au risque d’avoir un état instable.

CloudFormation propose en standard 3 modes pour gérer les erreurs via l’option “OnFailure” :

  • DO_NOTHING : comportement d’Ansible si le bloc “rescue” n’est pas présent
  • ROLLBACK : revient automatiquement à l’état précédent

  • DELETE : supprime la stack

Complétude de l’offre

La faiblesse de l’offre Ansible concernant l’offre AWS est un gros frein. Si vous souhaitez utiliser les services AWS de façon poussée ou bien quand vous choisissez des services managés récents vous allez au devant de difficultés.

Pour appuyer mon propos, je vais citer trois exemples que l’équipe a rencontrés. Pour rappel, la version d’Ansible est la 2.2 :

  • Après l’annonce du support des variables d’environnement par le service Lambda, nous avons refactoré le code pour utiliser pleinement cette nouvelle capacité. Or, même après plusieurs mois, le module Ansible lambda stable ne gère pas encore les variables d’environnement.
  • Le module rds ne permet pas de spécifier le type de disque pour les bases de données relationnelles (RDS). Le disque par défaut est magnétique (qui au passage est présent uniquement pour assurer la compatibilité descendante). Hors pour les performances, nous avions besoin d’un SSD.

  • Les services Step Functions et Elasticsearch Service n’ont tout simplement pas de module.

Pour palier ces manques, la solution est de patcher l’outil en soumettant des pull request qui, après discussion, si elles sont acceptées, prendront effet dans la version suivante. En attendant, la solution la plus rapide est de se baser sur la CLI AWS. C’est ainsi que notre OPS se voit contraint au sein d’un même rôle de créer une lambda avec le module lambda et deux lignes en dessous de coder une section AWS CLI pour ajouter la permission à Cloudwatch Events (aws lambda add-permission). La cohérence et la lecture du code en souffrent.

Pour les services non supportés (Step Functions, Elasticsearch), le développement d’un rôle Ansible entièrement géré avec AWS CLI est la solution rapide. Cela implique d’écrire une gestion CRUD des ressources pour gérer de façon transparente les mises à jours car les commandes AWS CLI ne sont pas les mêmes en création et en modification.

Tous ces écueils sont inexistants en utilisant CloudFormation. De par son statut officiel, il intègre plus rapidement que les autres solutions les évolutions des services AWS. Pour les cas non couverts, il est possible de l’étendre avec l’ajout de ressources personnalisées. À titre de comparaison, tous les services utilisés dans le projet sont disponibles dans CloudFormation.

Timeout

De par l’architecture distribuée AWS, il arrive que la création d’une ressource mette un peu de temps à se propager. Sa manipulation nécessitera donc un délai de quelques secondes sous peine d’avoir une erreur. Cette gestion des timeouts est à implémenter soi-même pour les modules Ansible ne la gérant pas, et bien entendu dès que la CLI AWS est utilisée. Nous avons rencontré le cas sur l’ajout de policies à un rôle IAM fraîchement créé.

Conclusion

Au final, le code Ansible produit par l’équipe est difficile à lire et à maintenir car il mélange des modules, et des appels AWS CLI. Une partie non négligeable du code est dédiée à la gestion des cas particuliers de suppression, de renommage, de wait, etc. qui de fait, détourne le néophyte de l’objectif à atteindre. Des outils comme CloudFormation encapsulent cette tuyauterie interne et permettent ainsi de se concentrer sur les problématiques d’organisation et d’optimisation des workflows.

Cela ne veut pour autant pas dire qu’Ansible est un mauvais outil. Bien au contraire, il excelle en tant que gestionnaire de configuration. Dès qu’il faut installer des logiciels sur une machine existante, il tire son épingle du jeu. Besoin d’installer un middleware sur une instance EC2 ? D’effectuer des opérations au démarrage ? Ansible remplira parfaitement ce rôle. À vouloir se diversifier en étendant son périmètre, il est évident qu’en dehors de la gestion de configuration, Ansible ne peut pas proposer autant d’options et de fonctionnalités que des outils dédiés.

De ce fait, Ansible n’est clairement pas le meilleur choix pour la création de ressources et la manipulation des API cloud AWS. CloudFormation ou d’autres outils spécialisés comme Terraform vous feront gagner un temps précieux tout en proposant des concepts adaptés (notion de stack, Change Set, etc). Le code n’en sera que plus lisible car dénué de tous les cas particuliers explicités plus haut.

Je ne saurai trop vous conseiller de choisir le bon outil pour le bon besoin.

7 réflexions au sujet de « Pourquoi ansible n’est pas un bon choix pour créer son infra AWS ? »

  1. Publié par Hoggar, Il y a 2 semaines

    Merci pour ce retour d’expérience, vous dites vers la fin que « le code Ansible produit par l’équipe est difficile à lire et à maintenir car il mélange des modules, et des appels AWS CLI. »,
    avez-vous regarder le code avec un œil critique, fort possible que votre code n’était pas bien optimiser?
    l’avantage des modules est de résoudre les problèmes spécifiques il faut développer vos propres modules.

    Merci.

  2. Publié par ALBERT Sébastien, Il y a 2 semaines

    Bonjour,

    Pourquoi ne pas avoir utiliser le rôle ansible cloudformation qui permet de lancer un stack AWS ?

  3. Publié par Jérémy Pinsolle, Il y a 2 semaines

    Bonjour, la solution d’allier l’univers Ansible avec CloudFormation à travers le module cloudformation a été proposée au client. Cependant il ne l’a pas retenu et a choisi de gérer l’infra avec les modules existants / AWS CLI. Ce qui occasionne les difficultés citées dans l’article.

    Pour avoir également utilisé le module cloudformation d’Ansible, il s’avère que c’est un bon moyen de gérer et de variabiliser les paramètres en étant dans l’écosystème Ansible.

  4. Publié par Jérémy Pinsolle, Il y a 2 semaines

    Bonjour,

    Les modules spécifiques apportent indéniablement la personnalisation souhaitée. Mais pour gérer convenablement les multiples cas (création, mise à jour, suppression) cela demande une organisation, du temps et des tests que nous n’avions pas au vu des délais du projet.

    Terraform ou CloudFormation ont déjà fait ce travail alors autant utiliser directement ces outils plutôt que de redévelopper des solutions personnalisées.

  5. Publié par Pierre FEVRIER, Il y a 2 semaines

    Bonjour, ce qui manque au rôle cloudformation, c’est un peu d’information sur ce qui se passe durant son exécution, au lieu d’avoir à attendre la fin de l’exécution pour qu’un bon gros JSON pas très parlant indique le résultat.

  6. Publié par Jean-François, Il y a 1 semaine

    Ansible est-il un bon choix pour créer une infra. sur openstack ?

  7. Publié par Alexis "Horgix" Chotard, Il y a 1 semaine

    Bonjour,

    La problématique est la même peu importe le provider de Cloud utilisé (AWS, Openstack, GCE, …) : Ansible n’est pas fait pour décrire de l’infrastructure, mais bien pour décrire de la configuration à appliquer sur une machine.

    Pour Openstack, Heat est l’équivalent de CloudFormation côté AWS et sera adapté à de la description d’infrastructure Openstack. Terraform, évoqué dans l’article et supportant de multiples providers de Cloud, est également capable de gérer des descriptions d’infrastructure sur Openstack.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *