diff --git a/changelogs/fragments/vars_prematurely_template.yaml b/changelogs/fragments/vars_prematurely_template.yaml new file mode 100644 index 0000000000..0721431526 --- /dev/null +++ b/changelogs/fragments/vars_prematurely_template.yaml @@ -0,0 +1,2 @@ +bugfixes: + - we don't really need to template vars on definition as we do this on demand in templating. diff --git a/lib/ansible/playbook/base.py b/lib/ansible/playbook/base.py index 5bc132d698..74f079e41d 100644 --- a/lib/ansible/playbook/base.py +++ b/lib/ansible/playbook/base.py @@ -348,7 +348,9 @@ class FieldAttributeBase(with_metaclass(BaseMeta, object)): if attribute.static: value = getattr(self, name) - if templar.is_template(value): + + # we don't template 'vars' but allow template as values for later use + if name not in ('vars',) and templar.is_template(value): display.warning('"%s" is not templatable, but we found: %s, ' 'it will not be templated and will be used "as is".' % (name, value)) continue @@ -592,7 +594,7 @@ class Base(FieldAttributeBase): _remote_user = FieldAttribute(isa='string', default=context.cliargs_deferred_get('remote_user')) # variables - _vars = FieldAttribute(isa='dict', priority=100, inherit=False) + _vars = FieldAttribute(isa='dict', priority=100, inherit=False, static=True) # module default params _module_defaults = FieldAttribute(isa='list', extend=True, prepend=True) diff --git a/test/integration/targets/var_templating/aliases b/test/integration/targets/var_templating/aliases new file mode 100644 index 0000000000..b59832142f --- /dev/null +++ b/test/integration/targets/var_templating/aliases @@ -0,0 +1 @@ +shippable/posix/group3 diff --git a/test/integration/targets/var_templating/runme.sh b/test/integration/targets/var_templating/runme.sh new file mode 100755 index 0000000000..0f22fb130b --- /dev/null +++ b/test/integration/targets/var_templating/runme.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -eux + +# this should succeed since we override the undefined variable +ansible-playbook undefined.yml -i inventory -v "$@" -e '{"mytest": False}' + +# this should still work, just show that var is undefined in debug +ansible-playbook undefined.yml -i inventory -v "$@" + +# this should work since we dont use the variable +ansible-playbook undall.yml -i inventory -v "$@" diff --git a/test/integration/targets/var_templating/undall.yml b/test/integration/targets/var_templating/undall.yml new file mode 100644 index 0000000000..9ea9f1d1dc --- /dev/null +++ b/test/integration/targets/var_templating/undall.yml @@ -0,0 +1,6 @@ +- hosts: localhost + gather_facts: false + tasks: + - debug: + vars: + mytest: '{{ und }}' diff --git a/test/integration/targets/var_templating/undefined.yml b/test/integration/targets/var_templating/undefined.yml new file mode 100644 index 0000000000..cf083d5f11 --- /dev/null +++ b/test/integration/targets/var_templating/undefined.yml @@ -0,0 +1,13 @@ +- hosts: localhost + gather_facts: false + tasks: + - name: show defined/undefined var + debug: var=mytest + vars: + mytest: '{{ und }}' + register: var_undefined + + - name: ensure either mytest is defined or debug finds it to be undefined + assert: + that: + - mytest is defined or 'VARIABLE IS NOT DEFINED!' in var_undefined['mytest']