Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible set_fact doesn't change the variable value

Tags:

shell

ansible

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?

like image 780
hauron Avatar asked Nov 20 '14 11:11

hauron


People also ask

What does set_fact do in ansible?

This module allows setting new variables. Variables are set on a host-by-host basis just like facts discovered by the setup module. These variables will be available to subsequent plays during an ansible-playbook run.

What is the use of set_fact?

The set_fact module takes key=value pairs or key: value (YAML notation) as variables to set in the playbook scope. The 'key' is the resulting variable name and the value is, of course, the value of said variable. You can create multiple variables at once, by supplying multiple pairs, but do NOT mix notations.

What is the order of precedence for ansible variables?

Here is the order of precedence from least to greatest (the last listed variables override all other variables): command line values (for example, -u my_user , these are not variables) role defaults (defined in role/defaults/main.yml) 1. inventory file or script group vars 2.

How are global variables defined in ansible?

Variable Scopes Global: this is set by config, environment variables and the command line. Play: each play and contained structures, vars entries, include_vars, role defaults and vars. Host: variables directly associated to a host, like inventory, facts or registered task outputs.


1 Answers

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.

like image 123
robo Avatar answered Oct 12 '22 21:10

robo