我的库存文件定义如下:
[app]
app1.service.com ansible_host=192.168.1.1
app2.service.com ansible_host=192.168.1.2
app3.service.com ansible_host=192.168.1.3
我需要为每个主机生成多个配置文件。当前任务如下所示:
- name: Create node-specific csync2 config files
template:
src: "templates/etc/csync2_node.cfg"
dest: "/etc/csync2_{{ hostvars[item]['ansible_hostname'] }}.cfg"
owner: root
group: root
backup: no
with_items: "{{ groups[csync2_cluster_nodes_group] }}"
我的模板看起来像这样:
nossl * *;
group {{ hostvars[item]['ansible_hostname'] }}
{
{% for host in groups[csync2_cluster_nodes_group] %}
{% if host != hostvars[item]['ansible_nodename'] %}
host ({{ host }});
{% else %}
host {{ host }};
{% endif %}
{% endfor %}
key /etc/csync2/csync2.key;
include /home;
exclude *.log;
exclude *.swp;
exclude /home/ansible;
auto younger;
}
这可以正常生成如下模板文件:
group app1
{
host app1.service.com;
host (app2.service.com);
host (app3.service.com);
key /etc/csync2/csync2.key;
include /home;
exclude *.log;
exclude *.swp;
exclude /home/ansible;
auto younger;
}
问题是此配置导致竞争条件,因此我需要链接配置。我的意思是我需要app1配置文件看起来类似于
group app1
{
host app1.service.com;
host (app2.service.com);
key /etc/csync2/csync2.key;
include /home;
exclude *.log;
exclude *.swp;
exclude /home/ansible;
auto younger;
}
app2配置看起来像:
group app2
{
host app2.service.com;
host (app3.service.com);
key /etc/csync2/csync2.key;
include /home;
exclude *.log;
exclude *.swp;
exclude /home/ansible;
auto younger;
}
app3配置看起来像:
group app3
{
host app3.service.com;
host (app1.service.com);
key /etc/csync2/csync2.key;
include /home;
exclude *.log;
exclude *.swp;
exclude /home/ansible;
auto younger;
}
据我所知,最好的方法是利用模板中主机的索引。问题是我不确定这样做的语法是什么。我想在配置文件中做类似的事情(伪代码,因为我不知道这个的语法)
nossl * *;
group {{ hostvars[item]['ansible_hostname'] }}
{
{% for host in groups[csync2_cluster_nodes_group] %}
{% if host != hostvars[item]['ansible_nodename'] %}
{# This "item" isn't the current "host", so check to see if this is the last item in the group #}
{% if group.last == item %}
{# this is the last host in the group, so pull the FIRST host from the group #}
host ({{ hostvars[groups['app'][0]]['ansible_nodename'] }});
{# OK, this isn't the last host in the group, so pull the NEXT host from the group #}
{% else %}
host ({{ hostvars[groups['app'][groups.app.index(host)+1]]['ansible_nodename'] }});
{% endif %}
{% else %}
host {{ host }};
{% endif %}
{% endfor %}
key /etc/csync2/csync2.key;
include /home;
exclude *.log;
exclude *.swp;
exclude /home/ansible;
auto younger;
}
我希望我能够清楚地解释这个问题。我确信这有可能实现,但我只是坚持正确的语法来实现它。
答案 0 :(得分:0)
这是我在reddit的一些帮助下想出来的。
{# This is our "cycle" of hosts - this way the first host is after the first instance of the last host #}
{% set hosts = groups[csync2_cluster_nodes_group] + groups[csync2_cluster_nodes_group] -%}
{% set current_host_index = hosts.index(hostvars[item].ansible_nodename) -%}
{% if current_host_index < 0 %}{{ fail() }}{% endif %}
{% set next_host = hosts[current_host_index + 1] %}
nossl * *;
group {{ hostvars[item]['ansible_hostname'] }}
{
host {{ hostvars[hosts[current_host_index]].ansible_nodename }};
host ({{ hostvars[next_host].ansible_nodename }});
key /etc/csync2/csync2.key;
include /home;
exclude *.log;
exclude *.swp;
exclude /home/ansible;
auto younger;
}
似乎工作得很漂亮。