Aller au contenu
English
Cloud medium

Ansible sur Scaleway : exploiter ce que Terraform a provisionné

35 min de lecture

Terraform provisionne, Ansible exploite : cette frontière décide de tout le reste. La collection stephrobert.scaleway, en version 0.5.0, ne contient aucun module de création ni de suppression, et c'est délibéré. Elle sert à piloter une flotte qui existe déjà : redémarrer, faire tourner une clé, ajuster une règle, lire un état. Cette leçon situe cette frontière, vous fait découvrir une flotte réelle par l'inventaire dynamique, sans écrire un seul nom de machine, et vous montre comment vérifier une idempotence en la rejouant au lieu de la croire sur parole. Elle clôt le volet Infrastructure as Code, sur l'infrastructure que les deux leçons précédentes ont construite.

  • Situer Ansible face à Terraform sur une infrastructure Scaleway.
  • Découvrir une flotte réelle avec l'inventaire dynamique, sans écrire un seul nom de machine.
  • Distinguer les trois familles de modules, et ce que chacune garantit.
  • Vérifier qu'un module est idempotent, en le rejouant.

Cette leçon ne réexplique pas Ansible : elle suppose acquis ce qui suit, et renvoie vers la formation correspondante plutôt que de la résumer.

  • Savoir écrire un playbook, lire un inventaire et ce que veut dire idempotent : c'est le programme de la formation Ansible du site.
  • ansible-core 2.20 ou plus récent, avec ansible-galaxy pour installer la collection, et le SDK Python scaleway accessible à l'interpréteur qu'utilise Ansible.
  • Une infrastructure Scaleway déjà provisionnée, par exemple celle de la leçon Terraform, et la CLI scw configurée sur le même profil.

Terraform ou Ansible : lequel possède la ressource ?

Section intitulée « Terraform ou Ansible : lequel possède la ressource ? »

Un outil décrit l'état voulu de ressources qu'il possède, l'autre agit sur des ressources qu'il ne possède pas. Confondre les deux produit la situation la plus pénible d'une infrastructure : deux outils qui se disputent la même ressource, chacun la ramenant à sa propre idée de l'état correct.

TerraformAnsible, avec cette collection
Ce qu'il faitcrée, modifie, détruitlit, déclenche, ajuste
Ce qu'il tientun état, qu'il compare au réelrien, il lit à chaque fois
La question qu'il pose« l'infrastructure correspond-elle au code ? »« cette ressource est-elle dans l'état voulu maintenant ? »
Ce qui casse si on l'oublieune ressource créée à la main disparaît au prochain applyrien : Ansible ne détruit pas ce qu'il n'a pas créé

La conséquence est visible dans le catalogue de la collection : aucun module ne crée ni ne supprime de ressource. Vous n'y trouverez pas instance_server_create. Vous y trouverez instance_server_action, qui redémarre une machine existante, et instance_server, qui en ajuste les propriétés.

Comment installer la collection Ansible Scaleway ?

Section intitulée « Comment installer la collection Ansible Scaleway ? »

Deux commandes, et une dépendance qu'on oublie. La collection s'appuie sur le SDK Python de Scaleway, qui n'est pas tiré automatiquement.

Fenêtre de terminal
ansible-galaxy collection install stephrobert.scaleway
pip install 'scaleway>=2.9.0'

Sans le SDK, le premier module joué échoue avec un message explicite qui nomme l'interpréteur Python utilisé, ce qui est la bonne piste dans neuf cas sur dix :

Failed to import the required Python library (scaleway) on … Python …/bin/python

Les identifiants se lisent dans trois sources, et l'ordre compte :

paramètre du module > variable d'environnement > fichier de configuration scw

Comment découvrir une flotte Scaleway avec l'inventaire dynamique ?

Section intitulée « Comment découvrir une flotte Scaleway avec l'inventaire dynamique ? »

L'inventaire dynamique interroge l'API et construit les groupes tout seul. C'est le premier bénéfice concret, et il se voit sur un fichier de quatre lignes.

production.scaleway.yml
plugin: stephrobert.scaleway.compute
products: [instance]
group_by: [product, zone, tags]
Fenêtre de terminal
ansible-inventory -i production.scaleway.yml --list

Sur une flotte réelle de six machines, le résultat donne :

groupes : all, scw_product_instance, scw_tag_app, scw_tag_bastion,
scw_tag_platform, scw_tag_web, scw_zone_fr_par_1
hôtes : 6

Les étiquettes posées sur les machines deviennent des groupes, ce qui permet d'écrire hosts: scw_tag_web sans tenir aucune liste. Chaque hôte porte ses variables, dont celles-ci, les plus utiles au quotidien :

VariableCe qu'elle contient
scaleway_idl'identifiant de la ressource, celui qu'attendent les modules
scaleway_private_ipv4les adresses privées, sous forme de liste
scaleway_private_networksle rattachement réseau, avec l'identifiant de chaque réseau
scaleway_address_sourcepourquoi cette adresse a été choisie comme ansible_host
scaleway_public_ipv4vide sur une machine sans adresse publique, ce qui est le cas normal

scaleway_address_source mérite d'être connue. Elle explique le choix du plugin plutôt que de le subir : sur une machine sans adresse publique, elle vaut private_ipv4, et vous savez immédiatement que votre playbook devra passer par un rebond.

Le suffixe du module dit ce qu'il fait, et surtout ce qu'il promet.

FamilleSuffixeCe qu'elle faitCe qu'elle garantit
Information_infolit et rend l'étatne signale jamais de changement
Action_actiondéclenche une opération ponctuellechanged dès que l'API a accepté
Gestion d'étatsans suffixeajuste les propriétéslit d'abord, n'écrit que la différence

La troisième est celle qui porte l'idempotence, et c'est celle qu'il faut éprouver.

Comment vérifier qu'un module Ansible est vraiment idempotent ?

Section intitulée « Comment vérifier qu'un module Ansible est vraiment idempotent ? »

Un module qui se dit idempotent se vérifie en le rejouant. La promesse de la documentation est explicite : « le module lit la ressource d'abord et n'écrit que les champs qui diffèrent, donc une seconde exécution ne signale aucun changement ».

  1. Écrivez un playbook qui ajuste une propriété

    - hosts: localhost
    gather_facts: false
    tasks:
    - stephrobert.scaleway.instance_security_group:
    security_group_id: "{{ groupe_id }}"
    zone: fr-par-1
    description: "piloté par ansible"
  2. Jouez-le trois fois de suite

    Fenêtre de terminal
    for i in 1 2 3; do ansible-playbook ajuster.yml | grep -oE 'changed=[0-9]+'; done

    Le résultat mesuré est celui qu'on attend, et c'est la seule preuve qui vaille :

    changed=1
    changed=0
    changed=0
  3. Vérifiez le mode répétition quand il n'y a plus rien à faire

    Fenêtre de terminal
    ansible-playbook --check ajuster.yml

    Il rend changed=0, et non un changement fantôme. C'est ce qui rend --check utilisable pour prévisualiser une intervention.

  4. Regardez le diff sur une valeur réellement différente

    Fenêtre de terminal
    ansible-playbook --check --diff ajuster.yml
    --- before
    +++ after
    @@ -1,3 +1,3 @@
    {
    - "description": "piloté par ansible"
    + "description": "valeur modifiee"
    }

Trois passages, pas deux. Le deuxième prouve que la comparaison fonctionne ; le troisième prouve que le deuxième n'était pas un hasard de cache.

Quelles garanties la collection donne-t-elle, module par module ?

Section intitulée « Quelles garanties la collection donne-t-elle, module par module ? »

Chaque module déclare ce qu'il sait faire, et Ansible publie cette déclaration sur sa page. C'est vérifiable sans rien exécuter, et c'est la première chose à regarder avant d'écrire un playbook qui devra tourner en production.

Compté le 11 septembre 2026 dans la collection 0.5.0 installée :

FamilleNombrecheck_modediff_mode
Information, suffixe _info29fullnone
Gestion d'état, sans suffixe17fullfull
Action, suffixe _action4fullnone

Les cinquante modules déclarent check_mode: full, et dix-sept déclarent diff_mode: full : exactement ceux qui modifient un état. Un module de lecture n'a rien à montrer en différentiel, et un module d'action non plus, puisqu'il déclenche une opération au lieu d'ajuster un champ. Déclarer none vaut mieux que se taire : le lecteur sait à quoi s'en tenir sans essayer.

Le rejeu est différencié selon le risque. Une lecture est rejouée sur un 429 et sur les 5xx ambigus ; l'écriture d'un module de gestion n'est rejouée que sur un 429, là où le limiteur a répondu avant l'API et où la requête n'a pas été traitée ; l'opération d'un module d'action n'est jamais rejouée, parce qu'un redémarrage joué deux fois n'est pas un redémarrage.

Effacer un champ a une syntaxe, et une seule. La valeur vide du type efface (description: "", tags: []), tandis qu'un null explicite est refusé avant toute lecture, avec un message qui nomme la valeur à écrire. Les entiers et les booléens n'ont pas de valeur vide et ne peuvent donc pas être effacés.

Les cinquante modules sont générés à partir des contrats d'API, et c'est la chose la plus importante à savoir avant de vouloir en modifier un.

Si vous corrigez un module directement, votre travail disparaît à la génération suivante. Le correctif appartient à l'un des trois endroits que le dépôt documente : le contrat, une règle de classification, ou un override portant sa raison.

C'est aussi ce qui explique la régularité du catalogue : les cinquante modules publient tous leur documentation, leurs exemples et leurs valeurs de retour, parce qu'aucun n'a été écrit à la main.

Cette collection ne crée ni ne détruit de ressource, il n'y a donc rien à supprimer côté Scaleway après un playbook. Le nettoyage porte sur ce que vous avez posé sur votre poste.

Fenêtre de terminal
rm -f production.scaleway.yml ajuster.yml
ansible-galaxy collection list stephrobert.scaleway

Si vous aviez provisionné une infrastructure d'essai avec Terraform pour jouer ces playbooks, c'est elle qui se détruit, avec sa propre commande terraform destroy et sa propre vérification de sortie.

La question à se poser n'est jamais « quel outil je préfère », mais « qui possède cette ressource ». Si Terraform la possède, la modifier avec Ansible crée une dérive que le prochain terraform plan proposera d'annuler. Le tableau ci-dessous se lit par la colonne de gauche : partez de l'opération réelle que vous avez à faire, et regardez qui détient la ressource concernée.

BesoinChoixPourquoi
Créer, redimensionner ou supprimer une ressource ScalewayTerraformil tient l'état, donc il sait ce qu'il possède et sait le détruire proprement
Redémarrer une instance, faire tourner une clé, appliquer un correctifAnsibleopération ponctuelle sur une ressource existante, sans état à maintenir
Ajuster une règle de groupe de sécurité géré par TerraformTerraformle modifier ailleurs crée une dérive que le prochain plan proposera d'annuler
Lire un inventaire pour alimenter un rapport ou un contrôleAnsible, modules _infoils ne changent rien, changed=False, donc rejouables sans risque
Réagir à une alerte, la nuit, sur une flotte de taille inconnueAnsible avec l'inventaire dynamiqueil découvre la flotte au moment de l'exécution, sans liste à maintenir

Les limites de ce volet ne sont pas dans Ansible, elles sont dans l'API qu'il appelle. Les valeurs ci-dessous sont comptées dans la collection 0.5.0 installée le 11 septembre 2026, lues sur la page officielle des quotas d'Organisation Scaleway dont la date de validation est le 29 octobre 2025, ou tirées d'une issue du provider Terraform qui décrit le même plafond côté API.

LimiteValeurPortée
Modules de la collection5029 en _info, 17 de gestion, 4 en _action
Modules déclarant check_mode: full50 sur 50comptés dans le bloc attributes de chaque module
Modules déclarant diff_mode: full17 sur 50exactement les modules de gestion, les autres déclarent none
Clés API50par Organisation ; la FAQ IAM annonce 100, la page des quotas est plus récente
Instances attachées à un Private Network512plafond de la flotte qu'un inventaire peut découvrir sur un réseau
Appels API en parallèlelimitation de débit non publiéedes 403 intermittents apparaissent quand le rythme est trop élevé

La dernière ligne mérite un mot, car elle ne figure sur aucune page de quotas. L'issue #3616 du provider Terraform, ouverte le 20 janvier 2026 et étiquetée priority:highest, décrit des erreurs 403 intermittentes sur la ressource scaleway_baremetal_server. Le rapporteur les attribue à un nombre d'appels API trop élevé, sans que Scaleway l'ait confirmé. Le rapprochement avec Ansible est donc une piste, pas un fait établi : un playbook lancé avec un forks élevé sur une flotte importante interroge l'API au même rythme, et pourrait rencontrer le même mur. Ce qui est sûr, c'est que le symptôme serait intermittent : le même playbook réussit puis échoue sans qu'aucun paramètre ait changé, ce qui pousse à chercher un défaut là où il n'y en a pas. Baissez forks pour écarter cette hypothèse avant de suspecter la collection.

Ces erreurs ont une racine commune : elles font porter à Ansible une responsabilité qui appartient à Terraform, ou tiennent une garantie pour acquise sans l'avoir vérifiée. Toutes produisent un playbook qui fonctionne la première fois, et qui devient imprévisible ensuite.

AntipatternConséquenceDiscipline
Créer des ressources Scaleway depuis Ansibleaucun état ne suit ce qui existe, et rien ne sait le détruire proprementTerraform crée et détruit, Ansible agit sur l'existant
Maintenir un inventaire statique à la mainil diverge de la réalité dès la première mise à l'échelle, en silenceplugin d'inventaire dynamique, qui découvre à l'exécution
Supposer l'idempotence d'un moduleun module non idempotent rejoué en boucle produit un effet cumulatif inattendurejouer deux fois et exiger changed=0, puis contrôler en --check
Réutiliser la clé API de l'administrateur pour l'automatisationla révoquer casse tout, et la trace d'audit ne distingue plus les acteursune application IAM par automatisation, avec le droit minimal
Lancer un playbook avec un forks élevé sur une grande flotterisque de 403 intermittents et d'échecs non reproductibles, par analogie avec #3616baisser le parallélisme pour écarter cette hypothèse avant de suspecter la collection

Ansible sur Scaleway sous l'angle Well-Architected

Section intitulée « Ansible sur Scaleway sous l'angle Well-Architected »

Exploiter une infrastructure demande d'autres garanties que la construire. Les deux piliers ci-dessous posent la question qu'un auditeur poserait sur cette phase, et la discipline qui y répond.

Question clé : que se passe-t-il si le playbook est rejoué deux fois par erreur ? C'est le cas normal, pas l'exception : une chaîne d'intégration qui relance, un opérateur qui doute, un incident traité à deux. Un playbook non idempotent transforme alors un geste anodin en incident.

Discipline : vérifier l'idempotence en rejouant, comme le montre cette leçon, et non la supposer. Mesuré le 2026-09-09 sur un compte Scaleway réel avec ansible-core 2.20.1 : le module de groupe de sécurité rend changed=1 au premier passage, puis changed=0 aux deuxième et troisième, et --check ne signale aucun écart quand il n'y en a pas.

Question clé : votre inventaire décrit-il la flotte d'aujourd'hui ou celle du mois dernier ? Un inventaire statique répond invariablement la seconde, et son écart ne se voit qu'au moment où l'on agit sur une machine qui n'existe plus, ou qu'on oublie celle qui vient d'être créée.

Discipline : découvrir la flotte à l'exécution avec le plugin d'inventaire, s'appuyer sur les groupes qu'il construit à partir des étiquettes plutôt que sur des listes tenues à la main, et faire des modules _info le point de départ de toute opération, puisqu'ils ne changent rien.

SymptômeCauseSolution
Failed to import the required Python library (scaleway)le SDK n'est pas dans l'interpréteur qu'Ansible utilisepip install 'scaleway>=2.9.0' dans cet interpréteur, que le message nomme
Un défaut corrigé se reproduit malgré une réinstallationinstall ne met pas à jour une version déjà présenteansible-galaxy collection install stephrobert.scaleway --upgrade, puis collection list pour vérifier
Le playbook agit sur le mauvais compteprécédence des identifiants mal comprisele paramètre du module gagne sur l'environnement, qui gagne sur le fichier
Deux passes en --check annoncent toutes deux changedle mode répétition n'écrit rien, la seconde passe voit donc le même état initial que la premièrecomportement normal : l'idempotence se vérifie en exécution réelle, pas en --check
Un module réclame un identifiant que l'inventaire ne donne pasla ressource visée est une sous-ressourceenchaîner un module _info puis le module de gestion
{'__ansible_unsafe': …} dans la sortieprotection contre l'injection de gabaritcomportement normal, la valeur s'utilise telle quelle dans un playbook
Un null explicite est refuséla syntaxe d'effacement est la valeur vide du typedescription: "" ou tags: []

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • Terraform provisionne, Ansible exploite. La collection ne contient aucun module de création ni de suppression, et c'est un choix.
  • L'inventaire dynamique construit les groupes depuis l'API : les étiquettes des machines deviennent des groupes, sans liste à tenir.
  • scaleway_address_source explique le choix d'adresse au lieu de le subir.
  • Trois familles, trois garanties : _info ne signale jamais de changement, _action signale dès que l'API accepte, la gestion d'état n'écrit que la différence.
  • Une idempotence se vérifie en rejouant trois fois, pas en lisant une promesse.
  • La moitié des modules réclame un identifiant de sous-ressource que l'inventaire ne fournit pas : le motif est _info puis gestion.
  • Un rejeu automatique n'est jamais appliqué à une action : un redémarrage joué deux fois n'est pas un redémarrage.
  • install ne met pas à jour : sans --upgrade, une version déjà présente reste en place, sans erreur.
  • Les modules sont générés : un correctif appliqué au module disparaît à la génération suivante.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn