samedi , 22 septembre 2018
Home » Services Hébergement Cloud » Pourquoi utilise-t-on Terraform et non Chef, Puppet, Ansible, SaltStack ou CloudFormation ?

Pourquoi utilise-t-on Terraform et non Chef, Puppet, Ansible, SaltStack ou CloudFormation ?

Dans cet article, nous allons discuter des différentes raisons pour lesquelles chaque entreprise devrait utiliser l’infrastructure-as-code (IAC). Pourquoi devons-nous choisir Terraform comme outil de choix IAC (Infrastructure-as-code) ?

Si vous recherchez « infrastructure-as-code » sur Internet, il est assez facile de trouver une liste des outils les plus populaires :

Ce qui n’est pas facile, c’est de déterminer lequel d’entre eux vous devriez utiliser. Tous ces outils peuvent être utilisés pour gérer l’infrastructure-as-code. Ils sont tous sont open source, soutenus par de grandes communautés de contributeurs, et travaillent avec de nombreux fournisseurs de cloud différents (à l’exception notable de CloudFormation, qui est à source fermée et uniquement AWS). Tous offrent un soutien aux entreprises. Tous sont bien documentés, à la fois en termes de documentation officielle et de ressources communautaires telles que les articles de blog et les questions StackOverflow. Alors, comment décidez-vous ?

Ce qui le rend encore plus difficile, c’est que la plupart des comparaisons que vous trouvez en ligne entre ces outils font un peu plus que lister les propriétés générales de chaque outil et donner l’impression que vous pourriez avoir autant de succès avec l’un d’eux. Et même si c’est techniquement vrai, ce n’est pas utile. C’est un peu comme dire à un novice en programmation que vous pourriez réussir à construire un site Web avec PHP, C ou Assembly – une affirmation qui est techniquement vraie, mais qui omet une énorme quantité d’informations qui serait incroyablement utile pour prendre une bonne décision .

Dans ce post, nous allons plonger dans les raisons très spécifiques pour lesquelles nous devons choisir Terraform que les autres outils IAC. Comme pour toutes les décisions technologiques, c’est une question de compromis et de priorités, nous espérons que le partage de ce processus de réflexion vous aidera à prendre votre propre décision. Voici les principaux compromis que vous devez considérer :

  • Gestion de configuration vs orchestration
  • Infrastructure Mutable vs Infrastructure Immutable
  • Procédural vs Déclaratif
  • Architecture client/serveur vs architecture client uniquement

Gestion de configuration vs orchestration

Chef, Puppet, Ansible et SaltStack sont tous des outils de « gestion de configuration », ce qui signifie qu’ils sont conçus pour installer et gérer des logiciels sur des serveurs existants. CloudFormation et Terraform sont des « outils d’orchestration », ce qui signifie qu’ils sont conçus pour provisionner les serveurs eux-mêmes, laissant le travail de configuration de ces serveurs à d’autres outils. Ces deux catégories ne s’excluent pas mutuellement, car la plupart des outils de gestion de configuration peuvent effectuer un certain niveau d’approvisionnement et la plupart des outils d’orchestration peuvent faire un certain niveau de gestion de la configuration. Mais, l’accent mis sur la gestion ou l’orchestration de la configuration signifie que certains outils seront mieux adaptés à certains types de tâches.

En particulier, nous avons constaté que si vous utilisez Docker ou Packer, la grande majorité de vos besoins de gestion de configuration sont déjà pris en charge. Avec Docker et Packer, vous pouvez créer des images (telles que des conteneurs ou des images de machines virtuelles) disposant de tous les logiciels dont votre serveur a besoin, déjà installés et configurés (pour plus d’informations sur ce qui rend Docker génial, voir ici). Une fois que vous avez une telle image, tout ce dont vous avez besoin est un serveur pour l’exécuter. Et si tout ce que vous avez à faire est de provisionner un tas de serveurs, un outil d’orchestration comme Terraform sera généralement mieux adapté qu’un outil de gestion de configuration (voici un exemple d’utilisation de Terraform pour déployer Docker sur AWS).

Infrastructure Mutable vs Infrastructure Immutable

Les outils de gestion de configuration tels que Chef, Puppet, Ansible et SaltStack sont généralement définis par défaut comme un paradigme d’infrastructure modifiable. Par exemple, si vous demandez à Chef d’installer une nouvelle version d’OpenSSL, il exécutera la mise à jour logicielle sur vos serveurs existants et les modifications seront effectuées sur place.

Au fil du temps, à mesure que vous appliquez de plus en plus de mises à jour, chaque serveur crée un historique unique de modifications. Cela conduit souvent à un phénomène connu sous le nom de dérive de configuration, où chaque serveur devient légèrement différent de tous les autres, ce qui conduit à des bogues de configuration subtils qui sont difficiles à diagnostiquer et presque impossible à reproduire.

Si vous utilisez un outil d’orchestration tel que Terraform pour déployer des images de machine créées par Docker ou Packer, chaque « changement » est en réalité un déploiement d’un nouveau serveur (tout comme chaque « changement » d’une variable dans la programmation fonctionnelle renvoie un nouvelle variable). Par exemple, pour déployer une nouvelle version d’OpenSSL, vous créez une nouvelle image à l’aide de Packer ou Docker avec la nouvelle version d’OpenSSL déjà installée, déployez cette image sur un ensemble de serveurs totalement nouveaux, puis annulez le déploiement des anciens serveurs.

Cette approche réduit la probabilité de bogues de dérive de configuration, permet de savoir exactement quel logiciel est en cours d’exécution sur un serveur et vous permet de déployer de manière triviale n’importe quelle version précédente du logiciel à tout moment. Bien sûr, il est possible de forcer les outils de gestion de la configuration à faire des déploiements immuables, mais ce n’est pas l’approche idiomatique pour ces outils, alors que c’est un moyen naturel d’utiliser les outils d’orchestration.

Procédural vs Déclaratif

Chef et Ansible encouragent un style procédural où vous écrivez un code qui spécifie, étape par étape, la manière d’atteindre certains états finaux souhaités. Terraform, CloudFormation, SaltStack et Puppet encouragent tous un style plus déclaratif où vous écrivez un code qui spécifie votre état final souhaité, et l’outil IAC lui-même est responsable de déterminer la manière d’atteindre cet état.

Par exemple, supposons que vous vouliez déployer 10 serveurs (« Instances EC2 » dans AWS jargon) pour exécuter v1 d’une application. Voici un exemple simplifié d’un modèle Ansible qui le fait avec une approche procédurale :

- ec2:
    count: 10
    image: ami-v1    
    instance_type: t2.micro

Et voici un exemple simplifié d’un modèle Terraform qui fait la même chose en utilisant une approche déclarative :

resource "aws_instance" "example" {
  count = 10
  ami = "ami-v1"
  instance_type = "t2.micro"
}

Maintenant, ces deux approches peuvent sembler similaires, et quand vous les exécutez initialement avec Ansible ou Terraform, elles produiront des résultats similaires. La chose intéressante est ce qui se passe quand vous voulez faire un changement.

Par exemple, imaginez que le trafic a augmenté et que vous voulez augmenter le nombre de serveurs à 15. Avec Ansible, le code de procédure que vous avez écrit précédemment n’est plus utile ; si vous venez de mettre à jour le nombre de serveurs à 15 et de relancer ce code, il déploiera 15 nouveaux serveurs, ce qui vous donnera 25 au total ! Donc, à la place, vous devez être conscient de ce qui est déjà déployé et écrire un script procédural totalement nouveau pour ajouter les 5 nouveaux serveurs :

- ec2:
    count: 5
    image: ami-v1    
    instance_type: t2.micro

Avec le code déclaratif, puisque tout ce que vous faites est de déclarer l’état final que vous voulez, et Terraform détermine comment atteindre cet état final, Terraform sera également au courant de tout état créé dans le passé. Par conséquent, pour déployer 5 serveurs de plus, il vous suffit de revenir au même modèle Terraform et de mettre à jour le nombre de serveurs de 10 à 15 :

resource "aws_instance" "example" {
  count = 15
  ami = "ami-v1"
  instance_type = "t2.micro"
}

Si vous avez exécuté ce modèle, Terraform se rendrait compte qu’il avait déjà créé 10 serveurs et donc que tout ce qu’il devait faire était de créer 5 nouveaux serveurs. En fait, avant d’exécuter ce modèle, vous pouvez utiliser la commande « plan » de Terraform pour prévisualiser les modifications qu’il apporterait :

> terraform plan
+ aws_instance.example.11
    ami:                      "ami-v1"
    instance_type:            "t2.micro"
+ aws_instance.example.12
    ami:                      "ami-v1"
    instance_type:            "t2.micro"
+ aws_instance.example.13
    ami:                      "ami-v1"
    instance_type:            "t2.micro"
+ aws_instance.example.14
    ami:                      "ami-v1"
    instance_type:            "t2.micro"
+ aws_instance.example.15
    ami:                      "ami-v1"
    instance_type:            "t2.micro"
Plan: 5 to add, 0 to change, 0 to destroy.

Maintenant, que se passe-t-il lorsque vous souhaitez déployer le service v2 ? Avec l’approche procédurale, vos deux modèles Ansible précédents ne sont pas utiles, vous devez donc écrire un autre modèle pour localiser les 10 serveurs que vous avez déployés précédemment (ou était-ce 15 maintenant ?) et les mettre à jour soigneusement pour la nouvelle version.

Avec l’approche déclarative de Terraform, vous revenez au même modèle et changez simplement le numéro de version « ami » en v2 :

resource "aws_instance" "example" {
  count = 15
  ami = "ami-v2"
  instance_type = "t2.micro"
}

Évidemment, les exemples ci-dessus sont simplifiés. Ansible vous permet d’utiliser des balises pour rechercher des instances EC2 existantes avant d’en déployer de nouvelles (par exemple en utilisant les paramètres instance_tags et count_tag), mais de devoir trouver manuellement ce type de logique pour chaque ressource que vous gérez avec Ansible, basée sur une histoire passée de chaque ressource, peut être étonnamment compliquée (par exemple trouver des instances existantes non seulement par tag, mais aussi par version d’image, zone de disponibilité, etc.).

Cela met en évidence deux problèmes majeurs avec les outils procéduraux IAC :

  1. Lorsqu’il s’agit de code de procédure, l’état de l’infrastructure n’est pas entièrement capturé dans le code. La lecture des trois modèles Ansible que nous avons créés ci-dessus ne suffit pas pour savoir ce qui est déployé. Vous devez également connaître l’ordre dans lequel on applique ces modèles. Si on les applique dans un ordre différent, on pourra se retrouver avec une infrastructure différente, et ce n’est pas quelque chose que l’on peut voir dans la base de code elle-même. En d’autres termes, pour raisonner sur un code Ansible ou Chef, vous devez connaître l’historique complet de chaque changement qui s’est produit.
  2. La réutilisabilité du code procédural est intrinsèquement limitée, car vous devez prendre en compte manuellement l’état actuel de la base de code. Comme cet état change constamment, le code que vous avez utilisé il y a une semaine peut ne plus être utilisable, car il a été conçu pour modifier un état de votre infrastructure qui n’existe plus. En conséquence, les bases de code procédural ont tendance à se développer et à se compliquer avec le temps.

D’un autre côté, avec le type d’approche déclarative utilisé dans Terraform, le code représente toujours le dernier état de votre infrastructure. En un coup d’œil, vous pouvez savoir ce qui est actuellement déployé et comment il est configuré, sans avoir à vous soucier de l’historique ou du timing.

Cela facilite également la création de code réutilisable, car vous n’avez pas à tenir compte manuellement de l’état actuel du monde. Au lieu de cela, vous vous concentrez simplement sur la description de votre état souhaité, et Terraform détermine automatiquement comment passer d’un état à l’autre. En conséquence, les bases de code Terraform ont tendance à rester petites et faciles à comprendre.

Bien sûr, il y a aussi des inconvénients pour les langages déclaratifs. Sans accéder à un langage de programmation complet, votre puissance expressive est limitée. Par exemple, certains types de changements d’infrastructure, tels qu’un déploiement progressif sans interruption, sont difficiles à exprimer en termes purement déclaratifs.

De même, sans la possibilité de faire de la « logique » (par exemple if-statements, loops), créer un code générique et réutilisable peut être difficile (en particulier dans CloudFormation). Heureusement, Terraform fournit un certain nombre de primitives puissantes – telles que variables d’entrée, variables de sortie, modules, fonctions create_before_destroy, count et interpolation – qui permettent de créer un code propre, configurable et modulaire même dans un langage déclaratif.

Architecture client/serveur et architecture client uniquement

© 2014 Pearson Education, Inc. Publishing as Prentice Hall.

Chef, Puppet et SaltStack utilisent tous une architecture client/serveur par défaut. Le client, qui peut être une interface utilisateur Web ou un outil CLI, est ce que vous utilisez pour émettre des commandes (par exemple « déployer X »). Ces commandes vont à un serveur, qui est responsable de l’exécution de vos commandes et de stocker l’état du système. Pour exécuter ces commandes, le serveur parle aux agents, qui doivent être en cours d’exécution sur chaque serveur que vous souhaitez configurer. Cela a un certain nombre d’inconvénients :

  • Vous devez installer et exécuter des logiciels supplémentaires sur chacun de vos serveurs.
  • Vous devez déployer un serveur supplémentaire (ou même un cluster de serveurs pour la haute disponibilité) uniquement pour la gestion de la configuration.
  • Vous devez non seulement installer ce logiciel et matériel supplémentaire, mais vous devez également le maintenir, le mettre à niveau, en faire des sauvegardes, le surveiller et le restaurer en cas de panne.
  • Comme le client, le serveur et les agents ont tous besoin de communiquer sur le réseau, vous devez leur ouvrir des ports supplémentaires et configurer les moyens de s’authentifier les uns aux autres, ce qui augmente votre surface pour les attaquants.
  • Toutes ces pièces mobiles supplémentaires introduisent un grand nombre de nouveaux modes de défaillance dans votre infrastructure. Lorsque vous recevez un rapport de bogue à 3h du matin, vous devez déterminer s’il s’agit d’un bogue dans votre code d’application, votre code IAC ou le logiciel client de gestion de configuration ou le logiciel agent de gestion de configuration ou le logiciel serveur de gestion de configuration ou les ports que tous ces éléments de gestion de configuration utilisent pour communiquer, ou la façon dont ils s’authentifient les uns aux autres, ou …

CloudFormation, Ansible et Terraform utilisent une architecture client uniquement. En fait, CloudFormation est également client/serveur, mais AWS gère tous les détails du serveur de manière transparente, en tant qu’utilisateur final, il suffit de penser au code client. Le client Ansible fonctionne en se connectant directement à vos serveurs via SSH.

Terraform utilise des API de fournisseur de cloud pour provisionner l’infrastructure, il n’y a donc pas de nouveaux mécanismes d’authentification au-delà de ce que vous utilisez déjà avec le fournisseur de cloud, et vous n’avez pas besoin d’un accès direct à vos serveurs. Nous avons trouvé cela comme la meilleure option en termes de facilité d’utilisation, de sécurité et de maintenabilité.

Conclusion

Tout mettre ensemble, voici un tableau qui montre comment s’empilent les outils IAC les plus populaires :

Une comparaison des outils populaires d’infrastructure-as-code. Notez que ce tableau montre la manière « idiomatique » d’utiliser chaque outil.

Chez Gruntwork, ils veulent un outil d’orchestration Open Source, indépendant du cloud, capable de prendre en charge une infrastructure immuable, un langage déclaratif et une architecture réservée aux clients. Dans le tableau ci-dessus, Terraform est le seul outil qui répond à tous ces critères.

Bien sûr, Terraform n’est pas parfait. Il est plus jeune et moins mature que tous les autres outils de la liste : alors que Puppet est sorti en 2005, Chef en 2009, SaltStack et CloudFormation en 2011, et Ansible en 2012, Terraform est sorti il ​​y a seulement 4 ans, en 2014. Terraform est toujours pre 1.0.0, donc il n’y a aucune garantie d’une API stable ou rétrocompatible.

Les bogues sont relativement courants (par exemple, il y a plus de 800 problèmes ouverts avec l’étiquette « bug »), bien que la grande majorité soit des problèmes de cohérence inoffensifs qui disparaissent lorsque vous réexécutez Terraform. Il y a aussi quelques problèmes avec l’état des magasins Terraform, bien qu’il existe des solutions efficaces pour les résoudre.

Malgré ses inconvénients, nous pouvons constater que les forces de Terraform surpassent de loin ses faiblesses, et qu’aucun autre outil IAC ne correspond presque aussi bien à vos critères que Terraform.

À lire aussi

13 APIs que chaque développeur doit connaître

De l’IA à l’AR en passant par la transportation et la téléphonie, ces APIs Web …