Comment utiliser le module Ansible blockinfile plusieurs fois dans le même fichier.

Encore une fois, j'ai rencontré pas mal de problèmes pour utiliser le module blockinfile d'Ansible plusieurs fois dans le même fichier. Cet article a pour objectif d'être un rappel sur comment s'en sortir.

J'utilise le fichier de configuration de Grafana comme exemple. Ce fichier contient plusieurs sections qui sont séparées par une entête de la forme [nom_entete]. Je souhaite modifier plusieurs sections: server, database, analytics, security et user.

Modifier une seule section est assez simple.

---
- name: test
  hosts: localhost
  connection: local
  tasks:
      -   name: setup grafana
          blockinfile:
              path: /etc/grafana/grafana.ini
              marker: "# {mark} ANSIBLE MANAGED BLOCK - grafana role"
              insertafter: '\[server\]'
              block: |
                 http_addr = 127.0.0.1
                 root_url = https://grafana.acme.dev
                 enable_gzip = true

Ce qui donne le résultat attendu suivant.

[server]
# BEGIN ANSIBLE MANAGED BLOCK - grafana role
http_addr = 127.0.0.1
root_url = https://grafana.acme.dev
enable_gzip = true
# END ANSIBLE MANAGED BLOCK - grafana role

Pour modifier plusieurs sections, j'utilise une variable et une boucle.

---
- name: test
  hosts: localhost
  connection: local
  vars:
      grafana_config:
          -   insertafter: '\[server\]'
              block: |
                  http_addr = 127.0.0.1
                  root_url = https://grafana.acme.dev
                  enable_gzip = true
          -   insertafter: '\[database\]'
              block: |
                  type = mysql
                  host = 127.0.0.1:3306
                  name = grafana
                  user = grafana
                  password = secret_me
          -   insertafter: '\[analytics\]'
              block: |
                  reporting_enabled = false
                  check_for_updates = false
          -   insertafter: '\[security\]'
              block: |
                  admin_user = user1
                  admin_password = secret
                  secret_key = s3d5fs6d54ds6
                  disable_gravatar = true
                  cookie_secure = true
                  cookie_samesite = lax
          -   insertafter: '\[users\]'
              block: |
                  allow_sign_up = false
  tasks:
      -   name: configure grafana
          blockinfile:
              path: /etc/grafana/grafana.ini
              marker: "# {mark} ANSIBLE MANAGED BLOCK - grafana role"
              insertafter: "{{ item.insertafter }}"
              block: "{{ item.block }}"
          loop: "{{ grafana_config }}"
          when:
              - item|lower != 'none'

Tout semble bon et pourtant le résultat est totalement inattendu. Chaque bloc est remplacé par le suivant entre les balises ansible et seul le dernier bloc reste. De plus ce bloc est dans la mauvaise section.

[server]
# BEGIN ANSIBLE MANAGED BLOCK - grafana role
allow_sign_up = false
# END ANSIBLE MANAGED BLOCK - grafana role

Pour résoudre le problème, je me suis rendu compte que les balises ansible doivent être différentes pour chaque section. J'ai donc ajouté le nom de la section dans la balise ce qui me donne.

---
- name: test
  hosts: localhost
  connection: local
  vars:
      grafana_config:
          -   insertafter: '\[server\]'
              section: server
              block: |
                  http_addr = 127.0.0.1
                  root_url = https://grafana.acme.dev
                  enable_gzip = true
          -   insertafter: '\[database\]'
              section: database
              block: |
                  type = mysql
                  host = 127.0.0.1:3306
                  name = grafana
                  user = grafana
                  password = secret_me
          -   insertafter: '\[analytics\]'
              section: analytics
              block: |
                  reporting_enabled = false
                  check_for_updates = false
          -   insertafter: '\[security\]'
              section: security
              block: |
                  admin_user = user1
                  admin_password = secret
                  secret_key = s3d5fs6d54ds6
                  disable_gravatar = true
                  cookie_secure = true
                  cookie_samesite = lax
          -   insertafter: '\[users\]'
              section: users
              block: |
                  allow_sign_up = false
  tasks:
      -   name: configure grafana
          blockinfile:
              path: /etc/grafana/grafana.ini
              marker: "# {mark} ANSIBLE MANAGED BLOCK - {{ item.section }} - grafana role"
              insertafter: "{{ item.insertafter }}"
              block: "{{ item.block }}"
          loop: "{{ grafana_config }}"
          when:
              - item|lower != 'none'

Cette fois le résultat est celui attendu, j'ai bien un bloc dans chacune des sections que je souhaite modifier.
J'espère que cette astuce vous sera autant utile qu'à moi.



Ajouter un commentaire