##### SUMMARY

Executing the same playbook that uses a template with a `set` and `include` results in an `undefined variable` error on CentOS 8, but it works on CentOS 7.
It looks like that on CentOS 8 all variables in scope will be evaluated, so also the once that are not used, which is the reason for this error.

On both operating systems the latest available version standard repo is used. This means on CentOS 8, Ansible with Python 3 and a newer Jinja2 version is used.
See for details the version section.

There is also a workaround, see the latest section.


##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
template

##### ANSIBLE VERSION

* On CentOS 8 (with the issue)
```paste below
ansible 2.9.5
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/mark/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Nov 21 2019, 19:31:34) [GCC 8.3.1 20190507 (Red Hat 8.3.1-4)]
```

Jinja2 version: `python3-jinja2-2.10.1-2.el8_0.noarch`

* On CentOS 7 (where it works as expected)
```paste below
ansible 2.9.6
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/mark/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Aug  7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
```
Jinja2 version: `python-jinja2-2.7.2-4.el7.noarch`

Also with version 2.9.5 it works as expected on CentOS 7.

##### CONFIGURATION
`ansible-config dump --only-changed` has no output on both systems

##### OS / ENVIRONMENT

* OS with the issue: `CentOS Linux release 8.1.1911 (Core)``
* OS with the exepcted result: `CentOS Linux release 7.7.1908 (Core)`


##### STEPS TO REPRODUCE

Create the following files:

`playbook.yml`:
```yaml
---
- hosts: localhost
  become: False
  gather_facts: False
  vars:
    test_var: Test
    not_used_variable: "{{ var_that_does_not_exists }}"
  tasks:
    - name: Test template
      debug:
        msg: "{{ lookup('template', 'test.j2') }}"
```

`templates/test.j2`:
```
{% set var_set_in_template=test_var %}
{% include "includes/test-include.j2" %}
```

`templates/includes/test-include.j2`:
```
{{ var_set_in_template }}
```

Execute the playbook using: `ansible-playbook playbook.yml`

For a complete set of files, see also: https://github.com/m-a-r-k-e/ansible-template-issue

##### EXPECTED RESULTS

The variable is correctly printed (this is the output when running on CentOS 7):

```
[mark ansible-template-issue](develop)$ ansible-playbook playbook.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'

PLAY [localhost] ***************************************************************

TASK [Test template] ***********************************************************
ok: [localhost] => {
    "msg": "Test\n"
}

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
```


##### ACTUAL RESULTS

An error because the template tries to resolve the not used variable: `not_used_variable: "{{ var_that_does_not_exists }}"`.
This is the result when running on CentOS 8:

<!--- Paste verbatim command output between quotes -->
```paste below
[mark ansible-template-issue](develop)$ ansible-playbook playbook.yml -vvvv
ansible-playbook 2.9.5
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/mark/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 3.6.8 (default, Nov 21 2019, 19:31:34) [GCC 8.3.1 20190507 (Red Hat 8.3.1-4)]
Using /etc/ansible/ansible.cfg as config file
setting up inventory plugins
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Parsed /etc/ansible/hosts inventory source with ini plugin
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
Loading callback plugin default of type stdout, v2.0 from /usr/lib/python3.6/site-packages/ansible/plugins/callback/default.py

PLAYBOOK: playbook.yml ******************************************************************************************************************
Positional arguments: playbook.yml
verbosity: 4
connection: smart
timeout: 10
become_method: sudo
tags: ('all',)
inventory: ('/etc/ansible/hosts',)
forks: 5
1 plays in playbook.yml

PLAY [localhost] ************************************************************************************************************************
META: ran handlers

TASK [Test template] ********************************************************************************************************************
task path: /home/mark/GIT/ansible-template-issue/playbook.yml:9
File lookup using /home/mark/GIT/ansible-template-issue/templates/test.j2 as file
fatal: [localhost]: FAILED! => {
    "msg": "The task includes an option with an undefined variable. The error was: 'var_that_does_not_exists' is undefined\n\nThe error appears to be in '/home/mark/GIT/ansible-template-issue/playbook.yml': line 9, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: Test template\n      ^ here\n"
}

PLAY RECAP ******************************************************************************************************************************
localhost   
```

##### Workaround

There is a workaround, so the output is the same on CentOS 7 and CentOS 8. In that case change the template by removing the `set` and replace this with a `for` loop that contains only a single element:

`templates/test.j2`:
```
#jinja2: lstrip_blocks: True
{% for var_set_in_template in [ test_var ] %}
  {% include "includes/test-include.j2" %}
{% endfor %}
```

For the complete working example, see: https://github.com/m-a-r-k-e/ansible-template-issue/tree/solution-centos8

'''
        Wraps a bare string, which may have an attribute portion (ie. foo.bar)
        in jinja2 variable braces so that it is evaluated properly.
        '''
        if isinstance(variable, string_types):
            contains_filters = "|" in variable
            first_part = variable.split("|")[0].split(".")[0].split("[")[0]
            if (contains_filters or first_part in self._available_variables) and self.environment.variable_start_string not in variable:
                return "%s%s%s" % (self.environment.variable_start_string, variable, self.environment.variable_end_string)
        
        
        return variable
    def _finalize(self, thing):
        '''
        A custom finalize method for jinja2, which prevents None from being returned. This
        avoids a string of ``"None"`` as ``None`` has no importance in YAML.
        If using ANSIBLE_JINJA2_NATIVE we bypass this and return the actual value always
        '''
        if USE_JINJA2_NATIVE:
            return thing
        return thing if thing is not None else ''
    def _fail_lookup(self, name, *args, **kwargs):
        raise AnsibleError("The lookup `%s` was found, however lookups were disabled from templating" % name)
    def _now_datetime(self, utc=False, fmt=None):