Scenario ansible-playbook is called with passed in extra var:
-e my_var=init_value
Then in a role code the value is supposed to change via set_fact call (variable other_var value is "new_value"):
set_fact: my_var: {{ other_var }}
This results in a nice output supposedly confirming alteration:
{"ansible facts": {"my_var": "new_value"}}
However echoing the variable after changing it shows the old value:
echo {{ my_var }}
-> "echo init_value"
To add to that, when I set two variables in the above example:
set_fact: my_var: {{ other_var }}
set_fact: new_var: {{ other_var }}
The new_var is set properly.
Is the variable in some way immutable? How to use the set_fact to update the variable's value?
The set_fact
module effectively adds another host fact, ie. "a fact discovered about the system". From the documentation (http://docs.ansible.com/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable) you can see that those facts have low priority, and will be overridden by extra-vars and various other things.
This can be confusing because using set_fact
can make it seem like you are changing the value of the variable at that point, but maybe the name is the key to understanding - it's not 'set_variable', it's 'set_(host)fact', and host facts have low precedence. Precedence is more important than the order in which the value is assigned.
One workaround if you want to supply a value via extra-vars that gets overwritten later would be to reassign that extra-vars value to a different variable via set_fact
at the start of your playbook, and then reassign that new variable later using set_fact again. Since they're at the same precedence level, the 'overwrite' should work as you would expect.
Command line variables have the highest precedence of all variable types. Anything you define on the command line will override any other definitions of that variable.
Documentation on variable precedence in Ansible is here http://docs.ansible.com/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable That lists all the other places you could put your initial/default value.