Testing paths in conditionals without stat

I thought I was quite familiar with Ansible conditionals, but I saw @bcoca do something I wasn’t aware of: testing paths without using stat:

- hosts: localhost
    builddir: "b1"
    - debug: msg="directory {{ builddir }} exists"
      when: builddir is exists and builddir is directory

It’s existed since 2.5, but I only now did I get the memo.

Edit: note that these are implemented as Jinja filters so their evaluation occurs on the controlling node.

I thought I’d mention it here as it’s getting a bit of feedback over on the Fediverse. :slight_smile:


Thanks, I’d also missed this, I think it could replace all of my uses of stat apart from the ones that need to check where a symlink points to or the checksum of a file. :+1:


Tested with adhoc:

$ ansible localhost -i /dev/null -m debug -a "msg={{ 'test.yml' is exists }}"
localhost | SUCCESS => {
    "msg": true
$ ansible localhost -i /dev/null -m debug -a "msg={{ 'test.yml' is file }}"
localhost | SUCCESS => {
    "msg": true
$ ansible localhost -i /dev/null -m debug -a "msg={{ 'test.yml' is directory }}"
localhost | SUCCESS => {
    "msg": false

Testing against a remote host where I know test.yml doesn’t exist returns the same results though, so this appears to be a controller test, not a remote test. Unless I’m missing something, stat would still be required to test against remote inventory.

$ ansible testhost -m command -a "echo {{ 'test.yml' is exists }}"
testhost | CHANGED | rc=0 >>
$ ansible testhost -m stat -a "path=test.yml"
testhost | SUCCESS => {
    "changed": false,
    "stat": {
        "exists": false

Ahh, thanks for testing this, the docs do make this clear, don’t know how I missed this :roll_eyes:

information about a path on the control node


These are actually Jinja filters, so yes – they occur on the controller, like all templating does. (Edited the above to add this.)


Tests, not filters. Filters are used with | (or map()) and are used to transform data in some way; tests are used with is (or select() etc.) and return true or false depending on whether the data passes the test.