Using Ansible blockinfile module multiple times in the same file
Once again, I struggled using Ansible module: blockinfile to change multiple sections of the same file. It's time to write somewhere how to achieve it.
I'm using Grafana config file as example. This file contains different sections separated by a header in the form of [section_name]. I need to edit sections: server, database, analytics, security and user.
Edit only on section is 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
As expected, the result is:
[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
To edit multiple sections, I'm using var and loop.
--- - 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'
Everything looks good but the result is unexpected. Each block is replaced by the next one inside the marker and only the last stay in the file and in the wrong section.
[server] # BEGIN ANSIBLE MANAGED BLOCK - grafana role allow_sign_up = false # END ANSIBLE MANAGED BLOCK - grafana role
It's annoying, to solve this I found out I need to have a dedicated marker by section. The new task looks like this:
--- - 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'
This time I got the expected result, having one block for each section I want to change. I hope this tips will help someone to achieve his goal faster than I did.
Add a comment