<h5 dir="auto">ISSUE TYPE</h5>
<ul dir="auto">
<li>Bug Report</li>
</ul>
<h5 dir="auto">ANSIBLE VERSION</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ansible 2.1.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides"><pre class="notranslate"><code class="notranslate">ansible 2.1.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
</code></pre></div>
<h5 dir="auto">CONFIGURATION</h5>
<p dir="auto">Bone stock</p>
<h5 dir="auto">OS / ENVIRONMENT</h5>
<p dir="auto">CentOS 7</p>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto">When lineinfile  with regexp finds a match, it substitutes properly.  When it doesn't find a match (say, on subsequent runs), it just dumps the specified line at the bottom of the file as if you hadn't specified a regexp.  Needless to say, this breaks idempotence.</p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>
<ol dir="auto">
<li>Take a look at a file.</li>
<li>Run lineinfile with regexp that matches a line</li>
<li>See that your line was in fact replaced.</li>
<li>Run lineinfile again.</li>
<li>See that the specified replacement line is now duplicated at the bottom of the file.</li>
</ol>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="- name: Add ops scripts to sudo secure_path
  lineinfile:
    dest: /etc/sudoers
    regexp: &gt;
      ^Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin$
    line: 'Defaults    secure_path = /opt/d7/bin:/sbin:/bin:/usr/sbin:/usr/bin'
    validate: visudo -cf %s"><pre class="notranslate"><code class="notranslate">- name: Add ops scripts to sudo secure_path
  lineinfile:
    dest: /etc/sudoers
    regexp: &gt;
      ^Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin$
    line: 'Defaults    secure_path = /opt/d7/bin:/sbin:/bin:/usr/sbin:/usr/bin'
    validate: visudo -cf %s
</code></pre></div>
<h5 dir="auto">EXPECTED RESULTS</h5>
<p dir="auto">Idempotent line replacement after a second run</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# Refuse to run if unable to disable echo on the tty.
Defaults   !visiblepw

#
# Preserving HOME has security implications since many programs
# use it when searching for configuration files. Note that HOME
# is already set when the the env_reset option is enabled, so
# this option is only effective for configurations where either
# env_reset is disabled or HOME is present in the env_keep list.
#
Defaults    always_set_home

Defaults    env_reset
Defaults    env_keep =  &quot;COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS&quot;
Defaults    env_keep += &quot;MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE&quot;
Defaults    env_keep += &quot;LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES&quot;
Defaults    env_keep += &quot;LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE&quot;
Defaults    env_keep += &quot;LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY&quot;

#
# Adding HOME to env_keep may enable a user to run unrestricted
# commands via sudo.
#
# Defaults   env_keep += &quot;HOME&quot;

Defaults    secure_path = /opt/d7/bin:/sbin:/bin:/usr/sbin:/usr/bin

## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
## Syntax:
##
##      user    MACHINE=COMMANDS
##
## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL

## Allows people in group wheel to run all commands without a password
%wheel        ALL=(ALL)       NOPASSWD: ALL"><pre class="notranslate"><code class="notranslate"># Refuse to run if unable to disable echo on the tty.
Defaults   !visiblepw

#
# Preserving HOME has security implications since many programs
# use it when searching for configuration files. Note that HOME
# is already set when the the env_reset option is enabled, so
# this option is only effective for configurations where either
# env_reset is disabled or HOME is present in the env_keep list.
#
Defaults    always_set_home

Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"

#
# Adding HOME to env_keep may enable a user to run unrestricted
# commands via sudo.
#
# Defaults   env_keep += "HOME"

Defaults    secure_path = /opt/d7/bin:/sbin:/bin:/usr/sbin:/usr/bin

## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
## Syntax:
##
##      user    MACHINE=COMMANDS
##
## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL

## Allows people in group wheel to run all commands without a password
%wheel        ALL=(ALL)       NOPASSWD: ALL
</code></pre></div>
<h5 dir="auto">ACTUAL RESULTS</h5>
<p dir="auto">Potentially show-stopping garbage at the bottom of a file</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# Refuse to run if unable to disable echo on the tty.
Defaults   !visiblepw

#
# Preserving HOME has security implications since many programs
# use it when searching for configuration files. Note that HOME
# is already set when the the env_reset option is enabled, so
# this option is only effective for configurations where either
# env_reset is disabled or HOME is present in the env_keep list.
#
Defaults    always_set_home

Defaults    env_reset
Defaults    env_keep =  &quot;COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS&quot;
Defaults    env_keep += &quot;MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE&quot;
Defaults    env_keep += &quot;LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES&quot;
Defaults    env_keep += &quot;LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE&quot;
Defaults    env_keep += &quot;LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY&quot;

#
# Adding HOME to env_keep may enable a user to run unrestricted
# commands via sudo.
#
# Defaults   env_keep += &quot;HOME&quot;

Defaults    secure_path = /opt/d7/bin:/sbin:/bin:/usr/sbin:/usr/bin

## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
## Syntax:
##
##      user    MACHINE=COMMANDS
##
## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL

## Allows people in group wheel to run all commands without a password
%wheel        ALL=(ALL)       NOPASSWD: ALL
Defaults    secure_path = /opt/d7/bin:/sbin:/bin:/usr/sbin:/usr/bin"><pre class="notranslate"><code class="notranslate"># Refuse to run if unable to disable echo on the tty.
Defaults   !visiblepw

#
# Preserving HOME has security implications since many programs
# use it when searching for configuration files. Note that HOME
# is already set when the the env_reset option is enabled, so
# this option is only effective for configurations where either
# env_reset is disabled or HOME is present in the env_keep list.
#
Defaults    always_set_home

Defaults    env_reset
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"

#
# Adding HOME to env_keep may enable a user to run unrestricted
# commands via sudo.
#
# Defaults   env_keep += "HOME"

Defaults    secure_path = /opt/d7/bin:/sbin:/bin:/usr/sbin:/usr/bin

## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
## Syntax:
##
##      user    MACHINE=COMMANDS
##
## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL

## Allows people in group wheel to run all commands without a password
%wheel        ALL=(ALL)       NOPASSWD: ALL
Defaults    secure_path = /opt/d7/bin:/sbin:/bin:/usr/sbin:/usr/bin
</code></pre></div>
<h5 dir="auto">ISSUE TYPE</h5>

<ul dir="auto">
<li>Bug Report</li>
</ul>
<h5 dir="auto">ANSIBLE VERSION</h5>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ansible 2.1.0.0
  config file = /home/remedy/scenter-playbooks/ansible.cfg
  configured module search path = Default w/o overrides"><pre class="notranslate"><code class="notranslate">ansible 2.1.0.0
  config file = /home/remedy/scenter-playbooks/ansible.cfg
  configured module search path = Default w/o overrides
</code></pre></div>
<h5 dir="auto">CONFIGURATION</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="[defaults]
ask_vault_pass=False"><pre class="notranslate"><code class="notranslate">[defaults]
ask_vault_pass=False
</code></pre></div>
<h5 dir="auto">OS / ENVIRONMENT</h5>
<p dir="auto">N/A</p>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto">lineinfile module creates duplicate lines on the second and subsequent runs if its regexp arg contains quantifiers (+, * etc.)</p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>
<p dir="auto">On the first run this task replaces <code class="notranslate">SELINUX=  #</code> with <code class="notranslate">SELINUX=enforcing</code></p>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="- lineinfile: dest=/etc/selinux/config regexp='^SELINUX=\s+#' line=SELINUX=enforcing"><pre class="notranslate"><code class="notranslate">- lineinfile: dest=/etc/selinux/config regexp='^SELINUX=\s+#' line=SELINUX=enforcing
</code></pre></div>
<p dir="auto">On the subsequent runs this task creates duplicate lines <code class="notranslate">SELINUX=enforcing</code></p>
<h5 dir="auto">EXPECTED RESULTS</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="SELINUX=enforcing"><pre class="notranslate"><code class="notranslate">SELINUX=enforcing
</code></pre></div>
<h5 dir="auto">ACTUAL RESULTS</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="SELINUX=enforcing
SELINUX=enforcing
..."><pre class="notranslate"><code class="notranslate">SELINUX=enforcing
SELINUX=enforcing
...
</code></pre></div>