VarDict Guide
Introduction
The ansible_collections.community.general.plugins.module_utils.vardict
module util provides the
VarDict
class to help manage the module variables. That class is a container for module variables,
especially the ones for which the module must keep track of state changes, and the ones that should
be published as return values.
Each variable has extra behaviors controlled by associated metadata, simplifying the generation of output values from the module.
Quickstart
The simplest way of using VarDict
is:
from ansible_collections.community.general.plugins.module_utils.vardict import VarDict
Then in main()
, or any other function called from there:
vars = VarDict()
# Next 3 statements are equivalent
vars.abc = 123
vars["abc"] = 123
vars.set("abc", 123)
vars.xyz = "bananas"
vars.ghi = False
And by the time the module is about to exit:
results = vars.output()
module.exit_json(**results)
That makes the return value of the module:
{
"abc": 123,
"xyz": "bananas",
"ghi": false
}
Metadata
The metadata values associated with each variable are:
output: bool
- marks the variable for module output as a module return value.fact: bool
- marks the variable for module output as an Ansible fact.verbosity: int
- sets the minimum level of verbosity for which the variable will be included in the output.change: bool
- controls the detection of changes in the variable value.initial_value: any
- when usingchange
and need to forcefully set an intial value to the variable.diff: bool
- used along withchange
, this generates an Ansible-style diffdict
.
See the sections below for more details on how to use the metadata.
Using VarDict
Basic Usage
As shown above, variables can be accessed using the []
operator, as in a dict
object,
and also as an object attribute, such as vars.abc
. The form using the set()
method is special in the sense that you can use it to set metadata values:
vars.set("abc", 123, output=False)
vars.set("abc", 123, output=True, change=True)
Another way to set metadata after the variables have been created is:
vars.set_meta("abc", output=False)
vars.set_meta("abc", output=True, change=True, diff=True)
You can use either operator and attribute forms to access the value of the variable. Other ways to access its value and its metadata are:
print("abc value = {0}".format(vars.var("abc")["value"])) # get the value
print("abc output? {0}".format(vars.get_meta("abc")["output"])) # get the metadata like this
The names of methods, such as set
, get_meta
, output
amongst others, are reserved and
cannot be used as variable names. If you try to use a reserved name a ValueError
exception
is raised with the message “Name <var> is reserved”.
Generating output
By default, every variable create will be enable for output with minimum verbosity set to zero, in other words, they will always be in the output by default.
You can control that when creating the variable for the first time or later in the code:
vars.set("internal", x + 4, output=False)
vars.set_meta("internal", output=False)
You can also set the verbosity of some variable, like:
vars.set("abc", x + 4)
vars.set("debug_x", x, verbosity=3)
results = vars.output(module._verbosity)
module.exit_json(**results)
If the module was invoked with verbosity lower than 3, then the output will only contain
the variable abc
. If running at higher verbosity, as in ansible-playbook -vvv
,
then the output will also contain debug_x
.
Generating facts is very similar to regular output, but variables are not marked as facts by default.
vars.set("modulefact", x + 4, fact=True)
vars.set("debugfact", x, fact=True, verbosity=3)
results = vars.output(module._verbosity)
results["ansible_facts"] = {"module_name": vars.facts(module._verbosity)}
module.exit_json(**results)
Handling change
You can use VarDict
to determine whether variables have had their values changed.
vars.set("abc", 42, change=True)
vars.abc = 90
results = vars.output()
results["changed"] = vars.has_changed
module.exit_json(**results)
If tracking changes in variables, you may want to present the difference between the initial and the final values of it. For that, you want to use:
vars.set("abc", 42, change=True, diff=True)
vars.abc = 90
results = vars.output()
results["changed"] = vars.has_changed
results["diff"] = vars.diff()
module.exit_json(**results)
Added in version 7.1.0.