2017-03-27 68 views
0

我有定義的清單文件,如下所示:Ansible遍歷組和參考索引

[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; 
} 

而且APP 2配置的樣子:

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

這裏是我想出了從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; 
}  

似乎工作得很好。