0

Please explain to me how can I fix this problem? i have this file defaults/main.yml

---
node1:
 ip: 1.1.1.1

node2:
 ip: 2.2.2.2

node3:
 ip: 3.3.3.3 

Now, I want in template file ip.j2 by for loop access the IPs of each server and save in address variable

Like this:

address= 1.1.1.1,2.2.2.2,3.3.3.3

I tried this code:

address={% for x in {{nubmer_nodes}} %}
{{node[x].ip}}
{% if loop.last %},{% endif %}
{% endfor %}

But an error occurs. How should I do this?

Error :

TASK [Gathering Facts] *********************************************************************

ok: [db2]
ok: [db3]
ok: [db1]

TASK [ssh : -- my loop --] *************************************************************************

fatal: [db1]: FAILED! => {"changed": false, "msg": "AnsibleError: template error while templating string: expected token ':', got '}'. String: \r\naddress={% for x in {{number_nodes}} %}\r\n{{node[x].ip}}\r\n{% if loop.last %},{% endif %}\r\n{% endfor %}"}
fatal: [db2]: FAILED! => {"changed": false, "msg": "AnsibleError: template error while templating string: expected token ':', got '}'. String: \r\naddress={% for x in {{number_nodes}} %}\r\n{{node[x].ip}}\r\n{% if loop.last %},{% endif %}\r\n{% endfor %}"}
fatal: [db3]: FAILED! => {"changed": false, "msg": "AnsibleError: template error while templating string: expected token ':', got '}'. String: \r\naddress={% for x in {{number_nodes}} %}\r\n{{node[x].ip}}\r\n{% if loop.last %},{% endif %}\r\n{% endfor %}"}
        to retry, use: --limit @/etc/ansible/playbooks/get_ip_ssh.retry

PLAY RECAP ********************************************************

db1                        : ok=1    changed=0    unreachable=0    failed=1
db2                        : ok=1    changed=0    unreachable=0    failed=1
db3                        : ok=1    changed=0    unreachable=0    failed=1

Edite-1

I changed the template and default/main.ymlcode. I have names(nodes) but I can not access IPs yet. default/main.yml:

nodes:
 node1:
     ip: 1.1.1.1

 node2:
     ip: 2.2.2.2

 node3:
     ip: 3.3.3.3

get-ip.j2

address={% for host in nodes %}{{host}}{% if not loop.last %},{% endif %}{% endfor %}

Output is:

address=node1,node3,node2

I also used this code:

address={% for host in nodes %}{{host.ip}}{% if not loop.last %},{% endif %}{% endfor %}

OR

address={% for host in nodes %}{{host.[ip]}}{% if not loop.last %},{% endif %}{% endfor %}

But not work yet!!

Update

My problem solved, I use this code:

address={% for host in nodes %}{{ nodes[host].ip }}{% if not loop.last %},{% endif %}{% endfor %}
  • what's the error? – man0v Feb 22 '18 at 7:59
1

A few things.

Firstly, assuming number_nodes has the values of 1,2,3, you are trying to access the element of node but you do not have such a variable in the provided yaml.

Secondly, you cannot iterate over three different variables in such a way.

However, if your yaml file looked like that:

---
nodes:
  - ip: 1.1.1.1
  - ip: 2.2.2.2
  - ip: 3.3.3.3 

Your code could look like that:

address={% for x in {{ nodes }} %}
{{ x.ip }}
{% if not loop.last %},{% endif %}
{% endfor %}

What is different from your code is:

  • In the first line we loop over the elements of nodes.
  • In the second you select the ip element of x, which is the each element in the loop.
  • In the third line, assuming you want commas in between all elements except after the last one, you need a not.

Not the answer you're looking for? Browse other questions tagged or ask your own question.