2017-03-15 58 views
1

在我的變量文件中,我需要定義一個列表變量,其中的項目具有相似的模式,並且還共享一些(冗餘)信息。而不是手動輸入所有這些信息,我想在循環中生成列表變量。Ansible:在循環中生成變量

例如,我有100個主機,主IP地址爲192.168.100。[1:100],每個主機都有一個額外的IP地址10.0.1。[1:100]。 所有的主IP使用相同的網關,比如說192.168.100.254,所有額外的IP使用另一個網關,比如說10.0.1.254。

在一個任務中,我想遍歷所有主機,並且對於每個主機,它是主IP,額外IP,並且網關都是需要的。我想在我的任務使用「with_items」,所以我想有一個列表變量「IP_ADDRS」,在其中每個項目是一個字典象下面這樣:

{ primary_ip: 192.168.100.x, primary_gw: 192.168.100.254, extra_ip: 10.0.1.x, extra_gw: 10.0.1.254} 

不用手動定義IP_ADDRS:

IP_ADDRS: 
    - { primary_ip: 192.168.100.1, primary_gw: 192.168.100.254, extra_ip: 10.0.1.1, extra_gw: 10.0.1.254} 
    - { primary_ip: 192.168.100.2, primary_gw: 192.168.100.254, extra_ip: 10.0.1.2, extra_gw: 10.0.1.254} 
    - ... 

我要生成列表變量 「IP_ADDRS」 莫名其妙......

我試過Jinja2的語句,像下面:

IP_ADDRS: > 
    "{% for idx in range(1, 101) %} 
    - { primary_ip: 192.168.100.{{ idx }}, primary_gw: 192.168.100.254, extra_ip: 10.0.1.{{ idx }}, extra_gw: 10.0.1.254 } 
    "{% endfor %}" 

當我使用調試模塊打印IP_ADDRS,但它字面上打印列表中的所有項目,似乎Ansible不把這個變量作爲一個LIST,從而

with_items:{{IP_ADDRS}}

不能正常工作。

jinja2語句有什麼錯誤,或者有沒有辦法達到同樣的結果?

非常感謝,

/熊先生

回答

3

你可以定義你的對象的模板,並在循環中使用它:

--- 
- hosts: localhost 
    gather_facts: no 
    vars: 
    ip_template: 
     primary_ip: "192.168.100.{{ item }}" 
     primary_gw: "192.168.100.254" 
     extra_ip: "10.0.1.{{ item }}" 
     extra_gw: "10.0.1.254" 
    tasks: 
    # execute single task, no need in list 
    - debug: 
     msg: "{{ ip_template }}" 
     with_sequence: "start=1 count=5" 

    # construct list 
    - set_fact: 
     ip_list: "{{ (ip_list | default([])) + [ip_template] }}" 
     with_sequence: "start=1 count=5" 
    - debug: 
     msg: "{{ ip_list }}" 

如果你仍然想在你的變量定義ip_list,您需要構建複雜的Jinja2語句來生成JSON格式的列表,而不是像您嘗試的那樣生成YAML。這樣的字符串中有兩個對象的小例子:'[{"ip":"192.168.0.10","gw":"192.168.0.1"},{"ip":"192.168.0.20","gw":"192.168.0.1"}]'

+0

非常感謝。我會盡快試一試! – bruin

+0

正如我測試過的,這很好用! 「set_fact」是我不知道的,因爲我覺得我可以飛翔:)再次感謝康斯坦丁! – bruin

0

如果有很多複雜的變量需要由loopsif/else生成。有時候,當試圖在任務中產生它們時,它會變得討厭而且不太容易理解。以jinja模板格式創建變量文件可能會有所幫助。

例如,創建一個由神社模板生成的變量:

# variable file 
{% for idx in range(1, 101) %} 
- primary_ip: 192.168.100.{{ idx }} 
    primary_gw: 192.168.100.254 
    extra_ip: 10.0.1.{{ idx }} 
    extra_gw: 10.0.1.254 
{% endfor %} 

然後通過template查找插件讀取任務變量:

# playbook tasks 
- name: Read variables 
    set_fact: 
    ip_list: "{{ lookup('template', 'path_to_file') | from_yaml }}" 

而結果將是:

TASK [set_fact] ******************************************************************************************************************* 
Tuesday 06 February 2018 17:16:55 +0800 (0:00:00.110)  0:00:00.110 ****** 
Tuesday 06 February 2018 17:16:55 +0800 (0:00:00.108)  0:00:00.108 ****** 
ok: [localhost] 

TASK [debug] ********************************************************************************************************************** 
Tuesday 06 February 2018 17:16:55 +0800 (0:00:00.137)  0:00:00.247 ****** 
Tuesday 06 February 2018 17:16:55 +0800 (0:00:00.137)  0:00:00.245 ****** 
ok: [localhost] => { 
    "ip_list": [ 
     { 
      "extra_gw": "10.0.1.254", 
      "extra_ip": "10.0.1.1", 
      "primary_gw": "192.168.100.254", 
      "primary_ip": "192.168.100.1" 
     }, 
     { 
      "extra_gw": "10.0.1.254", 
      "extra_ip": "10.0.1.2", 
      "primary_gw": "192.168.100.254", 
      "primary_ip": "192.168.100.2" 
     }, 
     ...........