Inventaire Ansible¶
Organisation de l'inventaire Ansible pour les déploiements multi-environnement, multi-provider, et pilotage de l'état desire depuis l'inventaire.
Convention d'arborescence¶
L'inventaire suit une arborescence a 4 niveaux :
env / provider-region / topology / project
inventory/
├── dev/
│ └── vsphere-paris/
│ ├── internet/
│ │ └── alpha/
│ │ ├── hosts.yml
│ │ └── group_vars/
│ │ └── all/
│ │ ├── vars.yml
│ │ └── vault.yml
│ ├── extranet/
│ ├── intranet/
│ ├── sandbox/
│ ├── webapp/
│ └── engineering/
├── staging/
│ └── gcp-europe-west1/
│ └── webapp/
│ └── alpha/
│ ├── hosts.yml
│ └── group_vars/
│ └── all/
│ ├── vars.yml
│ └── vault.yml
└── prod/
├── vsphere-lyon/
│ └── intranet/
│ └── alpha/
└── aws-eu-west-1/
└── internet/
└── beta/
Description des 4 niveaux¶
| Niveau | Valeurs typiques | Rôle |
|---|---|---|
| Environnement | dev, staging, prod | Cycle de vie de l'application |
| Provider-region | vsphere-paris, gcp-europe-west1, aws-eu-west-1 | Infrastructure et localisation géographique |
| Topologie | internet, intranet, sandbox, webapp | Zone réseau et niveau de sécurité |
| Projet | alpha, beta, nom de l'application | Service cible avec ses hosts et group_vars |
Topologies disponibles¶
| Topologie | Exposition | Usage |
|---|---|---|
internet | Public (DMZ) | Services exposes sur Internet |
extranet | Restreint | Accès partenaires, fournisseurs |
intranet | Interne | Services internes a consommer |
sandbox | Isole | POC, tests, environnements jetables |
webapp | Applicatif | Front-end applicatif |
engineering | Dev / CI | Outils de développement, exploration |
Héritage des variables¶
Les group_vars places à chaque niveau de l'arborescence permettent l'héritage par surchargé. Les variables se surchargent du plus général au plus spécifique.
Ordre de precedence¶
inventory/prod/group_vars/all.yml— variables communes à tout l'environnementprodinventory/prod/vsphere-lyon/group_vars/all.yml— variables spécifiques au providerinventory/prod/vsphere-lyon/intranet/group_vars/all.yml— variables de la topologieinventory/prod/vsphere-lyon/intranet/alpha/group_vars/all.yml— variables du projet
Exemple concret¶
# inventory/prod/group_vars/all.yml
log_retention_days: 30
ntp_servers:
- ntp1.example.com
- ntp2.example.com
# inventory/prod/vsphere-lyon/intranet/alpha/group_vars/all.yml
# Surcharge : le projet alpha conserve les logs 90 jours pour conformite
log_retention_days: 90
Ansible résout la variable en appliquant la valeur la plus spécifique. L'hôte srv-01 appartenant au projet alpha recevra log_retention_days: 90 ; tous les autres hôtes prod recevront la valeur par défaut 30.
Piloter les rôles par l'inventaire¶
Le pattern fondamental : l'état desire est défini dans l'inventaire, pas dans le playbook. Le playbook reste générique et délégué la décision à l'inventaire.
Niveaux de surchargé de l'état¶
Les variables d'état peuvent être définies a quatre niveaux, du moins au plus prioritaire :
all.varsdanshosts.yml— valeur par défaut pour tous les hôtes- Variables de groupe (
children) — valeur pour un groupe d'hôtes - Variables d'hôte (
hosts) — valeur pour un hôte spécifique - Extra-vars CLI (
-e) — surchargé opérationnelle au moment de l'exécution
Exemple d'inventaire avec pilotage d'état¶
# inventory/prod/aws-eu-west-1/internet/beta/hosts.yml
all:
vars:
remote_users_fact_state: present
children:
prod_servers:
hosts:
srv-01: {}
srv-02: {}
dev_servers:
hosts:
dev-01:
remote_users_fact_state: noop
legacy:
vars:
remote_users_fact_state: absent
Dans cet exemple :
srv-01etsrv-02heritent deall.vars: étatpresentdev-01surchargé au niveau hôte : étatnoop(aucune action)- Le groupe
legacysurchargé au niveau groupe : étatabsent(desinstallation)
Playbook générique correspondant¶
# playbooks/remote_users_fact.yml
---
- name: Gerer le role remote_users_fact
hosts: all
roles:
- nuevolia.identity.remote_users_fact
Le playbook ne contient aucune logique d'état. L'inventaire porte l'intention opérationnelle.
noop comme valeur par défaut sur dev
Définir remote_users_fact_state: noop sur les hôtes de développement garantit qu'aucune action destructive ne se produit si un playbook de production est exécuté par erreur sur un mauvais inventaire. C'est une sécurité de dernier recours qui ne remplacé pas le contrôle d'accès, mais qui en réduit l'impact.
Secrets dans l'inventaire¶
Stratégie a deux niveaux selon la nature et le cycle de vie du secret.
Ansible Vault (secrets de bootstrap)¶
Les credentials provider et les tokens initiaux vivent dans des fichiers vault.yml chiffres par Ansible Vault, co-localises avec les group_vars du niveau concerne.
inventory/prod/vsphere-lyon/
└── group_vars/
└── all/
├── vars.yml # variables en clair
└── vault.yml # secrets vault (credentials vCenter, tokens)
# Creer un fichier vault
ansible-vault create inventory/prod/vsphere-lyon/group_vars/all/vault.yml
# Editer un fichier vault existant
ansible-vault edit inventory/prod/vsphere-lyon/group_vars/all/vault.yml
# Executer un playbook avec vault ID par environnement
ansible-playbook -i inventory/prod/ playbook.yml --vault-id prod@prompt
ansible-playbook -i inventory/staging/ playbook.yml --vault-id staging@prompt
Secret manager externe (secrets applicatifs)¶
Les secrets applicatifs (mots de passe BDD, API keys, certificats) sont gérés dans OpenBao et injectes via le plugin de lookup community.hashi_vault.hashi_vault :
# Dans un role ou un playbook
vars:
db_password: "{{ lookup('community.hashi_vault.hashi_vault',
'secret/data/prod/db password') }}"
api_key: "{{ lookup('community.hashi_vault.hashi_vault',
'secret/data/prod/api token') }}"
Répartition des secrets par type
| Type de secret | Stockage | Exemple |
|---|---|---|
| Credentials provider | Ansible Vault | Mot de passe vCenter, access key AWS |
| Tokens de bootstrap | Ansible Vault | Token initial OpenBao, clé de chiffrement |
| Secrets applicatifs | OpenBao via lookup | Mot de passe BDD, API keys |
| Certificats TLS | OpenBao + nuevolia.identity.tls_certificates | TLS serveur, mTLS inter-services |
Facts statiques et dynamiques¶
Deux sources complementaires alimentent les facts disponibles dans les playbooks.
Facts statiques dans group_vars¶
Les facts statiques décrivent le contexte fixe de la topologie : réseau, sécurité, politique de hardening. Ils sont définis dans les group_vars du niveau topologie ou projet.
# inventory/prod/vsphere-lyon/intranet/group_vars/all.yml
network_vlan: 120
network_gateway: "10.1.120.1"
network_dns_servers:
- "10.1.0.53"
- "10.1.0.54"
network_domain: "intranet.lyon.example.com"
hardening_level: strict
ntp_servers:
- "10.1.0.123"
- "10.1.0.124"
Facts dynamiques via plugins d'inventaire¶
Les facts dynamiques sont collectes automatiquement par le plugin d'inventaire du provider. Ils décrivent l'état courant des ressources : adresses IP, tags, état de la VM, métriques.
vSphere avec community.vmware.vmware_vm_inventory :
# inventory/prod/vsphere-lyon/vsphere.yml
plugin: community.vmware.vmware_vm_inventory
hostname: "vcenter.lyon.example.com"
validate_certs: false
with_nested_properties: true
keyed_groups:
- key: config.guestId
prefix: os
- key: guest.net[0].network
prefix: network
- key: customValue[?(@.key == 'role')].value
prefix: role
GCP avec google.cloud.gcp_compute :
# inventory/staging/gcp-europe-west1/gcp.yml
plugin: google.cloud.gcp_compute
projects:
- mon-projet-staging
regions:
- europe-west1
auth_kind: serviceaccount
service_account_file: /opt/ansible/sa-staging.json
keyed_groups:
- key: labels.env
prefix: env
- key: labels.role
prefix: role
- key: status
prefix: status
Vérification de l'inventaire¶
# Lister tous les hotes avec leurs variables
ansible-inventory -i inventory/prod/ --list
# Afficher l'arborescence des groupes
ansible-inventory -i inventory/prod/ --graph
# Inspecter un hote specifique
ansible-inventory -i inventory/prod/ --host srv-01
Réutilisation des facts dans d'autres playbooks¶
Un fact collecte et mis en cache peut conditionner l'exécution d'un playbook différent. Le pattern repose sur une clause de garde sur ansible_local avant toute action.
Clause de garde sur ansible_local¶
- name: Verifier la presence du fact avant de continuer
ansible.builtin.assert:
that:
- ansible_local.remote_users_fact is defined
fail_msg: >-
Le fact remote_users_fact est absent. Executer le role
nuevolia.identity.remote_users_fact avant ce playbook.
Exemple 1 : bloquer un déploiement si trop de sessions actives¶
- name: Lire le nombre de sessions actives
ansible.builtin.set_fact:
active_sessions: "{{ ansible_local.remote_users_fact.active_sessions | default(0) }}"
- name: Refuser le deploiement si les sessions actives depassent le seuil
ansible.builtin.fail:
msg: >-
Deploiement annule : {{ active_sessions }} sessions actives
(seuil : {{ deploy_max_active_sessions }}).
Attendre la fin des sessions avant de relancer.
when: active_sessions | int > deploy_max_active_sessions | int
Exemple 2 : adapter le comportement selon le verdict du fact¶
- name: Lire le verdict de conformite
ansible.builtin.set_fact:
compliance_verdict: "{{ ansible_local.remote_users_fact.compliance | default('unknown') }}"
- name: Appliquer la configuration stricte si non conforme
ansible.builtin.import_tasks: enforce_strict.yml
when: compliance_verdict == 'non_compliant'
- name: Enregistrer le resultat dans le journal d'audit
ansible.builtin.lineinfile:
path: /var/log/ansible-compliance.log
line: "{{ ansible_date_time.iso8601 }} {{ inventory_hostname }} {{ compliance_verdict }}"
create: true
mode: '0640'
La condition when: ansible_local.xxx is defined protégé contre l'absence du fact et evite une erreur silencieuse ou un comportement non deterministe.
Tags et extra-vars en CLI¶
Les options CLI permettent de cibler finement un sous-ensemble d'hôtes et d'étapes sans modifier l'inventaire ni le playbook.
Cibler un groupe avec --limit¶
# Executer uniquement sur les serveurs citrix
ansible-playbook -i inventory/prod/ site.yml --limit citrix_servers
# Cibler un hote specifique dans un groupe
ansible-playbook -i inventory/prod/ site.yml --limit srv-01
Forcer un état avec -e¶
# Forcer l'etat present independamment de l'inventaire
ansible-playbook -i inventory/prod/ site.yml -e remote_users_fact_state=present
# Combiner plusieurs extra-vars
ansible-playbook -i inventory/prod/ site.yml \
-e remote_users_fact_state=present \
-e remote_users_fact_version=2.3.1
Exécuter une étape spécifique avec --tags¶
# Executer uniquement la phase de validation
ansible-playbook -i inventory/prod/ site.yml --tags validate
# Sauter la phase d'installation
ansible-playbook -i inventory/prod/ site.yml --skip-tags install
Combinaison opérationnelle¶
# Valider uniquement sur les serveurs citrix en prod, sans installer
ansible-playbook -i inventory/prod/aws-eu-west-1/internet/beta/ site.yml \
--limit citrix_servers \
--tags validate \
-e remote_users_fact_state=present
Commandes opérationnelles courantes¶
| Objectif | Commande |
|---|---|
| Valider tous les hôtes prod | ansible-playbook -i inventory/prod/ site.yml --tags validate |
| Installer sur un groupe | ansible-playbook -i inventory/prod/ site.yml --limit app_servers |
| Forcer la suppression sur un hôte | ansible-playbook -i inventory/prod/ site.yml -l srv-01 -e state=absent |
| Vérifier sans appliquer (dry-run) | ansible-playbook -i inventory/prod/ site.yml --check --diff |
| Lister les tâches sans les exécuter | ansible-playbook -i inventory/prod/ site.yml --list-tasks |
Performance¶
Sur un inventaire de plusieurs centaines d'hôtes, les parametres par défaut d'Ansible produisent des executions lentes. Les optimisations suivantes sont cumulatives.
Parallélisme avec forks¶
forks contrôle le nombre d'hôtes traites en parallèle. La valeur par défaut est 5, insuffisante pour les grands inventaires.
Pipelining SSH¶
pipelining réduit le nombre d'opérations SSH en transmettant plusieurs commandes dans la même connexion. Nécessité requiretty = false dans /etc/sudoers.
Mises à jour progressives avec serial¶
serial limite le nombre d'hôtes traites simultanément dans un play. Utile pour les mises à jour sans interruption de service.
# playbooks/site.yml
---
- name: Mettre a jour les serveurs web progressivement
hosts: web_servers
serial: 5 # traiter 5 hotes a la fois
roles:
- nuevolia.application.webapp
Désactiver la collecte des facts¶
Quand le playbook n'utilise pas les facts système, désactiver leur collecte economise plusieurs secondes par hôte.
---
- name: Mettre a jour les cles SSH autorisees
hosts: all
gather_facts: false
tasks:
- name: Deployer les cles autorisees
ansible.posix.authorized_key:
user: "{{ item.user }}"
key: "{{ item.key }}"
state: present
loop: "{{ authorized_keys_list }}"
Mise en cache des facts¶
Le cache de facts evite de les collecter à chaque exécution. Particulièrement utile quand les facts sont lus par plusieurs playbooks successifs.
# ansible.cfg
[defaults]
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
fact_caching_timeout = 3600
Combinaison pour les grands inventaires
Sur un inventaire de 200+ hôtes, combiner forks = 20, pipelining = True, gather_facts: false sur les playbooks qui n'en ont pas besoin, et fact_caching = jsonfile avec un TTL de 1 heure réduit typiquement le temps d'exécution de 60 a 80 %. Activer ces options progressivement et mesurer l'impact à chaque étape pour identifier le goulot d'étranglement.