URL: https://linuxfr.org/news/sortie-de-terraform-0-9 Title: Sortie de Terraform 0.9 Authors: CrEv Davy Defaud, ZeroHeure, palm123, Benoît Sibaud et Nils Ratusznik Date: 2017年03月16日T11:37:15+01:00 License: CC By-SA Tags: hashicorp, consul, nomad, terraform, cloud, infrastructure et elasticsearch Score: 25 Le 15 mars 2017 a été [annoncée](https://www.hashicorp.com/blog/terraform-0-9/) la sortie de la version 0.9 de [Terraform](https://terraform.io) par [HashiCorp](https://www.hashicorp.com) (Vagrant, Consul, Nomad, [etc.](https://www.hashicorp.com/)). Terraform est un outil d’_Infrastructure as Code_ qui permet de décrire et créer son infrastructure sous forme d’un code source déclaratif. Il est en partie équivalent à des outils tels [puppet](https://puppet.com/), [Ansible](https://www.ansible.com/) ou [Chef](https://www.chef.io/chef/) (pour la partie infrastructure). Pour ce faire il s’appuie sur un ensemble de [_providers_](https://www.terraform.io/docs/providers/) permettant de manipuler des ressources Amazon Web Services, Google Cloud, OpenStack, mais aussi Docker, Nomad, etc. La liste est longue et continue régulièrement à s’agrandir. ---- [Annonce de Terraform 0.9](https://www.hashicorp.com/blog/terraform-0-9/) [Terraform](https://terraform.io/) [Journal des modifications](https://github.com/hashicorp/terraform/blob/master/CHANGELOG.md) ---- Exemple ------- Pour mieux comprendre, voici deux petits exemples de ce qui peut être réalisé. Le premier crée une instance dans un _cloud_ OpenStack en y attachant un volume de données : ```docker resource "openstack_blockstorage_volume_v1" "myvol" { name = "myvol" size = 1 } resource "openstack_compute_instance_v2" "volume-attached" { name = "volume-attached" image_id = "ad091b52-742f-469e-8f3c-fd81cadf0743" flavor_id = "3" key_pair = "my_key_pair_name" security_groups = ["default"] network { name = "my_network" } volume { volume_id = "${openstack_blockstorage_volume_v1.myvol.id}" } } ``` Le deuxième définit une image pour Docker et crée un conteneur avec elle : ```docker # Configure the Docker provider provider "docker" { host = "tcp://127.0.0.1:2376/" } # Create a container resource "docker_container" "foo" { image = "${docker_image.ubuntu.latest}" name = "foo" } resource "docker_image" "ubuntu" { name = "ubuntu:latest" } ``` Nouveautés de la 0.9 ----------------------- ### Provisionneurs à la destruction Depuis les débuts de Terraform, un système d’approvisionnement permet d’exécuter des actions locales ou distantes lors de la création d’une ressource. Par exemple, vous voulez qu’un script shell soit exécuté à la création d’un serveur ; désormais, vous pouvez aussi réaliser cette action à la destruction. Cela peut permettre à un serveur membre d’une grappe d’envoyer un message indiquant qu’il va quitter la grappe juste avant que cela ne soit effectif. Voici un exemple où un membre d’une grappe de serveurs [Consul](https://www.consul.io/) indique qu’il quitte la grappe au moment de la destruction : ```docker resource "aws_instance" "consul" { # ... other fields provisioner "remote-exec" { command = "consul leave" when = "destroy" } } ``` ### Verrouillage de l’état Afin de pouvoir savoir quelles actions doivent êtres réalisées à chaque exécution, Terraform sauvegarde l’état courant de l’infrastructure dans un fichier. Avec cette solution il n’était pas possible d’exécuter simultanément (par exemple, par deux personnes différentes) plusieurs fois Terraform. Pour prévenir ce problème, il fallait s’appuyer sur des outils externes du type de [Terragrunt](https://github.com/gruntwork-io/terragrunt). Désormais, Terraform est capable de poser un verrou au niveau de l’état, que l’infrastruture soit stockée localement (dans un fichier), sur AWS S3 ou dans Consul. D’autres prises en charge vont être ajoutées dans les versions 0.9._x_, ainsi que des fonctionnalités avancées de verrouillage. C’était attendu avec impatience, non que Terragrunt ne fasse pas son boulot, mais cela va permettre de réduire le nombre d’outils mis en œuvre pour réaliser les actions de base. ### Approvisionnements interruptibles Terraform a toujours su s’arrêter proprement sur un `Ctrl` + `c`. Mais, pour rester dans un état cohérent, il devait attendre que la tâche courante se termine. Certaines tâches prenant parfois plusieurs minutes, cela n’était pas optimal (par exemple, création d’une instance de base de données chez Amazon). Désormais, Terraform va rendre la main sans attendre et marquer l’instance comme _tainted_ ce qui forcera sa recréation à la prochaine exécution. ### Gestion des environnements Si vous avez de multiples environnements pour votre projet (par exemple, _staging_, pré‐production, production) rien n’était fait jusqu’à présent pour vous faciliter la vie. Comme dit plus haut, Terraform stocke l’état de l’infrastructure dans un fichier. Mais, qui dit multiples environnements, dit multiples fichiers d’états à partir d’un même code et probablement de multiples fichiers de variables pour stocker des identifiants différents par environnement. Et ce n’était tout simplement pas géré. Avant la version 0.9, nous utilisions une surcouche à base de `Makefile` pour gérer tout ceci : ```Makefile apply: $(TERRAFORM_BIN) apply -state=$(call getenv).tfstate -var environment=$(call getenv) -var-file=$(call getenv).tfvars ``` Ce qui permettait de faire (je vous ai masqué un peu les détails) `make apply env=staging` ou `make apply production`. Certes, ça fonctionne, mais c’est mieux de l’éviter pour se concentrer sur des choses de plus grande valeur et pour gagner en fiabilité. Avec la 0.9, il est donc possible d’avoir de multiples environnements : ```bash $ terraform env list default * mitchellh-test $ terraform env select default Switched to environment "default"! $ terraform env delete mitchellh-test Deleted environment "mitchellh-test"! ``` Et une nouvelle interpolation `${terraform.env}` permet de connaitre l’environnement dans les fichiers Terraform : ```docker resource "aws_instance" "example" { count = "${terraform.env == "default" ? 5 : 1}" tags { Name = "web - ${terraform.env}" } # ... other fields } ``` ### Réorganisation du stockage distant de l’état Nous avons vu plus haut le nouveau verrouillage des fichiers d’état, y compris pour le stockage distant. Le stockage des états à distance a été revu en profondeur pour un usage plus agréable et une meilleure confiance. Par exemple, si un stockage distant est configuré, Terraform en ligne de commande va l’utiliser préférentiellement au fichier d’état local. ### DataSources pour Ignition C’est un point qui n’est pas présent dans le billet de sortie de la version 0.9, mais il fait partie des améliorations que nous utilisons en production depuis quelques temps. Nous utilisons Terraform pour instancier des grappes de serveurs [CoreOS](https://coreos.com/). Les machines nécessitant souvent quelques actions initiales (par exemple, formater et monter un disque) nous utilisons pour cela [Ignition](https://coreos.com/ignition/docs/latest/) qui au premier amorçage va configurer ces éléments plutôt bas niveau. Or, la prise en charge d’Ignition était loin d’être parfaite, avec certains comportements plutôt désagréables. Avec la version 0.9 [la manière de gérer Ignition](https://github.com/hashicorp/terraform/pull/11851) a été fortement améliorée. Voici un exemple réel (un poil allégé tout de même) montrant la configuration d’un serveur qui va installer un service systemd directement au premier démarrage : ```docker # Définition de l’unité systemd se trouvant dans le fichier data/elasticsearch.service data "ignition_systemd_unit" "elasticsearch" { name = "elasticsearch.service" content = "${file("${path.module}/data/elasticsearch.service")}" } # Définition d’un serveur prenant en charge elasticsearch resource "aws_instance" "es_srv" { # ... paramètres de l'instance, taille, etc # Indique la configuration à appliquer au premier boot user_data = "${data.ignition_config.es_srv.rendered}" } # Configuration systemd (ou autre) data "ignition_config" "es_srv" { systemd = [ "${data.ignition_systemd_unit.elasticsearch.id}", ] } ``` Open Source -------------- Le développement de Terraform est [ouvert](https://github.com/hashicorp/terraform). Terraform (ainsi que les autres outils de HashiCorp) fait partie de ces projets où il est facile d’échanger avec l’équipe de développeurs, que ce soit pour rapporter des bogues ou pour proposer des améliorations. Le projet est sous [licence publique Mozilla version 2](https://github.com/hashicorp/terraform/blob/master/LICENSE). Suite des développements ------ Le développement de la version 0.9.1 est déjà en route, avec entre autres un nouveau _provider_ pour [Kubernetes](https://kubernetes.io/), l’orchestrateur de conteneurs de Google qui a bien le vent en poupe en ce moment.