Sommaire
Le but ici est de présenter des outils ainsi qu’une méthode pour les utiliser en synergie.
Terraform
Terraform est un outil sous Mozilla Public License 2.0, dont le développement est soutenu par la société Hashicorp. C’est un outil d’infrastructure as code, encore un peu jeune, mais avec une communauté très active et son évolution technique va dans le bon sens (comprenez : le projet se bonifie à chaque nouvelle version).
Terraform permet de décrire, dans une syntaxe unique, basée sur un formalisme JSON légèrement simplifié pour une meilleure lisibilité, de l’infrastructure à provisionner chez différents fournisseurs. Attention, la promesse n’est pas une abstraction qui se voudrait portable chez tous les fournisseurs, mais bien une syntaxe de description commune.
Il existe déjà des connecteurs vers les plus gros fournisseurs de Cloud que sont Amazon Web Services, Azure, Google Cloud et OpenStack. Une infrastructure Cloud a tendance à avoir besoin de s’accrocher à des fournisseurs de services SaaS tels que des bases de données ou des DNS. C’est pourquoi de plus en plus de connecteurs sont apportés par la communauté, 34 autres connecteurs permettent de se provisionner sur :
- des bases de données (PostgreSQL, MySQL, RethinkDB)
- VMWare (vSphere et vCloud Director)
- CloudFlare
- CloudStack
Allez voir la liste complète, vous trouverez sûrement votre bonheur.
Une fois votre infrastructure décrite, Terraform peut vous l’appliquer ou calculer un différentiel entre une application actuelle et son état futur décrit dans les descripteurs . Terraform vous permet d’enregistrer ces plans d’exécution sous forme de fichiers, afin de pouvoir les relire avant de lui laisser la bride sur le cou pour impacter une plate-forme.
Dans notre boîte à outils, c’est à Terraform que nous allons confier toute la partie infrastructure.
Packer
Nous avons de l’infrastructure: formidable ! Cependant, il arrive souvent qu’on ait besoin de préparer des images serveurs en amont, afin de gagner un précieux temps d’installation et de mise à jour initiale du système. C’est là que Packer entre en jeu. La raison d’être de Packer est de créer des images serveurs ou des images de conteneurs : AMI Amazon, Azure, OpenStack, Docker, et d’autres.
Le principe est simplissime puisque, moyennant quelques paramètres dans un fichier de build JSON, Packer va :
- démarrer des instances sur les providers configurés
- leur appliquer une succession d’opérations de configuration
- prendre un instantané et ranger l’image dans la bibliothèque du provider concerné
Parmi les opérations de configuration il en est deux que je vais mettre un peu plus en lumière : shell et ansible-local.
Grâce à shell vous pouvez… tout faire évidemment, c’est du shell ! Mais ce que je vous suggère, c’est de n’utiliser le provisionner shell que pour le strict minimum à mon sens : installer ansible sur la machine. Une fois ansible installé, vous pouvez utiliser le provisionner ansible-local qui va uploader vos playbooks et les lancer sur la machine en train d’être provisionnée.
Ansible
Ansible est un outil d’orchestration qui n’a normalement plus besoin de présentation.
Pourquoi Ansible plutôt qu’un autre, sachant que Packer fournit des provisionners Puppet, Chef et Salt ? C’est vrai tiens…
Toi, lecteur aguerri, si tu as déjà tes habitudes avec un cousin de la famille des gestionnaires de configuration, garde-le. Si, si, j’insiste, utilise-le plutôt qu’Ansible. On parle d’infrastructure et de maintien dans le temps : maîtriser ses outils est indispensable. Pour le provisioning, j’ai tendance à privilégier l’outillage déjà maîtrisé que le dernier outil hipster-friendly.
Toi lecteur, qui hésite encore ou qui connaît des difficultés avec les petits cousins, je te conseille de donner sa chance à Ansible parce que c’est un outil qui :
- sent le script shell : porter un script vers du Ansible se fait très rapidement. En général, ça diminue le nombre de lignes, améliore la lisibilité et rend les choses plus structurées
- s’apprend vite : toute expérience de scripting est réutilisable, les arcanes de l’usage de rôles viendront plus tard. Vous pouvez commencer à être productif en quelques heures.
- ne nécessite pas d’agent : en terme de provisioning, on traite bien les playbooks Ansible comme des scripts. Complexité de mise en place égale à zéro : just run it.
Les astuces de Tonton Mô
Maintenant que nous avons bien dressé le tableau, vous avez l’idée, grosses mailles. Je vais vous donnez, en vrac, quelques conseils qui peuvent faire la différence entre une expérience réussie et une prise de tête de plusieurs heures.
Orchestrez
Rangez vos actions dans des jobs Jenkins, GitlabCI, GoCD ou autre, mais rangez-les. Une modification dans vos sources se traduit par une grosse poignée de commandes à lancer avec des outputs à chaîner d’une action sur l’autre. Soyez sûr d’avoir rôdé votre chaîne de déploiement continu et d’en faire un backup. J’ai personnellement un faible pour GoCD, cela fera peut-être l’objet d’un futur billet de blog.
Packer : collez à ansible-local
Gérer des inventaires de host dynamique pour pouvoir appliquer du Ansible distant est pénible. De plus, vos playbooks devront toujours cibler un groupe alors que vous ne provisionnez qu’une machine unique, donc autant coller au groupe par défaut “localhost” et appliquer cette norme sur tous vos playbooks. Utilisez un script d’installation propre de Ansible, appliqué par le provisionner shell, puis déportez toute la complexité dans des playbooks.
Terraform : relisez toujours le plan
Terraform vous permet de calculer et sauvegarder un plan d’exécution où est inscrit la liste exhaustive des actions qu’il se propose d’appliquer sur votre infrastructure. Suivant vos modifications, cela peut entraîner des suppressions sauvages et donc des interruptions de service. Faites calculer un plan, sauvegardez-le dans un fichier, relisez-le et s’il vous convient: jouez le plan d’exécution. Avec Terraform, on ne peut prendre le risque d’un déploiement continu à l’aveugle QUE sur un environnement non-critique.
Ansible : découpez en rôle
Pour plus de souplesse, évitez les playbooks monolithiques à rallonge. Découpez vos unités de configuration en rôles et utilisez ansible-galaxy et un fichier requirements.yml pour rapatrier directement les rôles de vos dépôts de source avant application des playbooks. Vous pourrez ainsi gérer finement le versionning de chaque rôle. Cela modifie un peu le provisioning Packer qui devient :
- file : upload du requirements.yml
- shell : installation d’ansible et installation des rôles via ansible-galaxy
- ansible-local : application du playbook de configuration
Ansible : laissez-le vivre
Une remarque qui m’a souvent été faite est qu’Ansible se retrouve installé sur toutes les images serveurs, à moins de rajouter des étapes shell pour le désinstaller en fin de provisioning. Je vous conseille de simplement le laisser en place. Si pour des conteneurs, il est important de gagner la moindre place, pour des images de serveur, les binaires Ansible ne pèsent presque rien en comparaison d’une AMI. Ansible ne risque pas de vous manger de ressources. Il est aussi inoffensif que ssh-client ou vim et peut vous rendre des services si un jour vous êtes amené à vous connecter à vos serveurs.
Le mot de la fin
Ceux qui connaissent bien Hashicorp auront vu que le modèle exposé ici est une version personnelle du Atlas Mindset de Hashicorp. Évidemment la solution poussée par la société met au coeur de la chaîne d’outils leur serveur payant : Atlas. Il est possible que ce soit un produit formidable qui fasse gagner beaucoup de temps… De mon point de vue, utiliser n’importe quel serveur d’intégration continue avec Packer, Terraform et un outil de gestion de configuration bien maîtrisé (Ansible est mon chouchou) suffit largement à l’ultra majorité des besoins.
Have fun. Hack in peace.