Variables et Facts
Objectifs du chapitre
- Comprendre les types de variables
- Maîtriser la priorité des variables
- Utiliser les facts système
- Créer des facts personnalisés
1 - Types de variables
Vue d'ensemble
Exemples
# Variables dans le playbook
vars:
app_name: myapp
app_port: 8080
# Variables depuis fichier
vars_files:
- vars/production.yml
# Variables d'environnement
environment:
DATABASE_URL: "postgres://localhost/db"
# Variables en ligne de commande
# ansible-playbook site.yml -e "version=1.2.3"
2 - Priorité des variables
Hiérarchie (de la plus basse à la plus haute)
Exemple pratique
# group_vars/all.yml
http_port: 80
# group_vars/webservers.yml
http_port: 8080
# host_vars/web-01.yml
http_port: 8081
# Résultat pour web-01: http_port = 8081
# Résultat pour web-02: http_port = 8080
# Si on exécute avec -e "http_port=9000"
# Tous les hôtes: http_port = 9000
3 - Définir des variables
Dans le playbook
---
- name: Configuration avec variables
hosts: webservers
vars:
# Variable simple
app_name: myapp
# Nombre
max_connections: 100
# Booléen
debug_enabled: false
# Liste
packages:
- nginx
- php-fpm
- php-mysql
# Dictionnaire
database:
host: localhost
port: 5432
name: mydb
user: admin
tasks:
- name: Afficher le nom
debug:
msg: "Application: {{ app_name }}"
- name: Afficher config DB
debug:
msg: "DB: {{ database.host }}:{{ database.port }}/{{ database.name }}"
Dans des fichiers séparés
# vars/common.yml
---
timezone: Europe/Paris
locale: fr_FR.UTF-8
ntp_servers:
- 0.fr.pool.ntp.org
- 1.fr.pool.ntp.org
# vars/production.yml
---
environment: production
debug_enabled: false
log_level: warn
# Utilisation dans le playbook
- name: Configuration
hosts: all
vars_files:
- vars/common.yml
- vars/{{ env }}.yml
Group vars et host vars
inventory/
├── hosts.ini
├── group_vars/
│ ├── all.yml # Tous les hôtes
│ ├── webservers.yml # Groupe webservers
│ └── webservers/ # Ou sous-dossier
│ ├── vars.yml
│ └── vault.yml # Secrets chiffrés
└── host_vars/
├── web-01.yml # Hôte spécifique
└── web-02.yml
4 - Facts système
Qu'est-ce qu'un fact ?
Les facts sont des informations collectées automatiquement sur les hôtes.
Collecter les facts
# Tous les facts
ansible web-01 -m setup
# Filtrer par pattern
ansible web-01 -m setup -a "filter=ansible_distribution*"
ansible web-01 -m setup -a "filter=ansible_memory*"
ansible web-01 -m setup -a "filter=ansible_default_ipv4"
Facts couramment utilisés
# Système d'exploitation
ansible_distribution: "Ubuntu"
ansible_distribution_version: "22.04"
ansible_distribution_release: "jammy"
ansible_os_family: "Debian"
# Réseau
ansible_hostname: "web-01"
ansible_fqdn: "web-01.example.com"
ansible_default_ipv4:
address: "192.168.1.10"
interface: "eth0"
gateway: "192.168.1.1"
# Hardware
ansible_processor_vcpus: 4
ansible_memtotal_mb: 8192
ansible_processor:
- "Intel(R) Core(TM) i7-9700K"
# Disques
ansible_mounts:
- mount: "/"
size_total: 107374182400
size_available: 53687091200
Utiliser les facts
tasks:
- name: Afficher l'OS
debug:
msg: "Système: {{ ansible_distribution }} {{ ansible_distribution_version }}"
- name: Installer sur Debian
apt:
name: nginx
state: present
when: ansible_os_family == "Debian"
- name: Configurer selon la RAM
template:
src: app.conf.j2
dest: /etc/app/app.conf
vars:
memory_limit: "{{ (ansible_memtotal_mb * 0.7) | int }}M"
- name: Afficher l'IP
debug:
msg: "IP: {{ ansible_default_ipv4.address }}"
5 - Désactiver/optimiser les facts
Désactiver la collecte
---
- name: Sans facts (plus rapide)
hosts: all
gather_facts: no
tasks:
- name: Tâche simple
command: uptime
Stratégies de collecte
# ansible.cfg
[defaults]
gathering = smart # Cache les facts
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
fact_caching_timeout = 86400 # 24 heures
# Dans le playbook
- name: Collecter seulement certains facts
hosts: all
gather_facts: no
tasks:
- name: Collecter facts réseau uniquement
setup:
gather_subset:
- network
6 - Facts personnalisés
Créer un fact local
# Sur le managed node: /etc/ansible/facts.d/app.fact
{
"version": "1.2.3",
"environment": "production",
"maintainer": "[email protected]"
}
# Ou en format INI: /etc/ansible/facts.d/app.fact
[app]
version=1.2.3
environment=production
[email protected]
Utiliser les facts locaux
tasks:
- name: Collecter les facts
setup:
- name: Afficher fact personnalisé
debug:
msg: "App version: {{ ansible_local.app.version }}"
Déployer des facts avec Ansible
tasks:
- name: Créer le répertoire facts
file:
path: /etc/ansible/facts.d
state: directory
mode: '0755'
- name: Déployer le fact
copy:
content: |
{
"deployed_at": "{{ ansible_date_time.iso8601 }}",
"deployed_by": "{{ ansible_user_id }}",
"app_version": "{{ app_version }}"
}
dest: /etc/ansible/facts.d/deployment.fact
mode: '0644'
- name: Recharger les facts
setup:
7 - set_fact et register
set_fact - Créer des variables dynamiques
tasks:
- name: Définir une variable
set_fact:
my_var: "valeur calculée"
- name: Variable basée sur facts
set_fact:
total_memory_gb: "{{ (ansible_memtotal_mb / 1024) | round(1) }}"
is_high_memory: "{{ ansible_memtotal_mb > 8000 }}"
- name: Utiliser la variable
debug:
msg: "RAM: {{ total_memory_gb }} GB, High memory: {{ is_high_memory }}"
register - Capturer les résultats
tasks:
- name: Exécuter une commande
command: cat /etc/os-release
register: os_release
- name: Vérifier si un service tourne
command: systemctl is-active nginx
register: nginx_status
ignore_errors: yes
- name: Actions selon le résultat
debug:
msg: "Nginx est {{ 'actif' if nginx_status.rc == 0 else 'inactif' }}"
- name: Installer si nécessaire
apt:
name: nginx
state: present
when: nginx_status.rc != 0
Différence set_fact vs register
8 - Filtres Jinja2
Filtres courants
tasks:
- name: Exemples de filtres
debug:
msg: |
Majuscules: {{ "hello" | upper }}
Minuscules: {{ "HELLO" | lower }}
Capitalise: {{ "hello world" | title }}
Défaut: {{ undefined_var | default("valeur_defaut") }}
Premier: {{ [1, 2, 3] | first }}
Dernier: {{ [1, 2, 3] | last }}
Taille: {{ [1, 2, 3] | length }}
Min: {{ [5, 2, 8] | min }}
Max: {{ [5, 2, 8] | max }}
Somme: {{ [1, 2, 3] | sum }}
Join: {{ ["a", "b", "c"] | join(", ") }}
MD5: {{ "password" | hash('md5') }}
Base64: {{ "hello" | b64encode }}
JSON: {{ my_dict | to_json }}
YAML: {{ my_dict | to_yaml }}
Filtres pour les chemins
tasks:
- name: Manipulation de chemins
debug:
msg: |
Basename: {{ "/etc/nginx/nginx.conf" | basename }}
Dirname: {{ "/etc/nginx/nginx.conf" | dirname }}
Extension: {{ "file.tar.gz" | splitext }}
Filtres pour les données
tasks:
- name: Traitement de listes
vars:
servers:
- { name: web-01, ip: "192.168.1.1" }
- { name: web-02, ip: "192.168.1.2" }
- { name: db-01, ip: "192.168.1.10" }
debug:
msg: |
Noms: {{ servers | map(attribute='name') | list }}
Web only: {{ servers | selectattr('name', 'match', 'web-.*') | list }}
IPs: {{ servers | map(attribute='ip') | list }}
9 - Lookups
Lire des fichiers
tasks:
- name: Lire un fichier
debug:
msg: "{{ lookup('file', '/etc/hostname') }}"
- name: Lire une clé SSH
authorized_key:
user: deploy
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
Variables d'environnement
tasks:
- name: Lire variable d'environnement
debug:
msg: "Home: {{ lookup('env', 'HOME') }}"
- name: Avec valeur par défaut
debug:
msg: "{{ lookup('env', 'MY_VAR') | default('default_value') }}"
Mot de passe aléatoire
tasks:
- name: Générer un mot de passe
set_fact:
random_password: "{{ lookup('password', '/dev/null length=16 chars=ascii_letters,digits') }}"
- name: Créer l'utilisateur
user:
name: deploy
password: "{{ random_password | password_hash('sha512') }}"
10 - Vault pour les secrets
Chiffrer des variables
# Créer un fichier vault
ansible-vault create group_vars/all/vault.yml
# Éditer
ansible-vault edit group_vars/all/vault.yml
# Voir le contenu
ansible-vault view group_vars/all/vault.yml
# Chiffrer un fichier existant
ansible-vault encrypt vars/secrets.yml
# Déchiffrer
ansible-vault decrypt vars/secrets.yml
Utiliser le vault
# group_vars/all/vault.yml (chiffré)
vault_db_password: "super_secret_password"
vault_api_key: "abc123xyz"
# group_vars/all/vars.yml
db_password: "{{ vault_db_password }}"
api_key: "{{ vault_api_key }}"
# Exécution avec mot de passe
ansible-playbook site.yml --ask-vault-pass
# Avec fichier de mot de passe
ansible-playbook site.yml --vault-password-file ~/.vault_pass
Résumé
Points clés
- Les extra-vars (-e) ont la priorité maximale
- Les facts sont collectés automatiquement au début
- Utilisez set_fact pour créer des variables dynamiques
- Protégez les secrets avec ansible-vault
Exercices pratiques
- Créez des group_vars pour configurer différents environnements
- Utilisez les facts pour adapter la configuration à la RAM
- Créez un fact personnalisé sur vos serveurs
- Chiffrez un fichier de secrets avec vault