Comment utiliser Terraform avec DigitalOcean

introduction

Terraform est un outil permettant de créer et de gérer des infrastructures de manière organisée. Il peut être utilisé pour gérer les gouttelettes DigitalOcean et les entrées DNS, en plus d’une grande variété de services offerts par d’autres fournisseurs. Il est contrôlé via une interface de ligne de commande facile à utiliser et peut être exécuté à partir de votre bureau ou d’un serveur distant.

Terraform fonctionne en lisant des fichiers de configuration décrivant les composants qui constituent votre environnement d’application ou votre centre de données. Sur la base de la configuration, il génère un plan d’exécution, décrivant ce qu’il va faire pour atteindre l’état souhaité. Le plan est ensuite exécuté pour construire l’infrastructure. Lorsque des modifications sont apportées à la configuration, Terraform peut générer et exécuter des plans incrémentiels pour mettre à jour l’infrastructure existante à l’état nouvellement décrit.

Dans ce didacticiel, nous allons montrer comment utiliser Terraform pour créer une infrastructure simple composée de deux serveurs Nginx équilibrés par un serveur HAProxy (voir image ci-dessous). Cela devrait vous aider à commencer à utiliser Terraform et à vous donner une idée de la manière dont il peut être utilisé pour gérer et déployer une infrastructure basée sur DigitalOcean qui répond à vos propres besoins.

image: https: //assets.digitalocean.com/articles/terraform/terraform_example.png [Exemple d’infrastructure]

Voyons ce dont vous avez besoin pour suivre ce tutoriel.

Conditions préalables

Compte DigitalOcean

Comme ce didacticiel est axé sur l’utilisation du fournisseur DigitalOcean de Terraform, vous devez disposer d’un compte DigitalOcean valide. Si vous n’en avez pas, register here.

Jeton d’API DigitalOcean

Générez un jeton d’accès personnel via le panneau de commande DigitalOcean. Les instructions pour le faire peuvent être trouvées dans ce lien: Comment générer un jeton d’accès personnel.

Dans chaque terminal sur lequel vous exécuterez Terraform, exportez votre jeton DigitalOcean Personal Access:

export DO_PAT=

Terraform utilisera ce jeton pour s’authentifier auprès de l’API DigitalOcean et contrôler votre compte. Gardez cela privé!

Ajouter une clé SSH sans mot de passe au nuage DigitalOcean

Si vous n’avez pas encore ajouté de clé SSH sans mot de passe à votre compte DigitalOcean, procédez comme suit: https://www.digitalocean.com/community/tutorials/how-to-use-ssh-keys-with-digitalocean-droplets [ce tutoriel].

En supposant que votre clé privée se trouve sur + ~ / .ssh / id_rsa +, utilisez la commande suivante pour obtenir l’empreinte MD5 de votre clé publique:

ssh-keygen -E md5 -lf ~/.ssh/id_rsa.pub | awk '{print $2}'

Cela produira quelque chose comme ce qui suit:

md5:

Vous devrez fournir cette empreinte, moins le préfixe + md5: +, lors de l’exécution de Terraform, comme suit (en remplaçant tous les mots en surbrillance par leurs valeurs appropriées):

terraform plan \
 -var "do_token=${DO_PAT}" \
 -var "pub_key=/.ssh/id_rsa.pub" \
 -var "pvt_key=/.ssh/id_rsa" \
 -var "ssh_fingerprint="

Maintenant que les conditions préalables sont remplies, installons Terraform!

Installer Terraform

  • Remarque: * Ce tutoriel a été écrit avec Terraform 0.1.1.

Terraform est très facile à installer et peut s’exécuter sur votre bureau ou sur un serveur distant. Voici les étapes:

[[1-download-terraform]] ===== 1. Téléchargez Terraform

Téléchargez le package correspondant à votre système d’exploitation et à votre architecture: Download Terraform

[[2-extract-terraform]] ===== 2. Extraire Terraform

Extrayez le package que vous venez de télécharger dans le répertoire de votre choix.

Si vous l’avez téléchargé sur + ~ / Downloads +, vous pouvez exécuter les commandes suivantes pour extraire:

mkdir -p
unzip ~/Downloads/terraform_0.1.1_darwin_amd64.zip -d

Cela désarchive le paquet dans le répertoire + opt / terraform / +, dans votre répertoire personnel.

[[3-add-path-to-profile]] ===== 3. Ajouter un chemin au profil

La dernière étape consiste à ajouter le répertoire bin de Terraform, + ~ / opt / terraform / bin +, à la variable d’environnement PATH pour faciliter l’accès.

Par exemple, si vous utilisez bash comme shell, vous pouvez ajouter le chemin d’accès à votre + .bash_profile +. Ouvrez votre profil pour le modifier:

vi ~/.bash_profile

Pour ajouter le chemin de Terraform à votre PATH, ajoutez la ligne suivante à la fin du fichier:

export PATH=$PATH:

Sauvegarder et quitter.

Désormais, toutes vos nouvelles sessions bash pourront trouver la commande + terraform +. Si vous souhaitez charger le nouveau PATH dans votre session actuelle, tapez ce qui suit:

. .bash_profile

Vérifier l’installation de Terraform

Pour vérifier que vous avez correctement installé Terraform, essayez de l’exécuter. Dans un terminal, lancez Terraform:

terraform

Si votre chemin est correctement configuré, vous verrez une sortie semblable à celle-ci:

Available commands are:
   apply      Builds or changes infrastructure
   graph      Create a visual graph of Terraform resources
   output     Read an output from a state file
   plan       Generate and show an execution plan
   refresh    Update local state file against real resources
   show       Inspect Terraform state or plan
   version    Prints the Terraform version

Ce sont les commandes que Terraform accepte. Leur mémoire est décrit ici, mais nous verrons plus tard comment les utiliser.

Maintenant que Terraform est installé, commençons par écrire une configuration pour décrire notre infrastructure!

Créer un répertoire de configuration

La première étape de la construction d’une infrastructure avec Terraform consiste à créer un répertoire qui stockera nos fichiers de configuration pour un projet donné. Le nom du répertoire n’a pas d’importance, mais nous allons utiliser «loadbalance» pour l’exemple (n’hésitez pas à changer son nom):

mkdir

Les configurations Terraform sont des fichiers texte qui se terminent par l’extension de fichier + .tf +. Ils sont lisibles par l’homme et soutiennent les commentaires. Terraform prend également en charge les fichiers de configuration au format JSON, mais nous ne les couvrirons pas ici. Terraform lira tous les fichiers de configuration de votre répertoire de travail de manière déclarative. Par conséquent, l’ordre des définitions de ressources et de variables importera peu. Toute votre infrastructure peut exister dans un seul fichier de configuration, mais nous allons séparer nos fichiers de configuration par les ressources de ce tutoriel.

Remplacez votre répertoire actuel par le répertoire nouvellement créé:

cd

A partir de maintenant, nous supposerons que votre répertoire de travail est celui que nous venons de changer. Si vous démarrez une nouvelle session de terminal, veillez à modifier le répertoire contenant votre configuration Terraform.

Si vous êtes coincé

Si vous êtes bloqué et que Terraform ne fonctionne pas comme prévu, vous pouvez recommencer en supprimant le fichier + terraform.tfstate + et en détruisant manuellement les ressources créées (par exemple, via le panneau de configuration ou un autre outil d’API tel que Tugboat).

Vous pouvez également activer la journalisation sur stdout afin de voir ce que Terraform essaie de faire. Faites cela en lançant la commande suivante:

export TF_LOG=1

De plus, si vous ne parvenez pas à créer une configuration fonctionnelle, les fichiers de configuration complets sont disponibles dans le GistHub Gist suivant: Configuration Files.

Passons maintenant à la création d’une configuration Terraform.

Créer une configuration de fournisseur

Terraform soutient divers fournisseurs de services par l’intermédiaire de «fournisseurs» livrés avec elle. Nous sommes intéressés par le fournisseur DigitalOcean, que Terraform utilisera pour interagir avec l’API DigitalOcean afin de construire notre infrastructure. La première étape pour utiliser le fournisseur DigitalOcean consiste à le configurer avec les variables d’identification appropriées. Faisons-le maintenant.

Créez un fichier nommé + provider.tf +:

vi provider.tf

Ajoutez les lignes suivantes dans le fichier:

variable "do_token" {}
variable "pub_key" {}
variable "pvt_key" {}
variable "ssh_fingerprint" {}

provider "digitalocean" {
 token = "${var.do_token}"
}

Sauvegarder et quitter. Voici une ventilation des quatre premières lignes:

  • * variable “do_token” *: votre jeton d’accès personnel DigitalOcean

  • * variable “pub_key” *: emplacement de la clé publique, permettant son installation dans de nouvelles gouttelettes

  • * variable “pvt_key” *: emplacement de la clé privée, afin que Terraform puisse se connecter à de nouvelles gouttelettes

  • * variable “ssh_fingerprint” *: empreinte de la clé SSH

Les lignes suivantes spécifient les informations d’identification de votre compte DigitalOcean en attribuant un «jeton» à la variable do_token. Nous transmettrons les valeurs de ces variables à Terraform lors de son exécution.

La documentation officielle Terraform du fournisseur DigitalOcean se trouve à l’adresse suivante: DigitalOcean Provider.

Ressources DigitalOcean

Chaque fournisseur a ses propres spécifications, qui correspondent généralement à l’API de son fournisseur de services respectif. Dans le cas du fournisseur DigitalOcean, nous pouvons définir trois types de ressources:

  • * digitalocean_domain *: entrées de domaine DNS

  • * digitalocean_droplet *: Droplets (i.e. VPS ou serveurs)

  • * digitalocean_record *: enregistrements DNS

Commençons par créer un droplet qui exécutera un serveur Nginx.

Décrire le premier serveur Nginx

Créez un nouveau fichier de configuration Terraform appelé + www-1.tf +:

vi www-1.tf

Insérez les lignes suivantes pour définir la ressource de droplet:

resource "digitalocean_droplet" "www-1" {
   image = "ubuntu-14-04-x64"
   name = "www-1"
   region = "nyc2"
   size = "512mb"
   private_networking = true
   ssh_keys = [
     "${var.ssh_fingerprint}"
   ]

Dans la configuration ci-dessus, la première ligne définit une ressource digitalocean_droplet nommée «www-1». Les autres lignes spécifient les attributs du droplet, accessibles via l’API DigitalOcean. Tout le reste est assez explicite, nous n’expliquerons donc pas chaque ligne. En outre, Terraform collectera diverses informations sur le droplet, telles que ses adresses IP publique et privée, qui peuvent être utilisées par d’autres ressources de votre configuration.

Si vous vous demandez quels arguments sont obligatoires ou facultatifs pour une ressource Droplet, veuillez vous reporter à la documentation officielle de Terraform: DigitalOcean Droplet Specification.

Nous allons maintenant configurer une + connexion + que Terraform peut utiliser pour se connecter au serveur via SSH. Insérez les lignes suivantes à la fin du fichier:

 connection {
     user = "root"
     type = "ssh"
     private_key = "${file(var.pvt_key)}"
     timeout = "2m"
 }

Ces lignes décrivent la manière dont Terraform doit se connecter au serveur, au cas où nous souhaiterions provisionner quoi que ce soit sur SSH (notez l’utilisation de la variable de clé privée).

Maintenant que la connexion est configurée, nous pouvons configurer le provisioner «remote-exec». Nous allons utiliser le provisioner Remote-Ex pour installer Nginx. Ajoutez les lignes suivantes à la configuration pour faire exactement cela:

 provisioner "remote-exec" {
   inline = [
     "export PATH=$PATH:/usr/bin",
     # install nginx
     "sudo apt-get update",
     "sudo apt-get -y install nginx"
   ]
 }
}

Sauvegarder et quitter.

Notez que les chaînes du tableau inline sont les commandes que root exécutera pour installer Nginx.

Exécutez Terraform pour créer un serveur Nginx

Actuellement, votre configuration Terraform décrit un seul serveur Nginx. Laissez-le tester.

Tout d’abord, initialisez Terraform pour votre projet. Cela lira vos fichiers de configuration et installera les plugins pour votre fournisseur:

terraform init

Vous verrez cette sortie:

OutputInitializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...                                                           - Downloading plugin for provider "digitalocean" (0.1.2)...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.digitalocean: version = "~> 0.1"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other                                                          commands will detect it and remind you to do so if necessary.

Ensuite, exécutez la commande + terraform plan + suivante pour voir ce que Terraform tentera de faire pour construire l’infrastructure que vous avez décrite (c.-à-d. voir le plan d’exécution). Vous devrez spécifier les valeurs de toutes les variables énumérées ci-dessous:

terraform plan \
 -var "do_token=${DO_PAT}" \
 -var "pub_key=/.ssh/id_rsa.pub" \
 -var "pvt_key=/.ssh/id_rsa" \
 -var "ssh_fingerprint="

Si toutes vos variables sont définies correctement, vous devriez voir plusieurs lignes de sortie, y compris les lignes suivantes:

Refreshing Terraform state prior to plan...
...
+ digitalocean_droplet.www-1
...

La ligne verte ++ digitalocean_droplet.www-1 + signifie que Terraform créera une nouvelle ressource de gouttelette appelée «www-1», avec les détails qui la suivent. C’est exactement ce que nous voulons, alors exécutons le plan. Exécutez la commande + terraform apply + suivante pour exécuter le plan en cours. De nouveau, spécifiez toutes les valeurs pour les variables ci-dessous:

terraform apply \
 -var "do_token=${DO_PAT}" \
 -var "pub_key=/.ssh/id_rsa.pub" \
 -var "pvt_key=/.ssh/id_rsa" \
 -var "ssh_fingerprint="

Vous devriez voir une sortie contenant les lignes suivantes (tronquées par souci de brièveté):

digitalocean_droplet.www-1: Creating...
...

digitalocean_droplet.www-1: Provisioning with 'remote-exec'...
digitalocean_droplet.www-1: Creation complete

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
...

À ce stade, Terraform a créé un nouveau droplet appelé + www-1 + et y a installé Nginx. Si vous visitez l’adresse IP publique de votre nouveau Droplet, l’écran d’accueil de Nginx s’affiche.

Décrire le deuxième serveur Nginx

Maintenant que vous avez décrit un serveur Nginx, il est très facile d’en ajouter un deuxième. Copions simplement le fichier de configuration d’origine et remplaçons le nom (et le nom d’hôte) de la ressource de droplet.

Vous pouvez le faire manuellement ou utiliser + sed + pour remplacer toutes les instances de + www-1 + par + www-2 + (il y en a deux) et créer un nouveau fichier. Voici la commande + sed + pour le faire:

sed 's/www-1/www-2/g' www-1.tf > www-2.tf

Maintenant, si vous exécutez à nouveau + terraform plan + ou + + terraform apply +, il affichera ou exécutera le nouveau plan, respectivement. Puisque nous savons déjà que Terraform créera simplement un autre droplet Nginx, sauvegardons-le pour plus tard.

Configurons maintenant notre droplet HAProxy.

Décrire le serveur HAProxy

Créez un nouveau fichier de configuration Terraform appelé + haproxy-www.tf +:

vi haproxy-www.tf

Insérez les lignes suivantes pour décrire le nouveau droplet. La première partie est identique aux descriptions des droplets Nginx, à la différence qu’elle porte un nom différent, «haproxy-www»:

resource "digitalocean_droplet" "haproxy-www" {
   image = "ubuntu-16-04-x64"
   name = "haproxy-www"
   region = "nyc2"
   size = "512mb"
   private_networking = true
   ssh_keys = [
     "${var.ssh_fingerprint}"
   ]

Insérez les informations de connexion suivantes (identiques, encore une fois, aux droplets de Nginx):

 connection {
     user = "root"
     type = "ssh"
     private_key = "${file(var.pvt_key)}"
     timeout = "2m"
 }

Maintenant que la connexion est configurée, nous pouvons configurer le provisioner «remote-exec». Nous allons utiliser le provisioner Remote-Ex pour installer et configurer HAProxy. Ajoutez les lignes suivantes à la configuration pour faire exactement cela:

 provisioner "remote-exec" {
   inline = [
     "export PATH=$PATH:/usr/bin",
     # install haproxy 1.5
     "sudo add-apt-repository -y ppa:vbernat/haproxy-1.5",
     "sudo apt-get update",
     "sudo apt-get -y install haproxy",

     # download haproxy conf
     "sudo wget https://gist.githubusercontent.com/thisismitch/91815a582c27bd8aa44d/raw/8fc59b7cb88a2be9b802cd76288ca1c2ea957dd9/haproxy.cfg -O /etc/haproxy/haproxy.cfg",

     # replace ip address variables in haproxy conf to use droplet ip addresses
     "sudo sed -i 's/HAPROXY_PUBLIC_IP//g' /etc/haproxy/haproxy.cfg",
     "sudo sed -i 's/WWW_1_PRIVATE_IP//g' /etc/haproxy/haproxy.cfg",
     "sudo sed -i 's/WWW_2_PRIVATE_IP//g' /etc/haproxy/haproxy.cfg",

     # restart haproxy to load changes
     "sudo service haproxy restart"
   ]
 }
}

Sauvegarder et quitter.

De nouveau, les chaînes du tableau inline sont des commandes que root exécutera pour installer et configurer HAProxy. Après l’installation de HAProxy, un fichier https://gist.githubusercontent.com/thisismitch/91815a582c27abaaaa44d/raw/8fc59b7cb88a2be9b802cd76288ca1c2ea957dd9/haproxy.cfgenchshappa) est téléchargé. À ce stade, la commande + sed + remplace certaines chaînes du fichier de configuration HAProxy par les adresses IP appropriées de chaque droplet, en utilisant des variables Terraform (surlignées en rouge ci-dessus). HAProxy sera prêt à fonctionner dès que il est provisionné. Enfin, HAProxy est redémarré pour charger les modifications de configuration.

Dans un cas plus pratique, vous pouvez avoir votre propre fichier haproxy.cfg sur votre système Terraform, que vous pouvez copier sur votre serveur avec le provisioner «fichier».

Notre serveur HAProxy est maintenant décrit, mais nous devons exécuter Terraform pour le construire.

Exécutez Terraform pour créer un serveur HAProxy

Actuellement, votre configuration Terraform décrit deux serveurs Nginx et un serveur HAProxy. Voyons

Exécutez à nouveau la commande + terraform plan + pour voir le nouveau plan d’exécution:

terraform plan \
 -var "do_token=${DO_PAT}" \
 -var "pub_key=/.ssh/id_rsa.pub" \
 -var "pvt_key=/.ssh/id_rsa" \
 -var "ssh_fingerprint="

Vous devriez voir plusieurs lignes de sortie, y compris les lignes suivantes:

...
digitalocean_droplet.www-1: Refreshing state... (ID: 2236747)
...
+ digitalocean_droplet.haproxy-www
...
+ digitalocean_droplet.www-2
...

Cela signifie que le droplet www-1 existe déjà et que Terraform créera les droplets haproxy-www et www-2. Lançons + terraform apply + pour construire les composants restants:

terraform apply \
 -var "do_token=${DO_PAT}" \
 -var "pub_key=/.ssh/id_rsa.pub" \
 -var "pvt_key=/.ssh/id_rsa" \
 -var "ssh_fingerprint="

Vous devriez voir une sortie contenant les lignes suivantes (tronquées par souci de brièveté):

digitalocean_droplet.www-2: Creating...
...
digitalocean_droplet.www-2: Provisioning with 'remote-exec'...
digitalocean_droplet.www-2: Creation complete
...
digitalocean_droplet.haproxy-www: Creating...
...
digitalocean_droplet.haproxy-www: Provisioning with 'remote-exec'...
digitalocean_droplet.haproxy-www: Creation complete
...
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
...

À ce stade, Terraform a créé un nouveau serveur Nginx et un nouveau serveur HAProxy. Si vous visitez l’adresse IP publique de haproxy-www, vous devriez voir un écran de bienvenue Nginx (car HAProxy est en train d’équilibrer la charge des deux serveurs Nginx).

  • Votre configuration est terminée! * La suite du didacticiel contient des informations sur la configuration du domaine DNS et des ressources d’enregistrement avec Terraform, ainsi que des informations sur l’utilisation des autres commandes Terraform.

Création de domaines et enregistrements DNS

Comme mentionné précédemment, Terraform peut également créer un domaine DNS et enregistrer des domaines. Par exemple, si vous souhaitez diriger votre domaine + example.com + vers le serveur HAProxy que vous venez de créer, vous pouvez créer la configuration Terraform pour cela. * Remarque: * Utilisez votre propre nom de domaine unique ou cette étape échouera car (c.-à-d. n’utilisez pas “exemple.com” ou tout autre enregistrement existant déjà dans le DNS DigitalOcean)

Créez un nouveau fichier pour décrire votre DNS:

vi

Insérez la ressource de domaine suivante:

# Create a new domain record
resource "digitalocean_domain" "default" {
  name = ""
  ip_address = "${digitalocean_droplet.haproxy-www.ipv4_address}"
}

Et pendant que nous y sommes, ajoutons un enregistrement CNAME qui pointe ".example.com" vers "example.com":

resource "digitalocean_record" "CNAME-www" {
 domain = "${digitalocean_domain.default.name}"
 type = "CNAME"
 name = "www"
 value = "@"
}

Sauvegarder et quitter.

Pour ajouter les entrées DNS, exécutez + terraform plan + suivi de + terraform apply +, comme pour les autres ressources.

Autres commandes Terraform

Terraform a plusieurs autres commandes qui n’étaient pas couvertes auparavant, nous allons donc en passer la plupart ici.

Afficher l’état

Terraform met à jour le fichier d’état chaque fois qu’il exécute un plan ou "rafraîchit" son état. Notez que si vous modifiez votre infrastructure en dehors de Terraform, votre fichier d’état sera obsolète.

Pour afficher l’état actuel de votre environnement, utilisez la commande suivante:

terraform show terraform.tfstate

Etat de rafraîchissement

Si vos ressources sont modifiées en dehors de Terraform, vous pouvez actualiser le fichier d’état pour le mettre à jour. Cette commande extraira les informations de ressources mises à jour de vos fournisseurs:

terraform refresh \
 -var "do_token=${DO_PAT}" \
 -var "pub_key=/.ssh/id_rsa.pub" \
 -var "pvt_key=/.ssh/id_rsa" \
 -var "ssh_fingerprint="

Détruire les infrastructures

Bien que cela ne soit pas couramment utilisé dans les environnements de production, Terraform peut également détruire les infrastructures qu’il crée. Ceci est principalement utile dans les environnements de développement construits et détruits à plusieurs reprises. Ce processus en deux étapes est décrit ci-dessous.

[[1-create-an-execution-plan-to-destroy-the-infrastructure]] ===== 1. Créez un plan d’exécution pour détruire l’infrastructure:

terraform plan -destroy -out=terraform.tfplan \
 -var "do_token=${DO_PAT}" \
 -var "pub_key=/.ssh/id_rsa.pub" \
 -var "pvt_key=/.ssh/id_rsa" \
 -var "ssh_fingerprint="

Terraform affichera un plan avec les ressources marquées en rouge et précédé du signe moins, indiquant qu’il supprimera les ressources de votre infrastructure.

[[2-apply-destroy]] ===== 2. Appliquer détruire:

terraform apply terraform.tfplan

Terraform détruira les ressources, comme indiqué dans le plan de destruction.

Conclusion

Maintenant que vous avez compris le fonctionnement de Terraform, n’hésitez pas à créer des fichiers de configuration décrivant une infrastructure de serveur qui vous est utile. L’exemple d’installation est simple, mais montre à quel point il est facile d’automatiser le déploiement des serveurs. Si vous utilisez déjà des outils de gestion de la configuration, tels que Puppet ou Chef, vous pouvez appeler les utilisateurs des fournisseurs Terraform pour configurer des serveurs dans le cadre de leur processus de création.

Terraform a beaucoup plus de fonctionnalités et peut fonctionner avec d’autres fournisseurs. Consultez la Terraform Documentation officielle pour en savoir plus sur l’utilisation de Terraform pour améliorer votre propre infrastructure.

Related