The same way there is a module lineinfile
to add one line in a file, is there a way to add several lines?
I do not want to use a template because you have to provide the whole file. I just want to add something to an existing file without necessarily knowing what the file already contains so a template is not an option.
This question is related to
ansible
I was able to do that by using \n
in the line parameter.
It is specially useful if the file can be validated, and adding a single line generates an invalid file.
In my case, I was adding AuthorizedKeysCommand
and AuthorizedKeysCommandUser
to sshd_config, with the following command:
- lineinfile: dest=/etc/ssh/sshd_config line='AuthorizedKeysCommand /etc/ssh/ldap-keys\nAuthorizedKeysCommandUser nobody' validate='/usr/sbin/sshd -T -f %s'
Adding only one of the options generates a file that fails validation.
You can use a loop to do it. Here's an example using a with_items
loop:
- name: Set some kernel parameters
lineinfile:
dest: /etc/sysctl.conf
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
with_items:
- { regexp: '^kernel.shmall', line: 'kernel.shmall = 2097152' }
- { regexp: '^kernel.shmmax', line: 'kernel.shmmax = 134217728' }
- { regexp: '^fs.file-max', line: 'fs.file-max = 65536' }
To add multiple lines you can use lineinfile
module with with_items
also including variable vars
here to make it simple :)
---
- hosts: localhost #change Host group as par inventory
gather_facts: no
become: yes
vars:
test_server: "10.168.1.1"
test_server_name: "test-server"
file_dest: "/etc/test/test_agentd.conf"
- name: configuring test.conf
lineinfile:
dest: "{{ item.dest }}"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
with_items:
- { dest: '"{{ file_dest }}"', regexp: 'Server=', line: 'Server="{{test_server}}"' }
- { dest: '"{{ file_dest }}"', regexp: 'ServerActive=', line: 'ServerActive="{{test_server}}"' }
- { dest: '"{{ file_dest }}"', regexp: 'Hostname=', line: 'Hostname="{{test_server_name}}"' }
You can try using blockinfile
instead.
You can do something like
- blockinfile: |
dest=/etc/network/interfaces backup=yes
content="iface eth0 inet static
address 192.168.0.1
netmask 255.255.255.0"
To add multiple Lines in a configuration file you can use " "
instead of ' '
and escape sequence \n
for the new line in lineinfile
ansible module:
- name: Configure core-site.xml
lineinfile:
path: /etc/hadoop/core-site.xml
insertafter: '^<configuration>'
line: "Line 1 \n Line 2 \n Line 3"
To add multiple lines you can use blockfile:
- name: Add mappings to /etc/hosts
blockinfile:
path: /etc/hosts
block: |
'10.10.10.10 server.example.com'
'10.10.10.11 server1.example.com'
to Add one line you can use lininfile:
- name: server.example.com in /etc/hosts
lineinfile:
path: /etc/hosts
line: '192.0.2.42 server.example.com server'
state: present
Here is a noise-free version of the solution which is to use with_items:
- name: add lines
lineinfile:
dest: fruits.txt
line: '{{ item }}'
with_items:
- 'Orange'
- 'Apple'
- 'Banana'
For each item, if the item exists in fruits.txt no action is taken.
If the item does not exist it will be appended to the end of the file.
Easy-peasy.
It's not ideal, but you're allowed multiple calls to lineinfile
. Using that with insert_after
, you can get the result you want:
- name: Set first line at EOF (1/3)
lineinfile: dest=/path/to/file regexp="^string 1" line="string 1"
- name: Set second line after first (2/3)
lineinfile: dest=/path/to/file regexp="^string 2" line="string 2" insertafter="^string 1"
- name: Set third line after second (3/3)
lineinfile: dest=/path/to/file regexp="^string 3" line="string 3" insertafter="^string 2"
If you need to configure a set of unique property=value lines, I recommend a more concise loop. For example:
- name: Configure kernel parameters
lineinfile:
dest: /etc/sysctl.conf
regexp: "^{{ item.property | regex_escape() }}="
line: "{{ item.property }}={{ item.value }}"
with_items:
- { property: 'kernel.shmall', value: '2097152' }
- { property: 'kernel.shmmax', value: '134217728' }
- { property: 'fs.file-max', value: '65536' }
Using a dict as suggested by Alix Axel and adding automatic removing of matching commented out entries,
- name: Configure IPV4 Forwarding
lineinfile:
path: /etc/sysctl.conf
regexp: "^#? *{{ item.key | regex_escape() }}="
line: "{{ item.key }}={{ item.value }}"
with_dict:
'net.ipv4.ip_forward': 1
Source: Stackoverflow.com