1. Le moteur de templates Jinja2 #
Variables, expressions, filtres.
Principe #
Ansible s'appuie sur Jinja2 : tout texte entre {{ ... }} est évalué comme une expression, tout bloc entre {% ... %} est une instruction (boucle, condition). Le module template rend un fichier .j2 sur le contrôleur, puis le copie sur l'hôte : chaque machine reçoit un fichier adapté à ses variables et à ses facts.
Les facts : informations sur la machine #
ansible web1.lab -m setup -a "filter=ansible_distribution*"
ansible web1.lab -m setup -a "filter=ansible_memtotal_mb"
ansible web1.lab -m setup -a "filter=ansible_default_ipv4"
# Dans un playbook
- ansible.builtin.debug:
msg: "{{ ansible_hostname }} - {{ ansible_distribution }} {{ ansible_distribution_version }} - {{ ansible_memtotal_mb }} Mo" Les facts les plus utilisés : ansible_hostname, ansible_fqdn, ansible_default_ipv4.address, ansible_os_family, ansible_processor_vcpus, ansible_memtotal_mb, ansible_mounts.
Bonne Pratique : Désactivez la collecte (gather_facts: false) sur les plays qui n'en ont pas besoin ou limitez-la avecgather_subset: ['!all', 'network']pour gagner plusieurs secondes par hôte.
2. Écrire un template utile #
Boucles, conditions et filtres.
Exemple : configuration d'un reverse proxy #
# templates/upstream.conf.j2
# {{ ansible_managed }}
upstream backend {
{% for host in groups['webservers'] %}
server {{ hostvars[host]['ansible_default_ipv4']['address'] }}:{{ app_port | default(8080) }}{% if loop.first %} weight=2{% endif %};
{% endfor %}
}
server {
listen {{ proxy_port | default(80) }};
{% if enable_tls | default(false) %}
listen 443 ssl;
ssl_certificate /etc/ssl/{{ inventory_hostname }}.crt;
{% endif %}
server_name {{ ansible_fqdn }};
location / {
proxy_pass http://backend;
proxy_set_header X-Env "{{ env | upper }}";
}
}- name: Configurer le reverse proxy
ansible.builtin.template:
src: upstream.conf.j2
dest: /etc/nginx/conf.d/upstream.conf
mode: "0644"
validate: nginx -t -c %s # %s = fichier temporaire à valider
notify: Recharger nginxÀ savoir : La variable magique ansible_managed insère un commentaire « fichier géré par Ansible » : utile pour éviter les modifications manuelles.Les filtres les plus utiles #
| Filtre | Exemple | Résultat |
|---|---|---|
default | {{ port | default(80) }} | Valeur de repli |
upper / lower | {{ env | upper }} | PROD |
join | {{ ['a','b'] | join(',') }} | a,b |
to_json / to_nice_yaml | {{ cfg | to_nice_yaml }} | Sérialisation |
regex_replace | {{ ver | regex_replace('^v','') }} | Nettoyage |
ipaddr | {{ ip | ansible.utils.ipaddr('network') }} | Calcul réseau |
b64encode / hash | {{ pwd | password_hash('sha512') }} | Encodage et hash |
int / float / bool | {{ '8' | int + 1 }} | 9 |
3. Boucles, conditions et lookups #
Rendre les playbooks dynamiques.
loop, when et register #
- name: Créer plusieurs utilisateurs
ansible.builtin.user:
name: "{{ item.name }}"
groups: "{{ item.groups | default(omit) }}"
loop:
- { name: alice, groups: sudo }
- { name: bob }
when: ansible_os_family == "Debian"
- name: Lire la version installée
ansible.builtin.command: nginx -v
register: nginx_version
changed_when: false
failed_when: nginx_version.rc not in [0, 1]
- ansible.builtin.debug:
msg: "{{ nginx_version.stderr }}" Les lookups : lire des données externes #
vars:
db_password: "{{ lookup('env', 'DB_PASSWORD') }}"
ssh_key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"
today: "{{ lookup('pipe', 'date +%F') }}"
tokens: "{{ query('community.general.random_string', length=24) }}"
secret: "{{ lookup('community.hashi_vault.hashi_vault', 'secret=kv/app:password') }}" Tester un template sans le déployer #
# Rendre un template localement pour vérifier le résultat
ansible web1.lab -m template -a "src=templates/upstream.conf.j2 dest=/tmp/upstream.conf" --check --diff
ansible localhost -m ansible.builtin.template -a "src=app.conf.j2 dest=/tmp/app.conf" -e @vars.yml
cat /tmp/app.confErreur Courante : N'oubliez pas validate: sur les fichiers critiques (nginx, sshd, sudoers) : un template invalide déployé en production peut vous enfermer hors du serveur.Mon suivi
Connectez-vous pour suivre votre progression et prendre des notes. Se connecter
Articles recommandés
Linux vs Unix : Le Guide Complet des Commandes et Distributions
Comprenez les différences entre Linux et Unix, explorez les distributions (serveur, desktop, ligh...
Ansible : l'inventaire (statique, dynamique, groupes et variables)
Comprendre et maîtriser l'inventaire Ansible : fichiers INI et YAML, groupes, variables d'hôte et...
Ansible : les commandes Ad-Hoc
Exécuter des actions immédiates sur un parc de serveurs avec ansible : modules ping, command, she...
Ansible : structurer son code avec les rôles
Créer, organiser et réutiliser des rôles Ansible : arborescence, defaults, tasks, handlers, templ...
Ansible : gérer la sécurité (Vault, SSH, privilèges et secrets)
Sécuriser Ansible : Ansible Vault, authentification SSH par clés, become et sudo, no_log, durciss...
Ansible : gérer son infrastructure avec des playbooks (Infrastructure as Code)
Écrire des playbooks de production : structure d'un projet, plays, handlers, tags, strategy seria...
Ansible : piloter ses automatisations avec une interface graphique (AWX, Semaphore, AAP)
Comparer et installer les interfaces graphiques d'Ansible : AWX, Ansible Automation Platform, Sem...
Ansible : aller plus loin (tests, qualité, CI/CD et performance)
Industrialiser Ansible : ansible-lint, yamllint, Molecule, intégration continue, collections, exe...
Bonnes pratiques Vagrant : des environnements reproductibles et rapides
Bonnes pratiques Vagrant : Vagrantfile versionné, boxes épinglées, provisioning idempotent, multi...