Utiliser des variables et des faits dans plusieurs inventaires

AnsibleBeginner
Pratiquer maintenant

Introduction

Un playbook réutilisable doit consommer les données des environnements plutôt que coder en dur des réponses séparées pour le développement et la production. La sélection de l'inventaire, la portée des variables et les faits des cibles déterminent ce que reçoit chaque nœud.

Vous utiliserez deux inventaires sélectionnant des nœuds SSH différents, stockerez des données de groupe et d'hôte à côté de chaque source et produirez les paramètres avec un seul playbook. Vous appliquerez aussi un remplacement temporaire par variable supplémentaire et rétablirez une configuration de référence stable.

Séparer les données d'inventaire par environnement

Dans cette étape, vous donnerez au développement et à la production des sources d'inventaire et des valeurs de variables de groupe distinctes.

Entrez dans le projet :

cd /home/labex/project

Le labo fournit deux petits inventaires. Lisez chacun avant d'exécuter l'automatisation :

cat inventories/dev/hosts.ini
cat inventories/prod/hosts.ini

Le groupe app de dev contient web1 ; le groupe app de prod contient web2. Leurs adresses et paramètres SSH sont préparés. Ce sont des nœuds réellement distincts, et non deux noms pour localhost.

-i sélectionne une source d'inventaire pour cette invocation, remplaçant l'inventaire par défaut du projet. Prévisualisez séparément chaque environnement :

ansible app -i inventories/dev/hosts.ini --list-hosts
ansible app -i inventories/prod/hosts.ini --list-hosts

Vous devez obtenir web1 pour dev et web2 pour prod. Ne combinez pas ces deux sources pour simuler des environnements isolés : les sources peuvent fusionner, et un même nom d'hôte d'inventaire identifie toujours un seul hôte. Gardez l'invocation de chaque environnement explicite.

Une variable est une valeur nommée consommée par l'automatisation. Une correspondance YAML utilise des lignes name: value. Ansible charge group_vars/app.yml à côté d'un inventaire pour son groupe app. Créez des données différentes pour le même nom de groupe dans chaque environnement :

cat > inventories/dev/group_vars/app.yml <<'EOF'
environment_label: development
release_channel: preview
EOF
cat > inventories/prod/group_vars/app.yml <<'EOF'
environment_label: production
release_channel: stable
EOF

Examinez les données d'inventaire résolues. --list renvoie du JSON, dont un objet _meta.hostvars pour les valeurs des hôtes :

ansible-inventory -i inventories/dev/hosts.ini --list
ansible-inventory -i inventories/prod/hosts.ini --list

L'hôte dev doit résoudre development/preview ; l'hôte prod production/stable. Un fichier de variables n'a d'utilité que si l'inventaire et le groupe prévus le chargent réellement.

Consommer les variables d'hôte et les faits réels

Dans cette étape, vous remplacerez la valeur de groupe d'un hôte et produirez des paramètres réellement gérés à partir des données d'environnement.

Un fichier sous host_vars porte le nom d'un hôte d'inventaire. Pour un même hôte et une même clé, sa variable d'hôte remplace la variable de groupe utilisée ici. Donnez au canary de développement un canal de publication propre à l'hôte :

cat > inventories/dev/host_vars/web1.yml <<'EOF'
release_channel: canary
EOF

Le développement conserve environment_label development, mais web1 résout maintenant release_channel canary. La production reste stable. Confirmez la résolution dev :

ansible-inventory -i inventories/dev/hosts.ini --list

Écrivez un playbook réutilisable pour l'un ou l'autre inventaire :

cat > deploy-info.yml <<'EOF'
- name: Configure environment-specific application settings
  hosts: app
  gather_facts: true
  vars:
    banner_prefix: Managed environment
  tasks:
    - name: Write settings from variables and facts
      ansible.builtin.copy:
        dest: /home/automation/app-settings.conf
        content: |
          [application]
          environment={{ environment_label }}
          channel={{ release_channel }}
          host={{ inventory_hostname }}
          distribution={{ ansible_facts.distribution }}
          label={{ banner_prefix }}
        mode: "0640"
EOF

vars définit une valeur au niveau du play, banner_prefix. Dans le contenu copy, {{ variable_name }} insère une valeur au moment de l'exécution. Il s'agit d'une substitution élémentaire de valeurs ; un prochain labo gérera des modèles Jinja autonomes.

Le | YAML conserve le contenu indenté qui suit comme texte multiligne, y compris son saut de ligne final. inventory_hostname est le nom d'inventaire actuel. Avec gather_facts true, Ansible collecte les données de la cible avant les tâches ; ansible_facts.distribution fournit la véritable distribution du système d'exploitation. Ce sont des données de la cible, et non un fait sur le contrôleur.

Vérifiez la syntaxe, puis exécutez séparément le même playbook pour chaque environnement :

ansible-playbook -i inventories/dev/hosts.ini deploy-info.yml --syntax-check
ansible-playbook -i inventories/dev/hosts.ini deploy-info.yml
ansible-playbook -i inventories/prod/hosts.ini deploy-info.yml

Lisez les deux fichiers réels via leurs inventaires respectifs :

ansible app -i inventories/dev/hosts.ini -m ansible.builtin.command -a 'cat /home/automation/app-settings.conf'
ansible app -i inventories/prod/hosts.ini -m ansible.builtin.command -a 'cat /home/automation/app-settings.conf'

Le développement doit contenir environment=development, channel=canary et host=web1. La production doit contenir environment=production, channel=stable et host=web2. Les deux doivent contenir distribution=Ubuntu et label=Managed environment. Le playbook commun a produit des contenus cibles différents en consommant des données différentes.

Remplacer une valeur pour une invocation et rétablir la référence

Dans cette étape, vous utiliserez une variable supplémentaire sans modifier les données d'inventaire enregistrées, puis reviendrez à une configuration de référence convergée.

-e fournit une variable supplémentaire pour cette exécution. Elle remplace les valeurs de groupe et d'hôte démontrées ici. Sélectionnez temporairement un canal hotfix uniquement en développement :

ansible-playbook -i inventories/dev/hosts.ini deploy-info.yml -e release_channel=hotfix

Lisez la configuration dev obtenue :

ansible app -i inventories/dev/hosts.ini -m ansible.builtin.command -a 'cat /home/automation/app-settings.conf'

Son canal doit être hotfix. Les fichiers source group_vars et host_vars n'ont pas été modifiés par -e, et la production n'a pas été sélectionnée.

Exécutez sans la variable supplémentaire pour rétablir le canal canary enregistré de web1 :

ansible-playbook -i inventories/dev/hosts.ini deploy-info.yml

Prévisualisez maintenant les deux environnements de référence :

ansible-playbook -i inventories/dev/hosts.ini deploy-info.yml --check
ansible-playbook -i inventories/prod/hosts.ini deploy-info.yml --check

Chaque hôte sélectionné doit indiquer zéro changement en attente et aucun échec ni résultat unreachable. Les relations de priorité limitées pratiquées ici sont les données de groupe, un remplacement propre à l'hôte et un remplacement par variable supplémentaire. Les règles de priorité plus complexes sont hors du périmètre de cet exercice.

Résumé

Vous avez sélectionné des inventaires d'environnement distincts, chargé des données de groupe, appliqué un remplacement propre à un hôte et produit du contenu avec les faits réels des cibles et un playbook commun. Une variable supplémentaire temporaire a modifié une invocation, puis les exécutions de référence suivantes ont ramené les deux environnements à des paramètres déclarés stables.