-
Notifications
You must be signed in to change notification settings - Fork 23.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
'recursive loop detected in template string' error with variables in name #8603
Comments
Hi! So this seems to be working exactly as designed for me, because you're defining a variable named host who's value is host.
I would recommend NOT doing that. It's kind of a "Doctor, My Arm Hurts When I Do This" kind of thing, if that joke translates :) I'm going to close this one as working as designed, but feel free to stop by ansible-project if you'd like to discuss further. We're open to it. |
I'm encountering the same error, although with a different configuration. This is enough to reproduce it in a playbook: vars:
app:
user: rails
home: "/home/{{ app.user }}" If I flatten the vars to |
I'm in the same boat as thom-nic. Although after thinking about it, it does make sense. We're trying to reference a variable before it has been assigned. Try the same thing in python: >>> app = {"user": "rails", "home": "/home/" + app['user']}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'app' is not defined It's a shame, because it does make for nice neat configs. app_user: "rails"
app:
user: "{{ app_user }}"
home: /home/{{ app_user }} Bit ugly, but so far it's a trade-off I'm ok with. |
Having something similar after moving from 1.6.X to 1.8.4. It was working before for us, now we run into the recursion issue. We have a playbook as follows:
Then in a group_vars for a specific environment we define the rsyslog:
Once the rsyslog role is run we get the error: I really hope this was not a bug that was fixed and now we cannot take advantage of it. My gut feel it is a ordering change, in the way variables are built up. Note we have forced the hash_behaviour to merge in our ansible configuration. Any thoughts or suggestions would be welcomed before I dig in deeper or rework how we define things. |
same problem here 👎 |
Same issue, worked around it by just moving and renaming the "conflicting" variable. |
Same here...because you're aloud to pass "variables" as extra arguments there are times where I need to use the passed in value otherwise use a default value.
|
Just encountered what @thom-nic did. I am not entirely sure why that results in an error though. Looking at it it looks like something that should work perfectly fine. |
yup. when i nest role dependencies, this happens. |
Same issue here. Wanted to use the nicer format so bad |
Software can solve all sorts of issues, and certainly this could be solved too. However the format for a dictionary calling on itself while it is being defined is in its own domain. A year ago someone asked this question, where a format is proposed, it could be a way to do it: |
I am also running into the same error. Can someone tell me how do I go about it. I am using the below variable and I get recursive loop error. maxHeapSizeAnsi: "{{(hostvars[inventory_hostname]['ansible_memtotal_mb'] * 3 / 4)|int}}" |
I also fall in it. Is it will be fixed? Should it be reopened? |
+1 |
6 similar comments
+1 |
+1 |
+1 |
+1 |
+1 |
+1 |
Seems dumb, yet it makes sense as to why this shouldn't work due to the dictionary trying to recursively ask itself for a key when the dictionary itself hasn't been fully initialized yet. Broken w/ recursion errorThis is what I was trying to do before hand to have only one place to alter the version. application:
params:
state: present
version: "0.6.3"
download_url: "https://releases.hashicorp.com/consul/{{ consul.params.version }}/consul_{{ consul.params.version }}_linux_amd64.zip"
agent:
... FixI decided to make use of the defaults folder and stuff the random things in there as keeping the vars flat forces them to be initialized first. Then, I could pull them into my 'beautiful' structure in vars/main.yml .
|-roles
|---Application
|-----defaults
|-------main.yml
|-----files
|-----handlers
|-----meta
|-----tasks
|-----templates
|-----vars
|-------main.yml In defaults/main.yml i have: _version: "0.6.3"
_download_url: "https://releases.hashicorp.com/consul/{{ _version }}/consul_{{ _version }}_linux_amd64.zip" In defaults/vars.yml i have: consul:
params:
state: present
version: "{{ _version }}"
download_url: "{{ _download_url }}"
is_agent: false
agent:
... This way the variables can still be altered higher up, but also allows a single source of where the 'default vars' can be changed from ;) EditAfter testing, I changed default vars to have an underscore due to denoting them this way (via convention) as 'private'. Also, this way you know exactly what file the variables are being read from. heh. |
+1 |
+1 I would love to be able to use such configuration: myapp:
version: 1.6.3
download_url: http://example.org/download/myapp-{{ myapp.version }}.tgz |
@mpdehaan, imagine I've just installed another module from the ansible galaxy in replacement for that I've used before. Imagine it has set default variable named, let's say I don't want to change the variable name inside my module. As it's mnemonic by itself, and all the variables are named following the same rule, i.e. What would be your advice for that pretty much common use case? |
+1 |
+1 Not having this prevents having a nice, clean variable hierarchy, since we have to do it the old-fashioned prefixed way. Consider: mysql:
version: 5.5
install_path: "/var/lib/mysql/{{ mysql.version }}"
user: mysql
group: mysql vs mysql_version: 5.5
mysql_install_path: "/var/lib/mysql/{{ mysql_version }}"
mysql_user: mysql
mysql_group: mysql Although this is just an example not a real world case of (at least for me), it presents what the problem is. IMO, the latter definition is just nasty. The former applies some kind of DRY'ing out. |
+1 |
Referring to @bn0 answer above:
And also referring to all who say, that this feature would be logically nonsense:This feature is actually well-defined in terms of meaning exactly one thing. The syntax and semantics (in terms of logic) are both well defined for this kind of "back reference". 1. Implementation ProblemBut wait: how can a hash map value refer to the hash map which is still not defined?The assumption here is partly wrong. Because we are handling two syntaxes here. YAML and ansible variables. One must know, that ansibles notion of variables 1. hash_map:
2. version: ab
3. path: "/somepath/{{hash_map.version}}" When is the variable Two different implementationsLet's see how the implementation would be affected by this decision.
Implementation#1 implies that the data structure is only defined after line 3 in the example above: variables = {}
variables["hash_map"] = {"version": "ab", "path": "/somepath/{{hash_map.version}}" }
# We cannot do this!!!
variables["hash_map"] = {"version": "ab", "path": "/somepath/%s" % variables["hash_map"]["version"] } Implementation#2 implies that line 1 above is totally sufficient to allocate the data structure. variables = {}
variables["hash_map"] = {}
variables["hash_map"]["version"] = "ab"
# This is totally possible
variables["hash_map"]["path"] = "/somepath/%s" % variables["hash_map"]["version"] Both represent the same, but as you can see the latter is somehow a bit more powerful. 2. Ok, so where is the problem then?What does the standard say?Let's see what we can achieve with plain YAML. Representation of YAML according to the standardThe YAML standard describes the semantics of YAML as a rooted directed graph. Nodes are described under section 3.2.1.1. Nodes. According to the standard values are represented as nodes too. But - and here is the point - there is no node type as far as I know, which can semantically represent the feature above correctly (as in the way we want it), as one node. The only real option here would be using a Consequences of thisThe YAML example above would be represented by the following graph according to my understanding of the standard: As we want to give meaning to
1. hash_map:
2. version: &anchor "ab" #setting the anchor
3. path:
4. - "/somepath/"
5. - *anchor # referring to the anchor, yields ab
yielding the following graph: What follows of this?Above we can see that we cannot combine those two nodes. As such there is no way to achieve this feature using YAML only syntax. TLDRYAML is a markup language (despite of what it's acronym may suppose) and a markup language just answers the "what" question not "how". And as it is totally clear what the reference means, it is totally possible to implement this feature.
EDITS:
|
And so what the conclusion? As {{ some_var_name_here }} is just ansible notation and its semantic may be changed to handle "deffer resolving" do you plan implement something similar (like closure binding for example in groovy)? Issue still closed. |
+1 |
11 similar comments
+1 |
+1 |
+1 |
+1 |
+1 |
+1 |
+1 |
+1 |
+1 |
+1 |
+1 |
+1 This is a YAML implementation bug. |
+1 |
4 similar comments
+1 |
+1 |
+1 |
+1 |
I also hit this. Can you please think about reopening this? |
@everybody, and i mean literally everybody :-). This did hit me before, the only thing you can do is restructure your variables. Note you can't refer to a variable that's not already definded (see variable precedence in the ansible docs. Note also that if you refer to a variable you define later on in the file, you will get an error.). The real 'problem' is not in Ansible but in Jinja2. If you think you can fix this, be my guest. However, i don't think its easy to fix, if not impossible within the current jinja2 architecture / project. When you have something like this (credits to @rqelibari for the example):
And also wants a clean and nice ansible variable file and / or directory. Consider another architecture, you could add variables in other files, you're not limited to the main.yml file or the all.yml file. Ansible is flexible, so if your'e smart, move and play with it :-D. For example, you could create a file in the ' all ' directory of the group_vars named 'hash_map' and create the variables you need in this file. Yes it should be nice if it's possible to refer to the key you noted in the same key-store, currently it is'nt possible. I don't see it happen within now and a few months either... Work around it, be creative and don't make your ansible scripts a mess. Personally i did like to make everything configurable with the ansible-variables. The only reward i got was an unmanageable playbook and a fuzzy variable structure :-). Alright, dont +1 this on ansible but fix this at the jinja2 project. |
This issue is a direct result of ansibles use of a yaml parser's
interpolation feature instead of loading the yaml object and doing a second
pass for interpolation. This is not just a jinja bug this is an
implementation bug in ansible. Please inspect. Loading as raw string and
then processing the initialised object members in a second pass should fix
this.
|
+1 |
3 similar comments
+1 |
+1 |
+1 |
This fixes issue, when variables config like below will fail with "infinite recursion in template": root_var: nested_var: value another: "{{ root_var.nested_var }}/extra_path or something"
This fixes issue, when variables config like below will fail with "infinite recursion in template": root_var: nested_var: value another: "{{ root_var.nested_var }}/extra_path or something"
Fixes variable templating for structures like this: root_var: nested_var: "value" another: "{{ root_var.nested_var }}_extra" or root: var: "value" subdict: subvar: "{{ root.var }} and puppies!"
Issue Type:
Bug Report
Ansible Version:
1.6.10 and 1.7
Environment:
Mac OSX 10.9.4
Summary:
I've found a weird bug with ansible playbooks (or maybe my code/setup). When I use a tasks playbook using an include, the variables passed in can't be used in the 'name' of a module.
Steps To Reproduce:
name:
include the variable.Here's the problem example:
task_runner.yml
tasks.yml
It should be noted that if I change
name: "ping {{ host }} twice"
toname: "ping host twice"
, I will not receive the error (that I'm receiving in "Actual Results" below).Expected Results:
No error message.
Here's a working example first done in a single playbook:
task_playbook.yml
Here's how it runs:
Actual Results:
Thanks.
The text was updated successfully, but these errors were encountered: