Aller au contenu
Guivin
Retour

Gérer l'infrastructure et la configuration ensemble : Terraform rencontre Ansible

Modifier la page

Terraform excelle dans le provisionnement de l’infrastructure. Ansible excelle dans sa configuration. Ensemble, ils couvrent tout le spectre de l’automatisation — mais les intégrations traditionnelles via local-exec peuvent vite devenir complexes et difficiles à faire évoluer.

C’est là qu’intervient le Terraform Ansible Provider : une façon plus propre et plus fluide de connecter les deux outils.

Dans cet article, nous allons déployer un serveur NGINX sur DigitalOcean en utilisant ce provider — en unifiant le provisionnement de l’infrastructure et sa configuration dans un seul workflow.

Prérequis

Installer la collection Ansible cloud.terraform :

ansible-galaxy collection install cloud.terraform

Relier Terraform et Ansible : la configuration de l’inventaire simplifiée

Le plugin cloud.terraform.terraform_provider fait le pont entre Terraform et Ansible en permettant à Ansible d’interagir directement avec l’infrastructure définie dans votre état Terraform. Cette intégration garantit la cohérence entre les deux outils en générant dynamiquement un inventaire Ansible à partir de l’état Terraform courant.

Voici à quoi ressemble le fichier inventory.yml :

---
plugin: cloud.terraform.terraform_provider

Écriture du code Terraform

La configuration Terraform suivante provisionne une infrastructure sur DigitalOcean et l’intègre directement avec Ansible via le Terraform Ansible provider. Elle définit :

terraform {
  required_providers {
    ansible = {
      source  = "ansible/ansible"
      version = "1.3.0"
    }

    digitalocean = {
      source  = "digitalocean/digitalocean"
      version = "2.45.0"
    }
  }
}

variable "do_token" {
  description = "Token to authenticate to DigitalOcean"
  type        = string
  sensitive   = true
}

resource "digitalocean_ssh_key" "default" {
  name       = "Terraform Example"
  public_key = file(pathexpand("~/.ssh/id_rsa.pub"))
}

resource "digitalocean_droplet" "web1" {
  name     = "web1"
  image    = "ubuntu-24-10-x64"
  region   = "nyc2"
  size     = "s-1vcpu-1gb"
  backups  = false
  ssh_keys = [digitalocean_ssh_key.default.fingerprint]
}

resource "ansible_host" "web1" {
  name   = digitalocean_droplet.web1.ipv4_address
  groups = ["webservers"]
  variables = {
    ansible_user                 = "root"
    ansible_ssh_private_key_file = "~/.ssh/id_rsa"
    ansible_python_interpreter   = "/usr/bin/python3"
    ansible_ssh_common_args      = "-o StrictHostKeyChecking=no"
  }
}

output "ipv4_address" {
  value = digitalocean_droplet.web1.ipv4_address
}

Appliquer le code Terraform avec votre token DigitalOcean :

$ read -s DO_TOKEN
$ terraform apply -var "do_token=$DO_TOKEN"

Visualiser l’inventaire dynamique Ansible généré par Terraform

Après avoir provisionné votre infrastructure et généré l’inventaire Ansible via Terraform, vous pouvez visualiser sa structure et les variables associées avec cette commande :

$ ansible-inventory -i inventory.yml --graph --vars

Ce que vous voyez expliqué

Sous le groupe @webservers, l’hôte 162.243.103.221 a plusieurs variables attachées :

Pourquoi c’est utile

Cette sortie graphique vous aide à :

Appliquer le playbook Ansible avec l’inventaire généré par Terraform

Une fois l’infrastructure provisionnée et l’inventaire dynamique prêt, vous pouvez exécuter votre playbook Ansible directement en utilisant le fichier inventory.yml généré par Terraform :

ansible-playbook playbook.yml -i inventory.yml

Cette commande exécute le playbook sur l’infrastructure provisionnée. Dans cet exemple, le playbook :

  1. Collecte les facts sur l’hôte cible.
  2. Installe le paquet NGINX s’il n’est pas déjà présent.
  3. S’assure que le service NGINX est démarré et activé au démarrage.

Exemples de sorties

PLAY [Webservers] *************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************
ok: [162.243.103.221]

TASK [Ensure NGINX package is present.] ***************************************************************************
changed: [162.243.103.221]

TASK [Ensure NGINX is started and enabled.] ***********************************************************************
ok: [162.243.103.221]

PLAY RECAP ********************************************************************************************************
162.243.103.221            : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Vérifier le déploiement

Vous pouvez vous connecter en SSH au serveur et vérifier que NGINX fonctionne correctement :

HOSTNAME=$(terraform output -json | jq -r .ipv4_address.value)
ssh root@$HOSTNAME

Une fois connecté :

systemctl status nginx

Exemple de sortie de statut :

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Wed 2024-12-04 10:51:51 UTC; 1min 29s ago
   Main PID: 2441 (nginx)
      Tasks: 2 (limit: 1110)
     Memory: 2.1M (peak: 2.3M)
        CPU: 26ms
     CGroup: /system.slice/nginx.service
             ├─2441 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             └─2442 "nginx: worker process"

Cela confirme que votre playbook a été appliqué avec succès et que le service NGINX fonctionne sur votre serveur nouvellement provisionné.

Conclusion

Dans cet article, nous avons exploré comment intégrer de manière fluide Terraform et Ansible via le Terraform Ansible provider pour automatiser à la fois le provisionnement de l’infrastructure et la gestion de la configuration.

En tirant parti de cette intégration :

Cette approche élimine le besoin de gestion manuelle des inventaires et garantit la cohérence entre provisionnement et configuration.

Le code complet est sur GitHub : terraform-ansible-integration-101


Modifier la page

Article précédent
Recording rules : la feature Prometheus que j'aurais dû connaître bien plus tôt
Article suivant
DIY : Surveiller la température et l'humidité avec DHT22/AM2302 et Prometheus