<!--- Verify first that your issue is not already reported on GitHub -->
<!--- Also test if the latest release and devel branch are affected too -->
<!--- Complete *all* sections as described, this form is processed automatically -->



##### SUMMARY

I'm using the `template` module to generate some templates.

If I say `x in y` and `y` is undefined, the error message is not at all specific.
It prints out the entire contents of a file, possibly the wrong one, and doesn't even name which variable is undefined.

Note that I expect this is not the right github repo to lodge this issue, since modules have been split into different repos.
But I have no idea how to figure out which repo is the right repo.
This itself is a documentation issue, #67939 .


##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME

template

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes -->
```
ansible 2.9.0
  config file = /home/ec2-user/environment/repo/workload/ansible.cfg
  configured module search path = ['/home/ec2-user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/ec2-user/.local/lib/python3.6/site-packages/ansible
  executable location = /home/ec2-user/.local/bin/ansible
  python version = 3.6.10 (default, Feb 10 2020, 19:55:14) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
```

##### CONFIGURATION
<!--- Paste verbatim output from "ansible-config dump --only-changed" between quotes -->
```
ANSIBLE_PIPELINING(/home/ec2-user/environment/repo/workload/ansible.cfg) = True
ANY_ERRORS_FATAL(/home/ec2-user/environment/repo/workload/ansible.cfg) = True
CACHE_PLUGIN(/home/ec2-user/environment/repo/workload/ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(/home/ec2-user/environment/repo/workload/ansible.cfg) = ~/.ansible-facts-cache
CACHE_PLUGIN_TIMEOUT(/home/ec2-user/environment/repo/workload/ansible.cfg) = 7200
DEFAULT_FORKS(/home/ec2-user/environment/repo/workload/ansible.cfg) = 50
DEFAULT_GATHERING(/home/ec2-user/environment/repo/workload/ansible.cfg) = no
INVENTORY_UNPARSED_IS_FAILED(/home/ec2-user/environment/repo/workload/ansible.cfg) = True
```

##### OS / ENVIRONMENT

Amazon Linux.

Python Jinja module 2.10.1

##### STEPS TO REPRODUCE

`playbook.yaml`
```

---
- hosts: localhost
  connection: local
  vars:
    x: 1
  tasks:
  - template:
      src: "parent.j2"
      dest: "/tmp/out/parent-out.txt"
      trim_blocks: False
```

`parent.j2`
```
Here is the parent
x = {{ x }}

{% include 'child.j2' %}

Back to the parent
```

`child.j2`
```
Here is the child

x = {{ x }}

{% if z in y %} {# this line will fail, because y is not defined #}
{{ z }}
{% endif %}

```

`ansible-playbook playbook.yaml`


##### EXPECTED RESULTS

The same thing as when variables are undefined in other ways.

```
TASK [template] *************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'y' is undefined"}
```

Additionally the line number and file of the child template would be great. But at the very least I want the name of the undefined variable.

##### ACTUAL RESULTS
<!--- Describe what actually happened. If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes -->
```
fatal: [localhost]: FAILED! => changed=false 
  msg: |-
    AnsibleUndefinedVariable: Unable to look up a name or access an attribute in template string (Here is the parent
    x = {{ x }}
  
    {% include 'child.j2' %}
  
    Back to the parent).
    Make sure your variable name does not contain invalid characters like '-': argument of type 'AnsibleUndefined' is not iterable

```

Note that:

* the name of the undefined variable does not appear in the error message
* the error message contains the contents of the `parent.j2` file, which had no errors in it, and no undefined variables in it
* the error message does not contain the content or path or the file `child.j2` which had the error
* if the `parent.j2` file is long, this error message can be very long, so it's not even clear which task failed until you scroll up several pages

The only way to figure out what went wrong is to use a binary search, deleting half of `child.j2` at a time.

Think of the case where you have a working template that uses a variable multiple times in the one template.
Then you rename it elsewhere, and forget to rename it in the template.
If you try to use the binary search method to find the error, you won't have any luck, because you'll end up in a situation where both halves have the same error.


Note that you get the error without nested templating, if you have `{{ x in y }}` in the parent, and no `include`.
So this bug isn't caused by nesting, it's just exacerbated, because when the undefined variable is in a nested template, the error message contains the wrong file contents entirely.
'''Determines if a string looks like a template, by seeing if it
        contains a jinja2 start delimiter. Does not guarantee that the string
        is actually a template.
        This is different than ``is_template`` which is more strict.
        This method may return ``True`` on a string that is not templatable.
        Useful when guarding passing a string for templating, but when
        you want to allow the templating engine to make the final
        assessment which may result in ``TemplateSyntaxError``.
        '''
        env = self.environment
        if isinstance(data, string_types):
            for marker in (env.block_start_string, env.variable_start_string, env.comment_start_string):
                if marker in data:
                    return True
        return False
    def _convert_bare_variable(self, variable):
        '''
        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):