I have a simple file at /etc/foo.txt. The file contains the following:
#bar
I have the following ansible playbook task to uncomment the line above:
- name: test lineinfile
lineinfile: backup=yes state=present dest=/etc/foo.txt
regexp='^#bar'
line='bar'
When I first run ansible-playbook, the line gets uncommented and the /etc/foo.txt now contains the following:
bar
However, if I run ansible-playbook again, I get the following:
bar
bar
If I run it yet again, then the /etc/foo.txt file will look like this:
bar
bar
bar
How to avoid this duplications of lines? I just want to uncomment the '#bar' and be done with it.
You need to add backrefs=yes if you don't want to change your regular expression.
- name: test lineinfile
lineinfile: backup=yes state=present dest=/etc/foo.txt
regexp='^#bar' backrefs=yes
line='bar'
This changes the behavior of lineinfile from:
find
if found
replace line found
else
add line
to:
find
if found
replace line found
In other words, this makes operation idempotent.
The problem is the task's regex only matches the commented out line, #bar
. To be idempotent, the lineinfile task needs to match both the commented and uncommented state of the line. This way it will uncomment #bar
but will pass bar
unchanged.
This task should do what you want:
- name: test lineinfile
lineinfile:
backup=yes
state=present
dest=/etc/foo.txt
regexp='^#?bar'
line='bar'
Note the only change was adding a "?" to the regex.
See https://github.com/ansible/ansible/issues/4531.
The solution is to not replace the commented out line, but to add an additional line, while keeping the original there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With