Vers 2019, « infrastructure as code » est devenu synonyme de Terraform dans la plupart des conversations, comme « recherche » veut dire Google. C'est un défaut raisonnable. C'est aussi le mauvais outil pour une part significative des équipes, et la raison n'est pas les fonctionnalités, que les trois options sérieuses ont toutes, mais qui va écrire et lire le code.
Nous exploitons nos plateformes clients sur AWS CDK. Nous avons livré du Terraform et du Pulumi pour d'autres clients. Voici la comparaison que nous aurions aimé lire avant de choisir, organisée autour de la question qui décide, avec les compromis énoncés clairement et les cas où nous choisirions encore Terraform.
La question
L'infrastructure appartient-elle à l'équipe applicative, ou à une équipe plateforme séparée ?
Si les personnes qui écrivent l'application Next.js sont celles qui écrivent l'infrastructure, elles ont déjà un langage, un gestionnaire de paquets, un lanceur de tests et un éditeur configurés pour TypeScript. Leur donner un second langage (HCL) avec sa propre sémantique, son propre système de modules et sa propre histoire de test est un coût payé chaque jour par chaque personne. CDK ou Pulumi leur permet de définir l'infrastructure dans le langage dans lequel elles pensent déjà, dans le même dépôt, avec le même processus de revue, et de partager des types entre l'application et l'infra.
Si l'infrastructure appartient à une équipe plateforme qui sert de nombreuses équipes applicatives dans de nombreux langages, le calcul s'inverse. Cette équipe veut un seul langage pour toute l'infrastructure quel que soit le langage des applications, un modèle déclaratif facile à relire sur des centaines de modules, un immense écosystème de providers, et une sortie de plan qu'un non-programmeur peut lire dans un ticket de changement. C'est le terrain de Terraform, et les limites de HCL y sont une qualité : il est difficile d'y être trop malin.
Tout le reste de la comparaison découle de cette réponse.
Les trois, honnêtement
| Terraform / OpenTofu | AWS CDK | Pulumi | |
|---|---|---|---|
| Langage | HCL, déclaratif | TypeScript, Python, Java, Go, C# ; synthétise en CloudFormation | TypeScript, Python, Go, C#, Java, YAML ; son propre moteur |
| Clouds | Tous, via des providers ; le plus grand écosystème | AWS seulement (CDK for Terraform existe, mais c'est du Terraform) | Tous, via des providers, beaucoup enveloppant ceux de Terraform |
| État | Un fichier d'état que vous gérez : S3 + verrouillage, ou Terraform Cloud | CloudFormation le détient ; rien à gérer, rien à corrompre | Pulumi Cloud, ou S3 auto-géré |
| Plan / diff | terraform plan : précis, lisible, la référence |
cdk diff : bon pour les ressources, faible pour IAM et certains changements de propriétés |
pulumi preview : bon, entre les deux |
| Abstractions | Modules ; la composition est verbeuse, pas de vrais types | Constructs avec de vrais types ; les constructs L2 encodent les bonnes pratiques (une Queue est chiffrée, un Bucket bloque l'accès public) |
Composants, vrais types, plus la possibilité d'importer des constructs CDK |
| Tests | Assertions sur le plan, Terratest (Go) | Jest contre le template synthétisé ; rapide et précis | Tests unitaires dans le langage, avec mocks |
| Mode de défaillance | Dérive d'état ; un verrou oublié ; montées de version de providers | Les limites de CloudFormation : 500 ressources par stack, rollbacks lents, sémantique de remplacement | Les bugs du moteur sont à vous de déboguer ; communauté plus petite |
| Se lit bien pour | Des relecteurs qui ne programment pas | Des programmeurs | Des programmeurs |
| Qui paie | Changements de licence HashiCorp en 2023 ; OpenTofu est le fork communautaire | Gratuit ; le problème d'AWS | OSS gratuit ; le service cloud est payant |
Trois éléments de ce tableau décident plus de choix que tout le reste réuni.
L'état. Le fichier d'état de Terraform est la source de la plupart des incidents Terraform pour lesquels on nous a appelés : un état corrompu après un apply interrompu, un verrou périmé, un état qui référence une ressource supprimée à la main, une migration entre backends qui a mal tourné. CDK n'a pas de fichier d'état ; CloudFormation est l'état, et c'est le problème d'AWS de le garder cohérent. Cela seul supprime toute une catégorie de travail opérationnel. Le prix, ce sont les particularités propres de CloudFormation, qui sont réelles, mais auxquelles nous n'avons jamais perdu un fichier d'état.
Le diff. terraform plan est vraiment le meilleur aperçu de changement du secteur, et c'est une grande part de la raison pour laquelle les équipes plateforme l'adorent. cdk diff est suffisant pour le quotidien et mauvais pour IAM : il montre qu'une politique a changé mais ne montre pas toujours comment. Nous compensons avec cdk-nag et une règle qui consiste à coller l'IAM synthétisé dans la PR pour tout changement qui le touche. Si votre processus de revue est « quelqu'un qui n'écrit pas de code lit le plan », Terraform gagne ici, et de loin.
Les abstractions typées. En CDK, new sqs.Queue(this, 'Q') vous donne une file chiffrée avec des défauts raisonnables, et queue.grantConsumeMessages(fn) écrit la politique IAM pour vous, correctement, avec l'ARN exact. L'équivalent en Terraform est un module que quelqu'un a écrit, ou vingt lignes de JSON de politique que vous écrivez à la main et ratez une fois. Cette différence se cumule sur une plateforme : notre base de code CDK pour trois comptes fait environ 6 000 lignes ; l'équivalent Terraform, nous l'avons estimé à environ le double, avant les modules.
Quand nous choisirions encore Terraform
- Multi-cloud avec une équipe plateforme. Un langage, un workflow, chaque provider. Pulumi peut le faire aussi, mais l'écosystème Terraform de modules et de providers a une décennie de profondeur en plus.
- Tout ce où le relecteur n'est pas un programmeur. Les environnements pilotés par la conformité où le ticket de changement doit contenir un plan qu'un auditeur lit. HCL et
terraform planont été construits pour ça. - Hors AWS, un seul cloud, petite équipe. Les équipes GCP ou Azure sans forte identité TypeScript sont généralement mieux avec Terraform qu'avec Pulumi, sur la seule taille de la communauté.
- Une équipe qui l'a déjà et pour qui ça marche. Migrer un Terraform qui fonctionne vers CDK pour des raisons esthétiques est un mauvais échange. Nous avons décliné ce travail deux fois.
Quand Pulumi, plutôt que CDK
Quand l'équipe est nativement TypeScript et que le parc n'est pas purement AWS : une zone Cloudflare, un projet Vercel, un ensemble de moniteurs Datadog, un bucket GCP, à côté des ressources AWS. CDK s'arrête à la frontière d'AWS ; Pulumi non. Pulumi a aussi le meilleur diff des deux et un moteur plus rapide que CloudFormation pour les grands stacks. Le coût est une communauté plus petite et un backend d'état que vous payez ou que vous exploitez.
Ce que nous utilisons, et pourquoi
CDK, TypeScript, pour chaque plateforme client tout AWS. Les équipes applicatives sont des équipes TypeScript ; l'infrastructure vit dans infra/ dans le même monorepo que les applications ; les types des routes de l'API et les noms des variables d'environnement de l'infra viennent du même packages/types ; un changement à une file et à son consommateur est une seule PR. Jamais de fichier d'état. cdk diff collé dans chaque PR, IAM synthétisé et collé pour tout ce qui le touche, cdk-nag en CI, assertions Jest sur les templates pour les invariants qui comptent (chaque bucket bloque l'accès public, chaque file a une DLQ, aucune politique de suppression DESTROY hors d'un stack de démontage nommé).
Nous payons ça avec les limites et la lenteur de CloudFormation, dont nous avons longuement parlé, et avec la lacune du diff IAM, que la règle du collage dans la PR couvre. Pour ces équipes, c'est le bon échange, de loin. Pour une équipe plateforme servant douze langages sur deux clouds, nous leur dirions Terraform, et nous le penserions.
La version courte
Infrastructure as code est une pratique, pas un produit. La pratique : l'infrastructure est dans un dépôt, les changements sont relus, rien n'est cliqué. Le produit est choisi par qui possède le code. Équipe applicative en TypeScript sur AWS : CDK. Même équipe, plus qu'AWS : Pulumi. Équipe plateforme, de nombreux langages, des plans lus par des non-programmeurs : Terraform. Un Terraform qui fonctionne et que vous avez déjà : gardez-le.
Si vous choisissez, ou si vous avez hérité d'un choix qui ne correspond pas à l'équipe, nous avons exploité les trois et nous vous dirons lequel correspond à la vôtre, y compris quand la réponse est « celui que vous avez ».