How to add new line in ansible playbook - ansible

I am trying to add new line in yaml configuration file through ansible playbook using lineinfile. What I have tried till now.
#attempt-1
- name: "Configure Node River"
lineinfile: "dest=/path/to/config.conf line='node.river: river_name'"
#attempt-2
- name: "Configure Node River"
lineinfile: "dest=/path/to/config.conf state=present regexp='^' line='node.river: river_name'"
Also I have tried as per reference document.
# Add a line to a file if it does not exist, without passing regexp
- lineinfile: dest=/tmp/testfile line="192.168.1.99 foo.lab.net foo"
Can anyone guide me how to add new line which is not present in file. I know I can add End of the File by adding regexp='' insertafter=EOF in my #attempt-1. But I want to add above line in middle of the file.

As I understand you can use insertafter=<regexp>:
--- play.yml
- hosts: localhost
gather_facts: False
tasks:
- name: "Configure Node River"
local_action: 'lineinfile dest=/home/ig/test.conf
line="node.river: river_name" insertafter="first line"'
test.conf before:
first line
second line
test conf after:
first line
node.river: river_name
second line

Related

Ansible lineinfile command error when not using "tasks:" before the lineinfile items

I'm with a problem when running lineinfile command. I've written the following script, which works like a charm:
- hosts: centos1
user: root
tasks:
- name: Replace nsswitch.conf passwd configuration
lineinfile:
path: /etc/nsswitch.conf
regexp: "^passwd:" #line to be searched
line: "passwd: xxx yyy zzz" # new line replacing the above
state: present
create: True
when: ansible_os_family == 'RedHat' and ansible_distribution_major_version|int >= 8
but on the prod server, yml scripts are summoned by a "main.yml", more or less like this:
---
include: script1.yml
include: script2.yml
include: myscript.yml
...
and then I was requested by my senior analyst to remove the "hosts", "user" and "tasks" from the final version, and add a tag on each lineinfile entry, which looked like this:
- name: Replace nsswitch.conf passwd configuration
lineinfile:
path: /etc/nsswitch.conf
regexp: "^passwd:" #line to be searched
line: "passwd: files sss systemd" # new line replacing the above
state: present
create: True
when: ansible_os_family == 'RedHat' and ansible_distribution_major_version|int >= 8
tags:
- nsswwitch_change
but now when I run the playbook, either through my yml file or the main file, I get the following error:
ansible-playbook 2.9.27
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /bin/ansible-playbook
python version = 2.7.5 (default, Aug 13 2020, 02:51:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
Using /etc/ansible/ansible.cfg as config file
host_list declined parsing /tmp/hosts as it did not pass its verify_file() method
script declined parsing /tmp/hosts as it did not pass its verify_file() method
auto declined parsing /tmp/hosts as it did not pass its verify_file() method
Parsed /tmp/hosts inventory source with ini plugin
ERROR! 'lineinfile' is not a valid attribute for a Play
The error appears to be in '/app/ansible/roles/linux-sap-hana/tasks/raul-mnsswitch.yml': line 26, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- name: Replace nsswitch.conf passwd configuration
^ here
I'm literally out of ideas, because the only way I was able to make it work was adding the host, user and tasks at the beggining of the playbook.
Any help would be appreciated folks, thanks a lot in advance.
If you top-level playbook looks like this:
include: script1.yml
include: script2.yml
include: myscript.yml
Then each of those included documents needs to be a playbook: that means it needs to be a list of plays, not a list of tasks:
- name: play 1
hosts: all
tasks:
...
- name: play 2
hosts: all
tasks:
...
Otherwise, how will Ansible know which hosts to target?
Note that the include module is deprecated:
DEPRECATED
Removed in
version 2.16
Why
it has too many conflicting behaviours depending on keyword combinations and it was unclear how it should behave in each case. new actions were developed that were specific about each case and related behaviours.
Alternative
include_tasks, import_tasks, import_playbook
You should be using import_playbook instead.
If you want to include a list of tasks, you can only do that via the include_tasks or import_tasks modules, as part of task in a play:
- name: play 1
hosts: all
tasks:
- name: import script1
import_tasks: script1.yml
- name: import script2
import_tasks: script2.yml
NB: To make sure you're clear on the nomenclature:
# This entire block is a playbook
# This is a play
- hosts: all
tasks:
# This is a task
- name: Example task 1
debug:
msg: This is an example task
# This is a play
- hosts: all
tasks:
# This is a task
- name: Example task 2
debug:
msg: This is an example task

Ansible playbook - regexp | unable to change data in brackets and quotes

I've been trying to finish up a playbook for deploying a new server. I'm struggling with changing data within brackets containing quotes via lineinfile and a regex:
- name: "Configuring: filebeat agent - configuring output to logstash"
lineinfile:
dest: "/etc/filebeat/filebeat.yml"
regexp: '#hosts: ["localhost:5044"]'
line: 'hosts: ["elk.home:5044"]'
tags: application
After the playbook is executed, the desired line:
#hosts: ["localhost:5044"]
is not updated to reflect:
hosts: ["elk.home:5044"]
What I'm trying to achieve is:
#hosts: ["localhost:5044"] is replaced with hosts: ["elk.home:5044"]
There are no errors generated. I've tried varying " and ' along with escapes \, but I can't get the expression correct. Any suggestions would be greatly appreciated!
Thanks seshadri_c and β.εηοιτ.βε!
I was able to reach a resolution with the following lines:
- name: "Configuring: filebeat agent - enabling logstash output hosts"
lineinfile:
dest: "/etc/filebeat/filebeat.yml"
regexp: '#hosts: \["localhost:5044"\]'
line: 'hosts: ["elk.home:5044"]'
tags:
- configuration
- application
- filebeat
After completing the playbook, I had an issue with whitespace. I added two spaces that correctly modified the line
- name: "Configuring: filebeat agent - enabling logstash output hosts"
lineinfile:
dest: "/etc/filebeat/filebeat.yml"
regexp: '#hosts: \["localhost:5044"\]'
line: ' hosts: ["elk.home:5044"]'
tags:
- configuration
- application
- filebeat

Ansible lineinfile adds new line before edit

I'm trying to edit the value of existing line without overriding it, when I run the playbook it adds the value in a new line
Line: server=foo
Value I'm trying to add: boo
Exception:
Line: server=foo,boo
Result:
Line: server=foo,
boo
Code:
- name: Update
lineinfile:
path: "{{ file_path }}"
backrefs: yes
regexp: '(server=.*)'
line: '\1,boo'
Resolved, since I run on WSL I had to do dos2unix and after edits unix2dos
and no extra new line added

Ansible Playbook keeps adding ^M to my files

I have the below ansible playbook where i am identifying a string in a file and replacing it with another
---
- name: Ansible Playbook
hosts: webserver1
remote_user: user45
tasks:
- name: Replacing content with other
lineinfile:
path: /home/user45/run.sh
regexp: '^(.*)DEBUG=(.*)$'
line: 'DEBUG=ON'
the above works, but it adds ^M to the end of every other line in that file and every blank line
From what I have read online this normally occurs when you copy and paste from Windows to Linux but i typed this out manually so i am kind of stumped
Playbook is running on Linux Redhat 7
Please verify your script "/home/user45/run.sh".Looks like carriage-return character exist in there.
For whatever reason lineinfile was adding the ^M .. If I change it to use replace module it does not add the ^M bits
---
- name: Ansible Playbook
hosts: webserver1
remote_user: user45
tasks:
- name: Replacing content with other
replace:
dest: /home/user45/run.sh
regexp: 'DEBUG=.*'
line: 'DEBUG=ON'
This problem has been fixed with this solution on ansible 2.9:
---
- name: Ansible Playbook
hosts: webserver1
remote_user: user45
tasks:
- name: Replacing content with other
replace:
path: /home/user45/run.sh
regexp: 'DEBUG=.*'
replace: 'DEBUG=ON'
Enjoy ;)

Use lineinfile to fill ansible inventory file

I have trivial task to fill particular ansible inventory file with the new deployed VMs names under their roles.
Here is my playbook:
- hosts: 127.0.0.1
tasks:
- name: Add host to inventory file
lineinfile:
dest: "{{inv_path}}"
regexp: '^\[{{role}}\]'
insertafter: '^#\[{{role}}\]'
line: "{{new_host}}"
Instead of adding new line after [role], ansible replace the string with the hostname. My aim is to naturally insert after it. If there is no matched role it should skip add new line.
How to achieve this? Thanks!
[role] is getting replaced because the regexp parameter is the regular expression Ansible will look for to replace with the line parameter. Just move that value to insertafter and get rid of regexp.
As for the other requirement you will need another task that will check if [role] exists first. Then your lineinfile task will evaluate the result of the checker task to determine if it should run.
- name: Check if role is in inventory file
shell: grep [{{ role }}] {{ inv_path }}
ignore_errors: True
register: check_inv
- name: Add host to inventory file
lineinfile:
dest: "{{ inv_path }}"
insertafter: '^\[{{role}}\]$'
line: "{{new_host}}"
when: check_inv.rc == 0

Resources