<h5 dir="auto">ISSUE TYPE</h5>
<ul dir="auto">
<li>Bug Report</li>
</ul>
<h5 dir="auto">COMPONENT NAME</h5>
<p dir="auto">user</p>
<h5 dir="auto">ANSIBLE VERSION</h5>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ansible 2.2.0.0
  config file = /ansible/configuration/ansible.cfg
  configured module search path = Default w/o overrides"><pre class="notranslate"><code class="notranslate">ansible 2.2.0.0
  config file = /ansible/configuration/ansible.cfg
  configured module search path = Default w/o overrides
</code></pre></div>
<h5 dir="auto">OS / ENVIRONMENT</h5>
<p dir="auto">RHEL6 on both source and target</p>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto">The "user" module has an "expires" option to set up the expiration date of a user. This option is using the Epoch format (not very helpful), and it seems it does not take into account the timezone.<br>
In my case, it means that setting a user to expire on 2017-02-18 00:00:00, the user actually expired on 2017-02-17 00:00:00, 24 hours earlier.</p>
<p dir="auto">Since all my systems are set with the CET timezone, I fully expect that an expiration date set using that timezone to be applied consistent to it.<br>
Since the Linux expiration is set using a number of days, and not seconds, it's confusing to say the least to have to deal with a proper time.</p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>
<p dir="auto">Convert a date to Epoch format, this is in local CET timezone:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ date -d &quot;2017-02-18 00:59:59&quot; +%s
1487375999"><pre class="notranslate"><code class="notranslate">$ date -d "2017-02-18 00:59:59" +%s
1487375999
</code></pre></div>
<p dir="auto">Use that value in the "user" module to set a user's expiry date, run the task, then check the actual expiry date:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ sudo chage -l user
Last password change                                : Feb 14, 2017
Password expires                                    : never
Password inactive                                   : never
Account expires                                     : Feb 17, 2017
Minimum number of days between password change      : 0
Maximum number of days between password change      : 99999
Number of days of warning before password expires   : 7"><pre class="notranslate"><code class="notranslate">$ sudo chage -l user
Last password change                                : Feb 14, 2017
Password expires                                    : never
Password inactive                                   : never
Account expires                                     : Feb 17, 2017
Minimum number of days between password change      : 0
Maximum number of days between password change      : 99999
Number of days of warning before password expires   : 7
</code></pre></div>
<h5 dir="auto">EXPECTED RESULTS</h5>
<p dir="auto">I expect the expiry date to be set to the one I used.</p>
<h5 dir="auto">ACTUAL RESULTS</h5>
<p dir="auto">The expiry date was set 24 hours earlier than expected.</p>
<h4 dir="auto">Note</h4>
<p dir="auto">A case was initially opened with RedHat support.</p>
<h5 dir="auto">ISSUE TYPE</h5>
<ul dir="auto">
<li>Feature Idea</li>
</ul>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto">With a fairly complicated and intertwined set of playbooks and roles such as <a href="https://github.com/openshift/openshift-ansible/">openshift-ansible</a> has developed for users to manage OpenShift, a common frustration is when running a playbook takes half an hour to run through dozens of roles and only then fails on something that could have been detected and corrected up front. We would like to enable a playbook run to fail early in common cases where the user hasn't supplied correct configuration or host prerequisites.</p>
<p dir="auto">This seems like something that should be a core competency of Ansible. I'm submitting this issue to discuss the design of features that could help.</p>
<h5 dir="auto">COMPONENT NAME</h5>
<p dir="auto">ansible-playbook and roles</p>
<h5 dir="auto">PROPOSAL</h5>
<p dir="auto">For each role that needs it, provide a set of tasks (perhaps in a subdirectory like <code class="notranslate">validations</code>) that are intended to run before the main tasks of the role or the main tasks of any of its dependencies, with the intent to fail quickly if there are obvious problems that would prevent the role from succeeding. Then Ansible can run through the playbook's role dependency tree twice, once for pre-validations, and once for the usual purpose.</p>
<p dir="auto">The validations of a dependency role should run before the validations of the role that depends on it.</p>
<p dir="auto">Probably the validations should run again during the main run, as runtime could have altered conditionals and even the dependency tree (for dynamic includes). As with check mode, this might imply supplying an awareness of whether a task is running in validation mode or runtime mode.</p>
<h5 dir="auto">ALTERNATE APPROACHES</h5>
<p dir="auto">Some initial ideas for solving under the current implementation that on reflection DO NOT seem like good approaches. The proposal above may prove clearly flawed as well, but hopefully some good ideas are generated.</p>
<ul dir="auto">
<li>Use <code class="notranslate">include_role</code> for all role dependencies; for those with validations, include them twice, first <code class="notranslate">with_tasks: validations.yml</code> (which in turn would invoke the validations of any roles it depends on). The meta.yml couldn't specify any role dependencies (because they would all run before any validation tasks). This is very awkward and requires strict compliance to work at all. Every role would have to be aware of the two modes, even if it didn't have any validations, in case any of its dependencies did or ever gained some in the future. And you'd be specifying each role's dependencies in two places.</li>
<li>Create a role for running validations and include it early in the relevant playbooks.
<ul dir="auto">
<li>Issues would arise from tightly coupling all the roles into this role. With the validation in a central role, do the other roles invoke that central role, or duplicate the validation logic, or just not try?</li>
<li>Different roles are meant to operate on different host groups and so the role would either need to be several roles (one for each host group where validations apply) or would require logic to determine whether validation tasks apply for a given host.</li>
<li>It can be complicated to determine up front which role validations would even be relevant, so as not to require something for a component that's not even being used.</li>
</ul>
</li>
<li>Tag all validation tasks with <code class="notranslate">validation</code> and have the user run the playbook twice, once with <code class="notranslate">--tags validation</code> and once without. It's not clear to me if this could accurately construct the dependency tree with <code class="notranslate">include_role</code> tasks in play, but it may work. To me the larger issue is that this just doesn't meet a user's expectations for how to use the tool, and it's not a very good UX to run it once with almost everything skipped, then run it again "for real".</li>
</ul>