# lineinfile reporting 'changed' status when changes aren't needed

**URL:** <https://forum.ansible.com/t/lineinfile-reporting-changed-status-when-changes-arent-needed/14789>\
**Category:** Ansible Project\
**Created:** [March 16, 2014, 5:14am UTC](https://forum.ansible.com/t/lineinfile-reporting-changed-status-when-changes-arent-needed/14789 "2014-03-16T05:14:12Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michael\_Krieger](https://avatars.discourse-cdn.com/v4/letter/m/ecae2f/32.png) [@Michael\_Krieger](https://forum.ansible.com/u/Michael_Krieger)\
**Post date:** [March 16, 2014, 5:14am UTC](https://forum.ansible.com/t/lineinfile-reporting-changed-status-when-changes-arent-needed/14789/1 "2014-03-16T05:14:12Z")

</div>

Foremost, I know the ‘best practice’ is to use the copy command for items such as this, however one goal is to keep the package-installed config files for basic system tools as close to the original package version to ease upgrades of systems and operating systems down the road and make easy ‘diffs’ as to what may have changed in a package maintainer’s version of the file. I don’t do this for essential types of programs, but for tweaking a couple options from the package maintainers, I like it this way. Now on to the example:

**I have a task as follows that basically changes some commented out options and replaces the line with uncommented versions**. For anyone who is seeing this as an example, I also have a handler caleld ‘restart denyhosts’ to complete this example.

- name: configure denyhosts  
lineinfile: dest=/etc/denyhosts.conf regexp=‘{{ item.re }}’ line=‘{{ item.ln }}’  
with\_items:
- { re: ‘^PURGE\_DENY =$’, ln: ‘#PURGE\_DENY =’ }
- { re: ‘^#PURGE\_DENY = 1w$’, ln: ‘PURGE\_DENY = 1w’ }
- { re: ‘^DENY\_THRESHOLD\_ROOT = 1$’, ln: ‘DENY\_THRESHOLD\_ROOT = 5’ }
- { re: ‘^#RESET\_ON\_SUCCESS = yes$’, ln: ‘RESET\_ON\_SUCCESS = yes’ }
- { re: '^ADMIN\_EMAIL = ', ln: ‘ADMIN\_EMAIL =’ }  
notify: restart denyhosts  
tags: denyhostsconfig

**The result on execution is as follows:**  
TASK: [common | configure denyhosts] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
changed: [clover.domain.tld] =\> (item={‘ln’: ‘#PURGE\_DENY =’, ‘re’: ‘^PURGE\_DENY =$’})  
changed: [clover.domain.tld] =\> (item={‘ln’: ‘PURGE\_DENY = 1w’, ‘re’: ‘^#PURGE\_DENY = 1w$’})  
changed: [clover.domain.tld] =\> (item={‘ln’: ‘DENY\_THRESHOLD\_ROOT = 5’, ‘re’: ‘^DENY\_THRESHOLD\_ROOT = 1$’})  
changed: [clover.domain.tld] =\> (item={‘ln’: ‘RESET\_ON\_SUCCESS = yes’, ‘re’: ‘^#RESET\_ON\_SUCCESS = yes$’})  
changed: [clover.domain.tld] =\> (item={‘ln’: ‘ADMIN\_EMAIL =’, ‘re’: '^ADMIN\_EMAIL = '})  
NOTIFIED: [common | restart denyhosts] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
changed: [clover.domain.tld]  
PLAY RECAP \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
clover.domain.tld : ok=3 changed=2 unreachable=0 failed=0

**THE QUESTION**  
The file has already been changed by running this once and contains NONE of those ‘regexp’ lines. Meanwhile, the lineinfile is showing changed on each one of them.  
How can I get this command to show as unchanged if those lines don’t match?

Obviously I can add changed\_when: False to that statement, but then it’ll never tell me if it actually made those changes, as it will always return ‘ok’.

**Can lineinfile simply return changed only if the line on the regexp is found?**

-Michael
