Conditinals based on remote facts

Hi

I would need to run tasks based on a remote fact - by executing a script to extract the actual variable. Currently I’m doing it in the following way:

  • name: Check Java Version
    shell: $JAVA_HOME/bin/java -version 2>&1 | grep ‘java version’ | awk ‘{ print substr($3, 2, length($3)-2); }’
    register: actual_java_version

  • name: Do Something based on Java version
    when: actual_java_version.stdout != …

Every time I run this script it says:

PLAY [vm] *********************************************************************

GATHERING FACTS ***************************************************************
ok: [vm]

TASK: [java-noinstall | Check Java Version] ***********************************
changed: [vm]

Which is not the desired behaviour. Ansible should not consider that as a ‘change’.
Additionally it stores the whole context into that ‘actual_java_version’ variable (the script itself, the timestamp, wheter it was ok, etc…) and if I need the actual result I need to address it like ‘actual_java_version.stdout’.
So all-in-all this is not a clean solution from my point of view.
What could I do?

The most clean way would be to collect that information in the GATHERING FACTS phase as it is done for e.g. $JAVA_HOME:

ansible_env.JAVA_HOME

…but for that I would need to create a new module just for that custom fact (http://serverascode.com/2015/01/27/ansible-custom-facts.html).

set_fact does not help me, since it just creates a new variable out of it with extended scope (to “survive between plays”).

Is there a quick solution like considering my TASK always OK?
Is there a clean solution without creating a new module for my custom fact?

Regards:
Bence

shell/command module actions are considered changed by default as
ansible has no way to know what transpired, there are several ways to
tell ansible, in your case i recommend adding the changed_when:
directive.

I created my custom facts file

/etc/ansible/facts.dcustom_facts.fact

#!/bin/bash
JAVA_VERSION="$JAVA_HOME/bin/java" -version 2>&1 | awk '/java version/{ print substr($3, 2, length($3)-2); }'

cat <<EOF
{
“java_version” : “$JAVA_VERSION”
}
EOF

If I run it on the control machine, everything is ok:
{
“java_version” : “1.7.0_45”
}

But if I run it on the remote machine:

ansible -m setup vm | grep ‘java_version’

then it is not populated. Only the ordinary ansible_facts are present, my java_version is not there.
It’s the same if I declares the fact_path:

ansible -m setup vm -a ‘fact_path=/etc/ansible/facts.d’ | grep ‘java_version’

I’m using ansible version 1.8.2

Any tips?

  1. március 10., kedd 13:02:33 UTC+1 időpontban Bence Takács a következőt írta:

THanks, it do work using that:

  • name: Check Java Version
    shell: $JAVA_HOME/bin/java -version 2>&1 | grep ‘java version’ | awk ‘{ print substr($3, 2, length($3)-2); }’
    register: actual_java_version
    changed_when: FALSE

result:

PLAY [vm] *********************************************************************

GATHERING FACTS ***************************************************************
ok: [vm]

TASK: [java-noinstall | Check Java Version] ***********************************
ok: [vm]

  1. március 10., kedd 15:17:34 UTC+1 időpontban Brian Coca a következőt írta: