When calling Ansible modules frequently with similar parameters, module_defaults can save on typing and, almost more importantly, improve on clarity by defining default values for modules I use in a play.
Let’s look at a small example in which I want to clear records for a host from a dynamic DNS server and then add it in again. In all invocations of the nsupdate module I would need to specify key name, algorithm, server, etc., but through the use of module_defaults
I can set default values and no longer have to specify these repetitively on individual tasks.
- hosts: all
vars_files:
dns-params.yml
module_defaults:
community.general.nsupdate:
key_algorithm: "hmac-sha256"
key_name: "{{ tsig_key_name }}"
key_secret: "{{ tsig_key_secret }}"
server: "{{ dns_server }}"
protocol: "tcp"
ttl: 60
zone: "example.org"
tasks:
- name: Clean old records from DNS
community.general.nsupdate:
record: "www.example.org."
state: absent
- name: Add IPv4 addresses to DNS
community.general.nsupdate:
record: "www.example.org."
type: "A"
value: "192.0.2.43"
state: present
What I wasn’t aware of and learned today via Ton, is that the module defaults don’t have to be statically specified; they can also be provided via a lookup plugin. I whipped up a simple example to illustrate this.
The lookup plugin (md.py
) returns an array containing a single dictionary of values. All keys returned must be valid parameters for the module I intend to use these with. For example, if params
contained a key called package
, the module would fail as “package” is not (currently) a valid parameter for copy
.
from ansible.plugins.lookup import LookupBase
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
params = {
"content" : "Rijsttafel",
"mode" : "0400",
}
return [ params ]
The playbook shows how this plugin is used to feed module_defaults
for the copy
module, and it then invokes copy
twice:
- hosts: localhost
module_defaults:
copy: "{{ lookup('md') }}"
tasks:
- copy: content="Hello" dest="a" mode=0444
- copy: dest="b"
The result: two files with distinct permissions and content:
$ ls -l ?
-r--r--r-- 1 jpm staff 5 Oct 5 18:32 a
-r-------- 1 jpm staff 10 Oct 5 18:32 b
$ cat a
Hello
$ cat b
Rijsttafel
The second file b
has permissions 0400 and content “Rijsttafel” set from the lookup, and both have these defaults overridden for file a
.
The small lookup plugin above doesn’t use terms
or kwargs
but easily could to return, say, a different class of values, etc.