Plans for tonight's development: conditional execution of task steps

Here’s the next feature I am going to add to play books – “only_if”.

  • name: foo
    action: modulename
    only_if: some conditional

This will allow conditional execution of steps, on a host by host basis, based on facts or ohais (is that even the proper plural of ohai? Inquiring minds want to know).

Ex:

  • name: package that should only be installed on CentOS
    action: yum pkg=foo ensure=installed
    only_if: $facter_operatingsystem == ‘Debian’

Which hosts actually execute the step, and which skip the step, will be logged in playbook output.

My goal here, with play books, is to keep the levels of indentation really flat, and the syntax as less like a programming language as possible. This is to make everything extremely auditable for compliance and maintaince purposes, as well as to keep the barrier to entry to the system super small – not having a lot of obscure syntax and remembering when to indent this, or not indent that.

In a very large example, imagine:

  • import: foo.yml
  • import: ntp.yml
  • import: fixup.yml

Suppose in fixup.yml we have a step that should ONLY run on Debian OSes with an operating system version of X.

This will make all that possible, but the logic is not listed in the main playbook, it’s defined well away in the import, so the main playbook is extremely clean, just containing a list of what composes that particular host group in the playbook.

Thus, something really simple (think in Puppet of site.pp) that normally just says “this is a foo, this is a bar”, +1 level of indirection is all you need, rather than having a complex series of files that import other files in somewhat hard to visualize ways.

After that, a brief timeout for some much-deserved refactoring… we’ve grown slightly over 1000 lines in the core (according to slocount), and that can be much shorter to make things easier to contribute to :slight_smile:

–Michael

One of the issues I have run into with extremely clean “books” is later trying to figure out where things went south … will it be possible to make a verbose end book so to speak where the various if else are expanded?

smooge

Definitely. (probably handled by a --verbose flag rather than a playbook setting?)

Of the things I know we need to output but currently do not:

  1. list imported files made/skipped per host

  2. module & args executed per host

there is also some stuff (currently not displayed) to report on success/failed/changed counts once all the hosts are done. I need to reinstate that as it’s pretty useful too … because you can quickly see which hosts you have to go back and look at.

Any other ideas on output/verbosity and things you would like to see in the scroll back?

Hi
The more verbose the better. If I can devise from the log what is happening and how I have miscoded my runbook then that is ideal. The ability to categorize might be nice, similar to 389 director server where I can specify what types of errors/bugs/info I want to see in the log. Just having a -v -vv and -vvv is not helpful. I had to restrain myself not going into a rant about that… I like logging to be specific and if logging can also reveal what the software is doing then it serves it purpose. It means I don’t have to know the code and the only debugging I need is my own runbooks and logic. The clearer I can be about assumptions ansible makes the better. Something that is missing in most modern software is a clear description of internal logic… this can be addressed in two ways, by doing it through very detailed logging or by actually documenting the internal logic and not pointing people to the source. ( I am writing a document on dns resolution on Linux and the differences in libraries and behaviour hence my semi rant )

Then after I get everything working I would like the ability to make ansible very quite.

My 5cents worth.

Regards

Yeah, for short term development purposes we’ll probably make it very squeaky/loud initially and then figure out how to make it selective as I can start to see where the desired levels might be.

I think you have convinced me about making verbosity a playbook setting versus a flag.

Points on making it very clear and logical are well made.

Thanks!

Hi all,

As requested, I've made some upgrades to logging. These are still
yet to be controlled by any kind of verbosity settings, so it's
*quite* noisy, and maybe not the ideal format, but take a look at what
is there.

I have some upgrades in mind to use callbacks to allow both
/bin/ansible and /bin/ansible-playbook to provide even faster realtime
status of what they are doing. This is still pending, so the
capability for more detail is still there.

(SIDENOTE -- as a consequence of the logging upgrades the JSON
datastructures MUST be hashes. They can still be nested, and I've
updated the yum module. I have to inject extra data into the
responses. This is a good thing :))

I like the idea of being able to tune the logging up or down... though
it's not an immediate priority, I am thinking of what Gerhardus said
in that we can probably do something like this at the top of the
playbook, maybe

- debug: 'counts imports invocations results'

This can wait though. I want to organize some things first, but ... in plan!

Here's the output, so you can see about what kind of granularity we
can get. Let me know if you think this is enough or not, keeping in
mind that there's some still not represented here that I can easily
surface.... once there are callbacks plumbed through the runner code,
the level of debug verbosity can be off the charts.

[root@localhost ansible]# ansible-playbook examples/playbooks/playbook.yml -T 2

PLAY [all] ****************************

SETUP PHASE ****************************

exception: [192.168.1.50] => FAILED: timed out
ok: [127.0.0.1]

TASK: [longrunner] *********

<job 805503341663> polling on 127.0.0.1, 45 remaining
<job 805503341663> polling on 127.0.0.1, 40 remaining
<job 805503341663> polling on 127.0.0.1, 35 remaining
<job 805503341663> finished on 127.0.0.1
ok: [127.0.0.1]

TASK: [write some_random_foo configuration] *********

ok: [127.0.0.1] => template src=/tmp/ansible.tNQALt/foo.j2
dest=/etc/some_random_foo.conf metadata=/etc/ansible/setup

TASK: [install httpd] *********

ok: [127.0.0.1] => yum pkg=httpd state=latest

TASK: [httpd start] *********

ok: [127.0.0.1] => service name=httpd state=running

PLAY RECAP ******************************

127.0.0.1 : {"changed": 0, "dark": 0, "failed": 0, "resources": 4, "skipped": 0}

DONE