Aller au contenu
Infrastructure as Code medium

Module blockinfile Ansible : insérer un bloc multi-lignes idempotent

9 min de lecture

Logo Ansible

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.

  • 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.
  • Connaître les modules copy: et lineinfile:blockinfile: se positionne entre les deux.

Quand vous insérez un bloc avec blockinfile:, Ansible encadre votre bloc avec deux markers :

# BEGIN ANSIBLE MANAGED BLOCK
PermitRootLogin no
PasswordAuthentication no
MaxAuthTries 3
# END ANSIBLE MANAGED BLOCK

Au 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.

- 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 sshd

create: 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 ANSIBLE
PermitRootLogin no
# END HARDENING ANSIBLE

Pourquoi 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.

- name: Retirer le bloc de durcissement
ansible.builtin.blockinfile:
path: /etc/ssh/sshd_config.d/99-ansible.conf
marker: "# {mark} HARDENING ANSIBLE"
state: absent

Ansible 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é.

CasModule 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 fichierblockinfile: × NUn marker custom par bloc
Fichier qu’on ne possède pas (système)blockinfile:On modifie sans tout réécrire
SymptômeCauseFix
2 blocs empilés à chaque runMarker par défaut + 2 tâches dans le playbookMarker unique par bloc (# {mark} BLOC1, # {mark} BLOC2)
Fichier YAML/JSON casséMarker # … injecté dans un format où # est invalideAdapter le marker (-- {mark} pour SQL, <!-- {mark} --> pour XML)
Bloc ajouté à EOF au lieu de l’endroit vouluinsertafter: regex ne matche pasTester la regex avec grep -E avant
blockinfile: sur fichier inexistant échouecreate: false (défaut)Ajouter create: true
  • 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: true crée le fichier s’il n’existe pas — utile pour les drop-in configs.
  • Adapter le format du marker au type de fichier (#, --, <!-- -->, etc.).

Cette page a un lab d’accompagnement : labs/modules-fichiers/blockinfile/ dans stephrobert/ansible-training.

Challenge — sur db1.lab :

  1. Créer /etc/profile.d/aliases-rhce.sh (create: true, mode 0644).
  2. Insérer un bloc d’aliases (ll, gs, ports) avec marker # {mark} ALIASES RHCE.
  3. Vérifier que 2 runs successifs ne dupliquent pas le bloc.

Validation pytest+testinfra :

Fenêtre de terminal
ansible-playbook solution.yml
ansible-playbook solution.yml # Doit etre ok=1, changed=0
pytest -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).

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn