<h5 dir="auto">ISSUE TYPE</h5>
<ul dir="auto">
<li>Bug Report</li>
</ul>
<h5 dir="auto">COMPONENT NAME</h5>
<p dir="auto">retries ... until</p>
<h5 dir="auto">ANSIBLE VERSION</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="2.2.0.0"><pre class="notranslate"><code class="notranslate">2.2.0.0
</code></pre></div>
<h5 dir="auto">CONFIGURATION</h5>
<p dir="auto">default</p>
<h5 dir="auto">OS / ENVIRONMENT</h5>
<p dir="auto">Ubuntu 16.04</p>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto">In my playbooks, I often use a variable in 'retries' in order to be able to adjust this value.<br>
When I want do disable the 'retries' with 0, 'until' expression is not evaluated, which results in a different behavior than when I use 'retries' &gt; 0.</p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>
<p dir="auto">Use this playbook:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="- hosts: all
  gather_facts: false
  tasks:
  - command: &quot;echo this is an error&quot;
    retries: &quot;{{ nb_retries }}&quot;
    delay: 1
    register: result
    until: '&quot;error&quot; not in result.stdout'"><pre class="notranslate"><code class="notranslate">- hosts: all
  gather_facts: false
  tasks:
  - command: "echo this is an error"
    retries: "{{ nb_retries }}"
    delay: 1
    register: result
    until: '"error" not in result.stdout'
</code></pre></div>
<p dir="auto">If I use nb_retries = 1, task fails (expected behavior) :</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ansible-playbook -c local -i &quot;localhost,&quot; site.yml -e nb_retries=1"><pre class="notranslate"><code class="notranslate">ansible-playbook -c local -i "localhost," site.yml -e nb_retries=1
</code></pre></div>
<p dir="auto">If I use nb_retries = 0, task succeeded :</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ansible-playbook -c local -i &quot;localhost,&quot; site.yml -e nb_retries=0"><pre class="notranslate"><code class="notranslate">ansible-playbook -c local -i "localhost," site.yml -e nb_retries=0
</code></pre></div>
<p dir="auto">To fix that, I need to overwrite 'failed_when' expression which makes an inverted duplicate of 'until' :</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="- hosts: all
  gather_facts: false
  tasks:
  - command: &quot;echo this is an error&quot;
    retries: &quot;{{ nb_retries }}&quot;
    delay: 1
    register: result
    failed_when: '&quot;error&quot; in result.stdout'
    until: '&quot;error&quot; not in result.stdout'"><pre class="notranslate"><code class="notranslate">- hosts: all
  gather_facts: false
  tasks:
  - command: "echo this is an error"
    retries: "{{ nb_retries }}"
    delay: 1
    register: result
    failed_when: '"error" in result.stdout'
    until: '"error" not in result.stdout'
</code></pre></div>
<h5 dir="auto">EXPECTED RESULTS</h5>
<p dir="auto">Both commands fails (with retries=0 or retries=1)</p>
<h5 dir="auto">ACTUAL RESULTS</h5>


<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ ansible-playbook -c local -i &quot;localhost,&quot; site.yml -e nb_retries=0
PLAY [all] *********************************************************************

TASK [command] *****************************************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=0   
"><pre class="notranslate"><code class="notranslate">$ ansible-playbook -c local -i "localhost," site.yml -e nb_retries=0
PLAY [all] *********************************************************************

TASK [command] *****************************************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=0   

</code></pre></div>
<h5 dir="auto">ISSUE TYPE</h5>

<ul dir="auto">
<li>Bug Report</li>
</ul>
<h5 dir="auto">COMPONENT NAME</h5>

<p dir="auto">/usr/lib/python2.7/site-packages/ansible/modules/system/pamd.py</p>
<h5 dir="auto">ANSIBLE VERSION</h5>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# ansible --version
ansible 2.3.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.5 (default, Aug 29 2016, 10:12:21) [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]"><pre class="notranslate"><code class="notranslate"># ansible --version
ansible 2.3.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.5 (default, Aug 29 2016, 10:12:21) [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]
</code></pre></div>
<h5 dir="auto">CONFIGURATION</h5>

<h5 dir="auto">OS / ENVIRONMENT</h5>

<h5 dir="auto">SUMMARY</h5>

<p dir="auto">The last pamd.py update has a bug, after/before state duplicate lines, is not idempotent. I took the library from pamd-fixes (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="236628733" data-permission-text="Title is private" data-url="https://github.com/ansible/ansible/issues/25817" data-hovercard-type="pull_request" data-hovercard-url="/ansible/ansible/pull/25817/hovercard" href="https://github.com/ansible/ansible/pull/25817">#25817</a>).</p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>


<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="
---
- hosts: lab
  gather_facts: yes
  remote_user: gnfux
  become: yes
  become_method: sudo
  tasks:
    - name: &quot;Ensure cryptographic hash and rember last 6 pwd /etc/pam.d/system-auth&quot;
      become: yes
      pamdl:
        path: /etc/pam.d/
        name: system-auth
        type: password
        control: requisite
        module_path: pam_cracklib.so
        new_type: password
        new_control: sufficient
        new_module_path: pam_unix.so
        module_arguments: 'remember=6 sha512 shadow nullok try_first_pass use_authtok'
        state: after"><pre class="notranslate">---
- <span class="pl-ent">hosts</span>: <span class="pl-s">lab</span>
  <span class="pl-ent">gather_facts</span>: <span class="pl-s">yes</span>
  <span class="pl-ent">remote_user</span>: <span class="pl-s">gnfux</span>
  <span class="pl-ent">become</span>: <span class="pl-s">yes</span>
  <span class="pl-ent">become_method</span>: <span class="pl-s">sudo</span>
  <span class="pl-ent">tasks</span>:
    - <span class="pl-ent">name</span>: <span class="pl-s"><span class="pl-pds">"</span>Ensure cryptographic hash and rember last 6 pwd /etc/pam.d/system-auth<span class="pl-pds">"</span></span>
      <span class="pl-ent">become</span>: <span class="pl-s">yes</span>
      <span class="pl-ent">pamdl</span>:
        <span class="pl-ent">path</span>: <span class="pl-s">/etc/pam.d/</span>
        <span class="pl-ent">name</span>: <span class="pl-s">system-auth</span>
        <span class="pl-ent">type</span>: <span class="pl-s">password</span>
        <span class="pl-ent">control</span>: <span class="pl-s">requisite</span>
        <span class="pl-ent">module_path</span>: <span class="pl-s">pam_cracklib.so</span>
        <span class="pl-ent">new_type</span>: <span class="pl-s">password</span>
        <span class="pl-ent">new_control</span>: <span class="pl-s">sufficient</span>
        <span class="pl-ent">new_module_path</span>: <span class="pl-s">pam_unix.so</span>
        <span class="pl-ent">module_arguments</span>: <span class="pl-s"><span class="pl-pds">'</span>remember=6 sha512 shadow nullok try_first_pass use_authtok<span class="pl-pds">'</span></span>
        <span class="pl-ent">state</span>: <span class="pl-s">after</span></pre></div>

<h5 dir="auto">EXPECTED RESULTS</h5>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/etc/pam.d/system-auth
auth      	required	pam_env.so
auth      	required	pam_tally2.so deny=5 onerr=fail
auth      	sufficient	pam_unix.so nullok try_first_pass
auth      	requisite	pam_succeed_if.so uid &gt;= 1000 quiet_success
auth      	required	pam_deny.so

password  	requisite	pam_cracklib.so retry=5 minlen=6 dcredit=-1 ucredit=0 lcredit=-1 ocredit=0 reject_username
password  	sufficient	pam_unix.so remember=6 sha512 shadow nullok try_first_pass use_authtok
password  	sufficient	pam_sss.so use_authtok
password  	required	pam_deny.so
"><pre class="notranslate"><code class="notranslate">/etc/pam.d/system-auth
auth      	required	pam_env.so
auth      	required	pam_tally2.so deny=5 onerr=fail
auth      	sufficient	pam_unix.so nullok try_first_pass
auth      	requisite	pam_succeed_if.so uid &gt;= 1000 quiet_success
auth      	required	pam_deny.so

password  	requisite	pam_cracklib.so retry=5 minlen=6 dcredit=-1 ucredit=0 lcredit=-1 ocredit=0 reject_username
password  	sufficient	pam_unix.so remember=6 sha512 shadow nullok try_first_pass use_authtok
password  	sufficient	pam_sss.so use_authtok
password  	required	pam_deny.so

</code></pre></div>
<h5 dir="auto">ACTUAL RESULTS</h5>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/etc/pam.d/system-auth

auth      	required	pam_env.so
auth      	required	pam_tally2.so deny=5 onerr=fail
auth      	sufficient	pam_unix.so nullok try_first_pass
auth      	requisite	pam_succeed_if.so uid &gt;= 1000 quiet_success
auth      	required	pam_deny.so

password  	requisite	pam_cracklib.so retry=5 minlen=6 dcredit=-1 ucredit=0 lcredit=-1 ocredit=0 reject_username
password  	sufficient	pam_unix.so remember=6 sha512 shadow nullok try_first_pass use_authtok
password  	sufficient	pam_unix.so remember=6 sha512 shadow nullok try_first_pass use_authtok
password  	sufficient	pam_sss.so use_authtok
password  	required	pam_deny.so"><pre class="notranslate"><code class="notranslate">/etc/pam.d/system-auth

auth      	required	pam_env.so
auth      	required	pam_tally2.so deny=5 onerr=fail
auth      	sufficient	pam_unix.so nullok try_first_pass
auth      	requisite	pam_succeed_if.so uid &gt;= 1000 quiet_success
auth      	required	pam_deny.so

password  	requisite	pam_cracklib.so retry=5 minlen=6 dcredit=-1 ucredit=0 lcredit=-1 ocredit=0 reject_username
password  	sufficient	pam_unix.so remember=6 sha512 shadow nullok try_first_pass use_authtok
password  	sufficient	pam_unix.so remember=6 sha512 shadow nullok try_first_pass use_authtok
password  	sufficient	pam_sss.so use_authtok
password  	required	pam_deny.so
</code></pre></div>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=""><pre class="notranslate"><code class="notranslate">
</code></pre></div>