Passer au contenu principal

Fondamentaux (Ansible)

Conditions et boucles

Les conditions et les boucles permettent d'écrire des playbooks adaptatifs. Sans eux, un playbook ne peut que répéter les mêmes actions sur tous les hôtes. Avec eux, on peut brancher le comportement selon l'état du système, itérer sur des listes de ressources, et attendre des états transitoires.

when : conditions

La directive when accepte une expression Jinja2 évaluée à true ou false. Elle s'applique après le module : le module est évalué mais pas exécuté si la condition est fausse.

# Condition sur un fact
- ansible.builtin.apt:
    name: ufw
    state: present
  when: ansible_distribution == "Debian"

# Conditions multiples (ET logique)
- ansible.builtin.service:
    name: nginx
    state: restarted
  when:
    - ansible_distribution == "Debian"
    - ansible_memtotal_mb >= 512

# OU logique
- ansible.builtin.debug:
    msg: "Système supporté"
  when: ansible_distribution == "Debian" or ansible_distribution == "Ubuntu"

# Variable définie
- ansible.builtin.template:
    src: custom.conf.j2
    dest: /etc/myapp/custom.conf
  when: custom_config is defined

# Variable non vide
- ansible.builtin.debug:
    msg: "Env : {{ app_env }}"
  when: app_env is defined and app_env | length > 0

loop : boucles

loop remplace les anciens with_items, with_dict, etc. L'élément courant est accessible via item.

# Boucle sur une liste simple
- ansible.builtin.apt:
    name: "{{ item }}"
    state: present
  loop:
    - git
    - curl
    - htop
    - vim

# Boucle sur une liste de dictionnaires
- ansible.builtin.user:
    name: "{{ item.name }}"
    groups: "{{ item.groups }}"
    shell: "{{ item.shell | default('/bin/bash') }}"
  loop:
    - name: alice
      groups: sudo
    - name: bob
      groups: docker
      shell: /bin/sh

# Boucle avec index
- ansible.builtin.debug:
    msg: "{{ loop_index }} - {{ item }}"
  loop: "{{ ['a', 'b', 'c'] }}"
  loop_control:
    index_var: loop_index
    label: "{{ item }}"   # affichage simplifié dans les logs

register + when : brancher sur le résultat d'une tâche

- name: Vérifier si le service est actif
  ansible.builtin.command:
    cmd: systemctl is-active myapp
  register: service_status
  failed_when: false    # ne pas échouer si le service est inactif
  changed_when: false

- name: Démarrer le service si inactif
  ansible.builtin.systemd:
    name: myapp
    state: started
  when: service_status.rc != 0

failed_when et changed_when

Ces directives permettent de contrôler le statut retourné par une tâche, utile avec command et shell qui ne peuvent pas être idempotents nativement :

- name: Vérifier la version de l'application
  ansible.builtin.command:
    cmd: myapp --version
  register: app_version
  changed_when: false              # cette commande ne change jamais rien
  failed_when: app_version.rc > 1  # rc=1 est acceptable, >1 est une vraie erreur

until / retries / delay : attente d'un état

Utile pour attendre qu'un service soit prêt après un démarrage, ou qu'une ressource externe soit disponible :

- name: Attendre que l'API soit disponible
  ansible.builtin.uri:
    url: http://localhost:8080/health
    status_code: 200
  register: health_check
  until: health_check.status == 200
  retries: 12
  delay: 5    # attendre 5s entre chaque tentative (max 60s total)