
ansible.builtin.blockinfile insère ou met à jour un bloc multi-lignes dans un fichier existant, avec idempotence garantie via des markers automatiques. C’est le module qui comble le trou entre lineinfile: (1 ligne) et template: (fichier complet).
Cas d’usage typiques : ajouter 3-10 lignes de durcissement dans /etc/ssh/sshd_config.d/99-ansible.conf, déposer un bloc d’aliases dans /etc/profile.d/, gérer une section custom dans un fichier que vous ne contrôlez pas entièrement.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Le rôle des markers
# BEGIN ANSIBLE MANAGED BLOCK/# END ANSIBLE MANAGED BLOCK. - Comment personnaliser le marker pour gérer plusieurs blocs dans le même fichier.
- Quand
blockinfile:est préférable àlineinfile:(multi-lignes) ou àtemplate:(fichier non possédé). - Le piège des commentaires de marker dans des fichiers où
#n’est pas un commentaire.
Prérequis
Section intitulée « Prérequis »- Connaître les modules
copy:etlineinfile:—blockinfile:se positionne entre les deux.
Le mécanisme des markers
Section intitulée « Le mécanisme des markers »Quand vous insérez un bloc avec blockinfile:, Ansible encadre votre bloc avec deux markers :
# BEGIN ANSIBLE MANAGED BLOCKPermitRootLogin noPasswordAuthentication noMaxAuthTries 3# END ANSIBLE MANAGED BLOCKAu prochain run, Ansible cherche les markers, remplace tout ce qui est entre les deux par le nouveau bloc, et regénère les markers. Conséquence : idempotence garantie, jamais de duplication.
Ne pas modifier les markers à la main entre deux runs — Ansible perdrait le repère et empilerait un nouveau bloc.
Exemple : durcissement sshd
Section intitulée « Exemple : durcissement sshd »- name: Durcissement sshd via blockinfile ansible.builtin.blockinfile: path: /etc/ssh/sshd_config.d/99-ansible.conf create: true mode: "0600" block: | PermitRootLogin no PasswordAuthentication no MaxAuthTries 3 ClientAliveInterval 300 marker: "# {mark} HARDENING ANSIBLE" notify: Reload sshdcreate: true crée le fichier s’il n’existe pas — pratique pour les drop-in configs dans /etc/ssh/sshd_config.d/.
marker: "# {mark} HARDENING ANSIBLE" personnalise le marker. {mark} est remplacé par BEGIN ou END. Résultat dans le fichier :
# BEGIN HARDENING ANSIBLEPermitRootLogin no…# END HARDENING ANSIBLEPourquoi customiser le marker ? Si vous gérez plusieurs blocs dans le même fichier (un pour le hardening, un pour les aliases utilisateur, un pour la perf tuning), chaque bloc doit avoir son marker unique — sinon Ansible ne sait plus lequel mettre à jour.
Insertion à un endroit précis — insertafter: / insertbefore:
Section intitulée « Insertion à un endroit précis — insertafter: / insertbefore: »Par défaut, blockinfile: ajoute à la fin du fichier (EOF). Pour insérer après une ligne précise :
- name: Ajouter un bloc apres la ligne PORT ansible.builtin.blockinfile: path: /etc/myapp/config.ini insertafter: '^Port=' block: | LogLevel = INFO LogPath = /var/log/myapp/ marker: "# {mark} LOGGING"Si la regex ne matche pas et qu’on utilise insertafter: EOF (défaut), le bloc est ajouté en fin de fichier. Si la regex est définie et ne matche pas, le bloc est aussi ajouté en fin (comportement par défaut Ansible) — pour échouer dans ce cas, ajouter une vérification préalable.
Suppression — state: absent
Section intitulée « Suppression — state: absent »- name: Retirer le bloc de durcissement ansible.builtin.blockinfile: path: /etc/ssh/sshd_config.d/99-ansible.conf marker: "# {mark} HARDENING ANSIBLE" state: absentAnsible cherche les markers BEGIN HARDENING ANSIBLE et END HARDENING ANSIBLE et supprime tout entre les deux (markers compris). Le reste du fichier est intact.
Marker dans des fichiers où # n’est pas un commentaire
Section intitulée « Marker dans des fichiers où # n’est pas un commentaire »Pour un fichier YAML, JSON ou XML, le marker # BEGIN… est invalide syntaxiquement.
# Pour un YAML : commentaire = "#" (OK)marker: "# {mark} ANSIBLE"
# Pour un XML : commentaire = "<!-- ... -->"marker: "<!-- {mark} ANSIBLE -->"
# Pour un fichier SQL :marker: "-- {mark} ANSIBLE"Toujours adapter le marker au format du fichier cible — sinon le fichier devient cassé.
Comparaison lineinfile vs blockinfile vs template
Section intitulée « Comparaison lineinfile vs blockinfile vs template »| Cas | Module recommandé | Raison |
|---|---|---|
1 ligne (net.ipv4.ip_forward = 1) | lineinfile: | Le plus simple, regex pour matching |
| 3-10 lignes liées (bloc d’options) | blockinfile: | Markers, idempotence, suppression facile |
Fichier complet (nginx.conf) | template: | Interpolation Jinja2, validate, backup |
| Plusieurs blocs dans un fichier | blockinfile: × N | Un marker custom par bloc |
| Fichier qu’on ne possède pas (système) | blockinfile: | On modifie sans tout réécrire |
Pièges courants
Section intitulée « Pièges courants »| Symptôme | Cause | Fix |
|---|---|---|
| 2 blocs empilés à chaque run | Marker par défaut + 2 tâches dans le playbook | Marker unique par bloc (# {mark} BLOC1, # {mark} BLOC2) |
| Fichier YAML/JSON cassé | Marker # … injecté dans un format où # est invalide | Adapter le marker (-- {mark} pour SQL, <!-- {mark} --> pour XML) |
Bloc ajouté à EOF au lieu de l’endroit voulu | insertafter: regex ne matche pas | Tester la regex avec grep -E avant |
blockinfile: sur fichier inexistant échoue | create: false (défaut) | Ajouter create: true |
À retenir
Section intitulée « À retenir »blockinfile:= idéal pour 3-10 lignes liées dans un fichier existant.- Markers garantissent l’idempotence — ne jamais les modifier à la main.
- Marker custom (
marker: "# {mark} MY_BLOCK") obligatoire si plusieurs blocs dans un fichier. create: truecrée le fichier s’il n’existe pas — utile pour les drop-in configs.- Adapter le format du marker au type de fichier (
#,--,<!-- -->, etc.).
Pratiquer dans le lab
Section intitulée « Pratiquer dans le lab »Cette page a un lab d’accompagnement : labs/modules-fichiers/blockinfile/ dans stephrobert/ansible-training.
Challenge — sur db1.lab :
- Créer
/etc/profile.d/aliases-rhce.sh(create: true, mode0644). - Insérer un bloc d’aliases (
ll,gs,ports) avec marker# {mark} ALIASES RHCE. - Vérifier que 2 runs successifs ne dupliquent pas le bloc.
Validation pytest+testinfra :
ansible-playbook solution.ymlansible-playbook solution.yml # Doit etre ok=1, changed=0pytest -v labs/modules-fichiers/blockinfile/challenge/tests/4 tests vérifient l’existence du fichier, son contenu, la présence des markers et l’idempotence (un seul bloc dans le fichier).