Aller au contenu principal

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

  1. Créez des group_vars pour configurer différents environnements
  2. Utilisez les facts pour adapter la configuration à la RAM
  3. Créez un fact personnalisé sur vos serveurs
  4. Chiffrez un fichier de secrets avec vault

← Playbooks | Roles →