Python

使用 jinja 在 Ansible 中動態創建列表

  • March 29, 2022

我需要動態設置一個新的列表類型變數list var。

這是一個基本的劇本範例:

 vars:
   app_instances:
     - host_name: host1-domain
       inst_count: 3
     - host_name: host2-domain
       inst_count: 1
     - host_name: host3-domain
       inst_count: 1

 tasks:
   - set_fact:
       instance_config: >-
         {% set inst_config = [] %}
         {% for inst in app_instances %}
           {% for inst_num in range(inst.inst_count) %}
             {% set node_number = inst.host_name.split('-') | first | replace('host', '') %}
             {% set host_name = "host_name" %}
             {% set host_num = "host_num" %}
             {% set inst_name = "inst_name" %}
             {% set node_conf = { host_name: inst.host_name, host_num: node_number, inst_name: inst_num+1 } %}
             {{ inst_config.append(node_conf) }}
           {% endfor %}
         {% endfor %}
         {{ inst_config|join(",") }}

   - debug:
       msg: "{{ instance_config }}"

這顯然將 設置instance_config為具有以下內容的字元串:

"instance_config": "                           \n                          \n                          \n                            \n                            \n   {'host_name': 'host1-domain', 'host_num': '1', 'inst_name': 1},{'host_name': 'host1-domain', 'host_num': '1', 'inst_name': 2},{'host_name': 'host1-domain', 'host_num': '1', 'inst_name': 3},{'host_name': 'host2-domain', 'host_num': '2', 'inst_name': 1},{'host_name': 'host3-domain', 'host_num': '3', 'inst_name': 1}"

因此,雖然我得到的列表的結構是正確的,但它是一個字元串,我似乎無法將它變成一個可以作為列表的變數。我在這裡想念什麼?我最終需要的是一個變數:

instance_config = [
 {'host_name': 'host1-domain', 'host_num': '1', 'inst_name': 1},
 {'host_name': 'host1-domain', 'host_num': '1', 'inst_name': 2},
 {'host_name': 'host1-domain', 'host_num': '1', 'inst_name': 3},
 {'host_name': 'host2-domain', 'host_num': '2', 'inst_name': 1},
 {'host_name': 'host3-domain', 'host_num': '3', 'inst_name': 1}
]

在我找到解決方案時回答我自己的問題:

  1. do在 ansible.cfg 中啟用jinja 擴展:jinja2_extensions = jinja2.ext.do
  2. 替換{{ inst_config.append(node_conf) }}{% do inst_config.append(node_conf) %}
  3. {%-使用和修剪空格-%}

任務的最終結果set_fact如下所示:

   - set_fact:
       instance_config: >-
         {%- set instance_config = [] -%}
         {%- for inst in app_instances -%}
           {%- for inst_num in range(inst.inst_count) -%}
             {%- set node_number = inst.host_name.split('-') | first | replace('host', '') | int -%}
             {%- set host_name = "host_name" -%}
             {%- set host_num = "host_num" -%}
             {%- set inst_name = "inst_name" -%}
             {%- set node_conf = { host_name: inst.host_name, host_num: node_number, inst_name: inst_num+1 } -%}
             {%- do instance_config.append(node_conf) -%}
           {%- endfor -%}
         {%- endfor -%}
         {{ instance_config }}

引用自:https://serverfault.com/questions/1043047