Ansible’s blockinfile module is a powerful tool in Ansible that allows you to insert, update, or remove a block of multi-line text within a file. It is useful when managing configurations where blocks of text (like multiple lines of settings) need to be programmatically controlled. It ensures idempotency by marking the block with identifiable delimiters so you can run the same playbook multiple times without duplicating content.
This module is typically used in scenarios like:
- Managing firewall rules.
- Updating configuration files.
- Adding or removing specific settings in scripts.
This article will explore the blockinfile module in Ansible with practical examples.
Basic Syntax
Some commonly used parameters of the blockinfile module include:
- path: (Required) The path to the file to modify.
- block: (Required) The content to insert as the block.
- marker: Custom delimiters to identify the block.
- insertbefore: Inserts the block before a matching pattern.
- insertafter: Inserts the block after a matching pattern.
- state: Can be present (default) to ensure the block exists or absent to remove it.
- backup: Creates a file backup before modifying it if set to yes.
Example 1: Inserting a Block of Text
This playbook adds a configuration block to the Apache configuration file surrounded by identifiable markers for easier management.
- name: Add Apache configuration block
hosts: all
tasks:
- name: Insert Apache configuration block
ansible.builtin.blockinfile:
path: /etc/httpd/httpd.conf
block: |
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
marker: "# {mark} Apache Configuration Block"
Example 2: Updating an Existing Block
Modify an SSH configuration block in the /etc/ssh/sshd_config file.
- name: Update SSH configuration
hosts: all
tasks:
- name: Update SSH settings block
ansible.builtin.blockinfile:
path: /etc/ssh/sshd_config
block: |
PermitRootLogin no
PasswordAuthentication yes
marker: "# {mark} SSH Configuration Block"
This playbook identifies the block using markers and replaces the content inside it.
Example 3: Removing a Block
Remove a block of firewall rules from /etc/firewalld/services/my_custom_service.xml.
- name: Remove firewall rules block
hosts: all
tasks:
- name: Remove NFS mount block
ansible.builtin.blockinfile:
path: /etc/firewalld/services/my_custom_service.xml
marker: "# {mark} Custom Firewall Rules"
state: absent
The block marked with Custom Firewall Rules will be removed.
Example 4: Update or Add a Block After a Pattern
You can use the insertafter parameter to add a text block after a specific line.
Here is an example:
- name: Add block after a specific line
hosts: all
tasks:
- name: Insert kernel parameters after 'net.ipv4.ip_forward'
ansible.builtin.blockinfile:
path: /etc/sysctl.conf
block: |
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.default.rp_filter = 1
marker: "# {mark} Additional Kernel Parameters"
insertafter: '^net.ipv4.ip_forward'
This task inserts a block of kernel parameters into /etc/sysctl.conf immediately after the line containing net.ipv4.ip_forward.
Example 5: Update or Add a Block Before a Pattern
You can use the insertbefore parameter to add a text block before a specific line.
Here is an example:
- name: Add block before a specific line
hosts: all
tasks:
- name: Insert Apache configuration block before 'IncludeOptional sites-enabled/*.conf'
ansible.builtin.blockinfile:
path: /etc/httpd/httpd.conf
block: |
# Custom Logging Configuration
LogLevel warn
ErrorLog /var/log/httpd/error.log
CustomLog /var/log/httpd/access.log combined
marker: "# {mark} Logging Configuration"
insertbefore: '^IncludeOptional sites-enabled/.*\.conf'
This playbook inserts a block of Apache logging configuration into /etc/httpd/httpd.conf immediately before the line matching IncludeOptional sites-enabled/*.conf.
Example 6: Conditional Block Management
Add a text block to /etc/environment only if the system is running Ubuntu.
- name: Add environment variables conditionally
hosts: all
tasks:
- name: Insert environment variables block for Ubuntu systems
ansible.builtin.blockinfile:
path: /etc/environment
block: |
# Custom Environment Variables
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
PATH=$PATH:/usr/lib/jvm/java-11-openjdk-amd64/bin
marker: "# {mark} Environment Variables"
when: ansible_facts['distribution'] == "Ubuntu"
In this example:
- The when clause ensures the block is only added if the target system runs Ubuntu.
- The block contains custom environment variables for Java.
Conclusion
The blockinfile module is a powerful tool for managing multi-line configurations in files. Its ability to identify blocks with markers ensures precision and idempotence, making it ideal for complex system administration tasks.
Explore the Ansible lineinfile module if you want to add/update a single line in a specific file.
FAQs
1. How do I manage the indentation of blocks in configuration files?
To control indentation, include the necessary whitespace within the block content. Ansible will respect the formatting you provide.
2. Is it possible to include variables within the block content?
Yes, you can include variables using Jinja2 syntax (e.g., {{ variable_name }}) within the block parameter.
3. How do I ensure the playbook doesn’t overwrite manual changes in a block?
The blockinfile module replaces the block entirely if it differs from the playbook’s content. To retain manual changes, manage those lines outside the block.