Comment Déployer Plusieurs Environnements dans Votre Projet Terraform Sans Dupliquer de Code

L’auteur a choisi le Fonds Libre et Open Source pour recevoir un don dans le cadre du programme Write for DOnations.

Introduction

Terraform offre des fonctionnalités avancées qui deviennent de plus en plus utiles à mesure que votre projet grossit en taille et en complexité. Il est possible de réduire le coût du maintenance de définitions d’infrastructure complexes pour plusieurs environnements en structurettant votre code pour minimiser les répétitions et en introduisant des workflows assistés par des outils pour une mise à l’essai et une mise en production plus faciles.

Terraform associe un état à un backend, qui détermine où et comment l’état est stocké et récupéré. Chaque état n’a qu’un seul backend et est lié à une configuration d’infrastructure. Certains backends, tels que local ou s3, peuvent contenir plusieurs états. Dans ce cas, le lien entre l’état et l’infrastructure et le backend décrit un workspace. Les workspaces permettent de déployer plusieurs instances distinctes de la même configuration d’infrastructure sans les stocker dans des backends distincts.

Dans ce tutoriel, vous déployerez d’abord plusieurs instances d’infrastructure en utilisant des espaces de travail différents. Ensuite, vous déployerez une ressource avec état, qui, dans ce tutoriel, sera un Volume DigitalOcean. Enfin, vous référenerez des modules préconçus à partir du Registre Terraform, que vous pouvez utiliser pour compléter le vôtre.

Prérequis

Pour terminer ce tutoriel, vous aurez besoin de :

  • Un Jeton d’Accès Personnel DigitalOcean, que vous pouvez créer via le Panneau de Contrôle DigitalOcean. Vous pouvez trouver des instructions dans les documents du produit DigitalOcean, Comment Créer un Jeton d’Accès Personnel.
  • Terraform installé sur votre machine locale et un projet configuré avec le fournisseur DO. Complétez Étape 1 et Étape 2 du tutoriel Comment Utiliser Terraform avec DigitalOcean, et assurez-vous de nommer le dossier du projet terraform-advanced au lieu de loadbalance. Pendant Étape 2, n’incluez pas la variable pvt_key et la ressource de clé SSH.

Remarque : Ce tutoriel a spécifiquement été testé avec Terraform 1.0.2.

Déploiement de plusieurs instances d’infrastructure utilisant les espaces de travail

Les espaces de travail multiples sont utiles lorsque vous souhaitez déployer ou tester une version modifiée de votre infrastructure principale sans créer un projet séparé et sans avoir à configurer à nouveau les clés d’authentification. Une fois que vous avez développé et testé une fonctionnalité en utilisant un état séparé, vous pouvez intégrer le nouveau code dans l’espace de travail principal et éventuellement supprimer l’état supplémentaire. Lorsque vous init un projet Terraform, indépendamment du backend, Terraform crée un espace de travail appelé default. Il est toujours présent et vous ne pouvez jamais le supprimer.

Cependant, les espaces de travail multiples ne constituent pas une solution appropriée pour créer plusieurs environnements, comme pour le staging et la production. Par conséquent, les espaces de travail, qui ne suivent que l’état, ne stockent pas le code ou ses modifications.

Les espaces de travail ne suivent pas le code réel, vous devez donc gérer la séparation du code entre plusieurs espaces de travail au niveau de contrôle de version (VCS) en les reliant à leurs variantes d’infrastructure. La manière dont vous pouvez y parvenir dépend du outil VCS lui-même ; par exemple, dans les branches Git serait une abstraction appropriée. Pour faciliter la gestion du code pour plusieurs environnements, vous pouvez les diviser en modules réutilisables, afin d’éviter de répéter le code similaire pour chaque environnement.

Déploiement de ressources dans les espaces de travail

Vous allez maintenant créer un projet qui déploie un Droplet, que vous appliquerez à partir de plusieurs espaces de travail.

Vous stockerez la définition du Droplet dans un fichier appelé droplets.tf.

En supposant que vous êtes dans le répertoire terraform-advanced, créez-le et ouvrez-le à l’édition en exécutant :

  1. nano droplets.tf

Ajoutez les lignes suivantes :

resource "digitalocean_droplet" "web" {
  image  = "ubuntu-18-04-x64"
  name   = "web-${terraform.workspace}"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

Cette définition créera un Droplet fonctionnant sous Ubuntu 18.04 avec un核心 CPU et 1 Go de RAM dans la région fra1. Son nom contiendra le nom de l’espace de travail actuel depuis lequel il est déployé. Lorsque vous avez terminé, enregistrez et fermez le fichier.

Appliquer le projet pour Terraform pour exécuter ses actions avec :

  1. terraform apply -var "do_token=${DO_PAT}"

La sortie ressemblera à ceci :

Output
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.web sera créé + resource "digitalocean_droplet" "web" { + backups = false + created_at = (known after apply) + disk = (known after apply) + id = (known after apply) + image = "ubuntu-18-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + ipv6_address_private = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-default" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. ...

Entrez yes lorsque vous serez invité à déployer le Droplet dans l’espace de travail default.

Le nom du Droplet sera web-default, car l’espace de travail auquel vous démarrez est nommé default. Vous pouvez lister les espaces de travail pour vérifier qu’il n’y en a qu’un seul disponible :

  1. terraform workspace list

La sortie ressemblera à ceci :

Output
* default

L’astérisque (*) signifie que vous avez actuellement sélectionné cet espace de travail.

Créez et basculez vers un nouvel espace de travail appelé testing, que vous utiliserez pour déployer un Droplet différent, en exécutant workspace new :

  1. terraform workspace new testing

La sortie ressemblera à ceci :

Output
Created and switched to workspace "testing"! You're now on a new, empty workspace. Workspaces isolate their state, so if you run "terraform plan" Terraform will not see any existing state for this configuration.

Vous planifiez à nouveau le déploiement du Droplet en exécutant :

  1. terraform plan -var "do_token=${DO_PAT}"

La sortie sera similaire à celle de l’exécution précédente :

Output
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.web sera créé + resource "digitalocean_droplet" "web" { + backups = false + created_at = (known after apply) + disk = (known after apply) + id = (known after apply) + image = "ubuntu-18-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + ipv6_address_private = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-testing" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. ...

Notez que Terraform prévoit déployer un Droplet nommé web-testing, qui est nommé différemment de web-default. Cela est dû au fait que les espaces de travail default et testing ont des états séparés et n’ont aucune connaissance des ressources les uns des autres, même s’ils proviennent du même code.

Pour confirmer que vous êtes dans l’espace de travail testing, affichez l’espace de travail actuel en utilisant workspace show :

  1. terraform workspace show

La sortie sera le nom de l’espace de travail actuel :

Output
testing

Pour supprimer un espace de travail, vous devez d’abord détruire toutes les ressources déployées qui y sont associées. Ensuite, si c’est actif, vous devez passer à un autre en utilisant `workspace select`. Comme l’espace de travail `testing` ici est vide, vous pouvez passer directement à `default` :

  1. terraform workspace select default

Vous recevrez une sortie de Terraform confirmant le passage :

Output
Switched to workspace "default".

Vous pouvez ensuite le supprimer en exécutant `workspace delete` :

  1. terraform workspace delete testing

Terraform effectuera ensuite la suppression :

Output
Deleted workspace "testing"!

Vous pouvez détruire le Droplet que vous avez déployé dans l’espace de travail `default` en exécutant :

  1. terraform destroy -var "do_token=${DO_PAT}"

Entrez `yes` lors de l’invite pour terminer le processus.

Dans cette section, vous avez travaillé dans plusieurs espaces de travail de Terraform. Dans la prochaine section, vous déployerez une ressource avec état.

Déploiement de Ressources avec État

Les ressources stateless ne stockent pas de données, vous pouvez donc les créer et les remplacer rapidement car elles ne sont pas uniques. En revanche, les ressources stateful contiennent des données qui sont uniques ou non simplement recréables, et donc, elles nécessitent un stockage de données persistant.

Comme vous pourriez finalement détruire de telles ressources ou si plusieurs ressources ont besoin de leurs données, il est préférable de les stocker dans une entité distincte, comme par exemple DigitalOcean Volumes.

Les volumes offrent des espaces de stockage supplémentaires. Ils peuvent être branchés sur des serveurs Droplets, mais ils sont indépendants d’eux. Dans cette étape, vous définirez le Volume et le connecterez à un Droplet dans droplets.tf.

Ouvrez-le pour l’édition :

  1. nano droplets.tf

Ajoutez les lignes suivantes :

resource "digitalocean_droplet" "web" {
  image  = "ubuntu-18-04-x64"
  name   = "web-${terraform.workspace}"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

resource "digitalocean_volume" "volume" {
  region                  = "fra1"
  name                    = "new-volume"
  size                    = 10
  initial_filesystem_type = "ext4"
  description             = "New Volume for Droplet"
}

resource "digitalocean_volume_attachment" "volume_attachment" {
  droplet_id = digitalocean_droplet.web.id
  volume_id  = digitalocean_volume.volume.id
}

Voici où vous définissez deux nouvelles ressources, le Volume en tant que tel et une attache de volume. Le Volume sera de 10GO, formaté en ext4, nommé new-volume, et situé dans la même région que le Droplet. Comme le Volume et le Droplet sont des entités distinctes, vous devrez définir un objet d’attache de volume pour les connecter. volume_attachment prend les ID du Droplet et du Volume et donne des instructions au cloud DigitalOcean de rendre le Volume accessible au Droplet en tant que périphérique disque.

Une fois terminé, enregistrez et fermez le fichier.

Planifiez cette configuration en exécutant :

  1. terraform plan -var "do_token=${DO_PAT}"

Les actions que Terraform plane seront les suivantes :

Output
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.web sera créé + resource "digitalocean_droplet" "web" { + backups = false + created_at = (known after apply) + disk = (known after apply) + id = (known after apply) + image = "ubuntu-18-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + ipv6_address_private = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-default" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } # digitalocean_volume.volume sera créé + resource "digitalocean_volume" "volume" { + description = "New Volume for Droplet" + droplet_ids = (known after apply) + filesystem_label = (known after apply) + filesystem_type = (known after apply) + id = (known after apply) + initial_filesystem_type = "ext4" + name = "new-volume" + region = "fra1" + size = 10 + urn = (known after apply) } # digitalocean_volume_attachment.volume_attachment sera créé + resource "digitalocean_volume_attachment" "volume_attachment" { + droplet_id = (known after apply) + id = (known after apply) + volume_id = (known after apply) } Plan: 3 to add, 0 to change, 0 to destroy. ...

Les détails de sortie montrent que Terraform créera un Droplet, un Volume et une attache de volume, ce qui connecte le Volume au Droplet.

Vous avez maintenant défini et connecté un Volume (une ressource étatique) à un Droplet. Dans la prochaine section, vous verrez les modules Terraform publics et pré-faites que vous pouvez intégrer à votre projet.

Reférencer des modules prédéfinis

Outre la création de vos propres modules personnalisés pour vos projets, vous pouvez également utiliser des modules et fournisseurs prédéfinis d’autres développeurs, accessibles au public sur le registre Terraform.

Dans la section Modules, vous pouvez rechercher dans la base de données des modules disponibles et trier par fournisseur afin de trouver le module doté de la fonctionnalité nécessaire. Une fois trouvé, vous pouvez lire sa description, qui liste les entrées et sorties que le module offre, ainsi que ses dépendances externes de modules et de fournisseurs.

Vous allez maintenant ajouter le module de clé SSH DigitalOcean à votre projet. Vous stockeriez le code à part des définitions existantes dans un fichier nommé ssh-key.tf. Créez-le et ouvrez-le en édition en exécutant :

  1. nano ssh-key.tf

Ajoutez les lignes suivantes :

module "ssh-key" {
  source         = "clouddrove/ssh-key/digitalocean"
  key_path       = "~/.ssh/id_rsa.pub"
  key_name       = "new-ssh-key"
  enable_ssh_key = true
}

Ce code définit une instance du module clouddrove/droplet/digitalocean à partir du registre et défini certains des paramètres qu’il offre. Il devrait ajouter une clé SSH publique à votre compte en la lisant à partir de ~/.ssh/id_rsa.pub.

Une fois que vous avez terminé, enregistrez et fermez le fichier.

Avant de planifier ce code, vous devez télécharger le module référencé en exécutant :

  1. terraform init

Vous recevrez une sortie similaire à celle-ci :

Output
Initializing modules... Downloading clouddrove/ssh-key/digitalocean 0.13.0 for ssh-key... - ssh-key in .terraform/modules/ssh-key Initializing the backend... Initializing provider plugins... - Reusing previous version of digitalocean/digitalocean from the dependency lock file - Using previously-installed digitalocean/digitalocean v2.10.1 Terraform has been successfully initialized! ...

Vous pouvez maintenant planifier le code pour les modifications :

  1. terraform plan -var "do_token=${DO_PAT}"

Vous recevrez une sortie similaire à celle-ci :

Output
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: ... # module.ssh-key.digitalocean_ssh_key.default[0] sera créé + resource "digitalocean_ssh_key" "default" { + fingerprint = (known after apply) + id = (known after apply) + name = "devops" + public_key = "ssh-rsa ... demo@clouddrove" } Plan: 4 to add, 0 to change, 0 to destroy. ...

La sortie montre que vous allez créer la ressource de clé SSH, ce qui signifie que vous avez téléchargé et invoqué le module à partir de votre code.

Conclusion

Les projets plus grands peuvent faire usage de fonctionnalités avancées que Terraform offre pour aider à réduire la complexité et faciliter la maintenance. Les espaces de travail vous permettent de tester de nouvelles ajouts à votre code sans toucher aux déploiements principaux stables. Vous pouvez également associer les espaces de travail à un système de contrôle de version pour suivre les modifications du code. L’utilisation de modules prêts à l’emploi peut également raccourcir le temps de développement, mais peut entraîner des coûts ou des temps supplémentaires à l’avenir si le module devient obsolète.

Ce tutoriel fait partie de la série Comment Gérer l’Infrastructure avec Terraform. La série couvre un certain nombre de sujets Terraform, depuis l’installation de Terraform pour la première fois jusqu’à la gestion de projets complexes.

Source:
https://www.digitalocean.com/community/tutorials/how-to-deploy-multiple-environments-with-workspaces-in-your-terraform-project