<h5 dir="auto">ISSUE TYPE</h5>

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

<h5 dir="auto">ANSIBLE VERSION</h5>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="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, Nov  6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]
"><pre class="notranslate"><code class="notranslate">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, Nov  6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]

</code></pre></div>
<h5 dir="auto">CONFIGURATION</h5>
<p dir="auto">my ansible configured as follow:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="[defaults]
gathering = smart
fact_caching_timeout = 2592000
fact_caching = redis
fact_caching_connection = localhost:6379
host_key_checking = False
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
pipelining = False
[persistent_connection]
connect_timeout = 30
connect_retries = 30
connect_interval = 1
[accelerate]
[selinux]
[colors]
[diff]"><pre class="notranslate"><code class="notranslate">[defaults]
gathering = smart
fact_caching_timeout = 2592000
fact_caching = redis
fact_caching_connection = localhost:6379
host_key_checking = False
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
pipelining = False
[persistent_connection]
connect_timeout = 30
connect_retries = 30
connect_interval = 1
[accelerate]
[selinux]
[colors]
[diff]
</code></pre></div>
<h5 dir="auto">OS / ENVIRONMENT</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="CentOS Linux release 7.2.1511 (Core)
Linux localhost.localdomain 3.10.0-327.el7.x86_64 #1 SMP Thu Nov 19 22:10:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
Python 2.7.5"><pre class="notranslate"><code class="notranslate">CentOS Linux release 7.2.1511 (Core)
Linux localhost.localdomain 3.10.0-327.el7.x86_64 #1 SMP Thu Nov 19 22:10:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
Python 2.7.5
</code></pre></div>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto">**I use redis to cache ansible facts, but when redis's key expires, I can't use ansible-plabook to perform the host group operation, but I can use Playbook for a single host operation<br>
also,If I cache facts early, then this playbook can be normal。<br>
**</p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>
<p dir="auto">the full traceback was:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Traceback (most recent call last):
  File &quot;/usr/bin/ansible-playbook&quot;, line 109, in &lt;module&gt;
    exit_code = cli.run()
  File &quot;/usr/lib/python2.7/site-packages/ansible/cli/playbook.py&quot;, line 154, in run
    results = pbex.run()
  File &quot;/usr/lib/python2.7/site-packages/ansible/executor/playbook_executor.py&quot;, line 153, in run
    result = self._tqm.run(play=play)
  File &quot;/usr/lib/python2.7/site-packages/ansible/executor/task_queue_manager.py&quot;, line 264, in run
    start_at_done = self._start_at_done,
  File &quot;/usr/lib/python2.7/site-packages/ansible/executor/play_iterator.py&quot;, line 213, in __init__
    if host.name in variable_manager._fact_cache and variable_manager._fact_cache.get(host.name).get('module_setup', False):
AttributeError: 'NoneType' object has no attribute 'get'"><pre class="notranslate"><code class="notranslate">Traceback (most recent call last):
  File "/usr/bin/ansible-playbook", line 109, in &lt;module&gt;
    exit_code = cli.run()
  File "/usr/lib/python2.7/site-packages/ansible/cli/playbook.py", line 154, in run
    results = pbex.run()
  File "/usr/lib/python2.7/site-packages/ansible/executor/playbook_executor.py", line 153, in run
    result = self._tqm.run(play=play)
  File "/usr/lib/python2.7/site-packages/ansible/executor/task_queue_manager.py", line 264, in run
    start_at_done = self._start_at_done,
  File "/usr/lib/python2.7/site-packages/ansible/executor/play_iterator.py", line 213, in __init__
    if host.name in variable_manager._fact_cache and variable_manager._fact_cache.get(host.name).get('module_setup', False):
AttributeError: 'NoneType' object has no attribute 'get'
</code></pre></div>

<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content=""><pre class="notranslate"></pre></div>

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

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


<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=""><pre class="notranslate"><code class="notranslate">
</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">redis.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 = /home/dkimsey/redis/ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.5 (default, Nov 20 2015, 02:00:19) [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 = /home/dkimsey/redis/ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.5 (default, Nov 20 2015, 02:00:19) [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)]
</code></pre></div>
<h5 dir="auto">CONFIGURATION</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="[defaults]
gathering = smart

# just demo a small amount please
gather_subset = virtual

fact_caching = redis
fact_caching_connection = localhost:6379:1
# 5s
fact_caching_timeout = 5

[privilege_escalation]
become=False"><pre class="notranslate"><code class="notranslate">[defaults]
gathering = smart

# just demo a small amount please
gather_subset = virtual

fact_caching = redis
fact_caching_connection = localhost:6379:1
# 5s
fact_caching_timeout = 5

[privilege_escalation]
become=False
</code></pre></div>
<h5 dir="auto">OS / ENVIRONMENT</h5>
<p dir="auto">RHEL 7/OS X</p>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto">The redis cache plugin will not return facts when the data expires mid-run. It raises a KeyError but that does not seem to trigger a re-gather-facts for those hosts.</p>
<p dir="auto">The jsonfile and in-memory facts appear to return the old, expired data.</p>
<p dir="auto">I believe the desired behavior should be a KeyError in <code class="notranslate">smart</code> mode should trigger a re-gathering of facts for those hosts.</p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>
<p dir="auto">Using the aforementioned ansible.cfg settings, the following playbook will demo the expiring between plays. Note if one were to use jsonfile or no-cache (in-memory?) it works correctly and maintains the data the entire run.</p>
<p dir="auto"><strong>Playbook: <code class="notranslate">demo.yml</code>:</strong></p>
<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="
- hosts: localhost
  connection: local
  tasks:
      - name: Facts gathereed OK
        debug:
            var: ansible_date_time.epoch
      - name: Sleep for a few seconds
        command: sleep 2

- hosts: localhost
  connection: local
  tasks:
      - name: Facts from previous run OK
        debug:
            var: ansible_date_time.epoch
      - name: Sleep for 4s
        command: sleep 4

- hosts: localhost
  connection: local
  tasks:
      - name: Facts from previous run NOT OK
        debug:
            var: ansible_date_time.epoch"><pre class="notranslate">- <span class="pl-ent">hosts</span>: <span class="pl-s">localhost</span>
  <span class="pl-ent">connection</span>: <span class="pl-s">local</span>
  <span class="pl-ent">tasks</span>:
      - <span class="pl-ent">name</span>: <span class="pl-s">Facts gathereed OK</span>
        <span class="pl-ent">debug</span>:
            <span class="pl-ent">var</span>: <span class="pl-s">ansible_date_time.epoch</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Sleep for a few seconds</span>
        <span class="pl-ent">command</span>: <span class="pl-s">sleep 2</span>

- <span class="pl-ent">hosts</span>: <span class="pl-s">localhost</span>
  <span class="pl-ent">connection</span>: <span class="pl-s">local</span>
  <span class="pl-ent">tasks</span>:
      - <span class="pl-ent">name</span>: <span class="pl-s">Facts from previous run OK</span>
        <span class="pl-ent">debug</span>:
            <span class="pl-ent">var</span>: <span class="pl-s">ansible_date_time.epoch</span>
      - <span class="pl-ent">name</span>: <span class="pl-s">Sleep for 4s</span>
        <span class="pl-ent">command</span>: <span class="pl-s">sleep 4</span>

- <span class="pl-ent">hosts</span>: <span class="pl-s">localhost</span>
  <span class="pl-ent">connection</span>: <span class="pl-s">local</span>
  <span class="pl-ent">tasks</span>:
      - <span class="pl-ent">name</span>: <span class="pl-s">Facts from previous run NOT OK</span>
        <span class="pl-ent">debug</span>:
            <span class="pl-ent">var</span>: <span class="pl-s">ansible_date_time.epoch</span></pre></div>
<p dir="auto"><strong>Command:</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ansible-playbook -i localhost, ./demo.yml"><pre class="notranslate"><code class="notranslate">ansible-playbook -i localhost, ./demo.yml
</code></pre></div>
<h5 dir="auto">EXPECTED RESULTS</h5>
<p dir="auto">Either maintain consistency with other fact caching mechanisms and the fact should never change during the run.<br>
OR<br>
A more-correct solution I feel is the third Play should refresh expired facts.</p>
<h5 dir="auto">ACTUAL RESULTS</h5>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ ansible-playbook -i localhost, ./demo.yml

PLAY [localhost] *******************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [localhost]

TASK [Facts gathereed OK] **********************************************************************************************
ok: [localhost] =&gt; {
    &quot;ansible_date_time.epoch&quot;: &quot;1504289061&quot;,
    &quot;changed&quot;: false
}

TASK [Sleep for a few seconds] *****************************************************************************************
changed: [localhost]

PLAY [localhost] *******************************************************************************************************

TASK [Facts from previous run OK] **************************************************************************************
ok: [localhost] =&gt; {
    &quot;ansible_date_time.epoch&quot;: &quot;1504289061&quot;,
    &quot;changed&quot;: false
}

TASK [Sleep for 4s] ****************************************************************************************************
changed: [localhost]

PLAY [localhost] *******************************************************************************************************

TASK [Facts from previous run NOT OK] **********************************************************************************
ok: [localhost] =&gt; {
    &quot;ansible_date_time.epoch&quot;: &quot;VARIABLE IS NOT DEFINED!&quot;,
    &quot;changed&quot;: false
}

PLAY RECAP *************************************************************************************************************
localhost                  : ok=6    changed=2    unreachable=0    failed=0
"><pre class="notranslate"><code class="notranslate">$ ansible-playbook -i localhost, ./demo.yml

PLAY [localhost] *******************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************
ok: [localhost]

TASK [Facts gathereed OK] **********************************************************************************************
ok: [localhost] =&gt; {
    "ansible_date_time.epoch": "1504289061",
    "changed": false
}

TASK [Sleep for a few seconds] *****************************************************************************************
changed: [localhost]

PLAY [localhost] *******************************************************************************************************

TASK [Facts from previous run OK] **************************************************************************************
ok: [localhost] =&gt; {
    "ansible_date_time.epoch": "1504289061",
    "changed": false
}

TASK [Sleep for 4s] ****************************************************************************************************
changed: [localhost]

PLAY [localhost] *******************************************************************************************************

TASK [Facts from previous run NOT OK] **********************************************************************************
ok: [localhost] =&gt; {
    "ansible_date_time.epoch": "VARIABLE IS NOT DEFINED!",
    "changed": false
}

PLAY RECAP *************************************************************************************************************
localhost                  : ok=6    changed=2    unreachable=0    failed=0

</code></pre></div>