Ansible 通过数组嵌套循环把 yaml 内容写入 ini 配置的新思路

昨天遇到一个问题场景,我需要修改一个 ini 配置文件,ansible 的 ini_file 模块里需要定义 section, option 和 value 三个数据。

那么,我如何可以通过一个通用的变量数组,把数据套用到 ini 文件里呢?

假设我的 ini 文件内容是:

[log]
level = info
max_size = 100

[storage]
data_path = /mnt/data
log_path = /mnt/log

我写了一个 yaml 格式的字典,如下:

node_config_ini:
  log:
    level: warn
    max_size: 200
  storage:
    data_path: /tmp/data
    log_path: /tmp/log

摸索的过程就不详细写了,反正 ansible 的 loop 功能没有适合我的。于是我选择直接用 python 的嵌套循环来生成一个 list:

- hosts: localhost
  gather_facts: false
  vars:
    node_config_ini:
      log:
        level: warn
        max_size: 200
      storage:
        data_path: /tmp/data
        log_path: /tmp/log

  tasks:
    - set_fact:
        ini_items: "{{ item.split(';') }}"
      with_items: >-
        {%- for section in node_config_ini | dict2items -%}
        {%- for option in section.value | dict2items -%}
          {{ section.key }},{{ option.key }},{{ option.value }}
        {%- if loop.nextitem is defined -%};{%- endif -%}
        {%- endfor -%}
        {%- if loop.nextitem is defined -%};{%- endif -%}
        {%- endfor -%}
      loop_control:
        label: "{{ item.split(';') }}"

    - debug:
        msg: "{{ item.split(',') }}"
      loop: "{{ ini_items }}"

set_fact 和 debug 打印出来的内容如下:

TASK [set_fact] *******************************************************************************
星期二 22 二月 2022  15:22:42 +0800 (0:00:00.055)       0:00:00.072 **************** 
ok: [localhost] => (item=['log,level,warn', 'log,max_size,200', 'storage,data_path,/tmp/data', 'storage,log_path,/tmp/log'])

TASK [debug] *******************************************************************************
星期二 22 二月 2022  15:22:42 +0800 (0:00:00.057)       0:00:00.130 **************** 
ok: [localhost] => (item=log,level,warn) => {
    "msg": [
        "log",
        "level",
        "warn"
    ]
}
ok: [localhost] => (item=log,max_size,200) => {
    "msg": [
        "log",
        "max_size",
        "200"
    ]
}
ok: [localhost] => (item=storage,data_path,/tmp/data) => {
    "msg": [
        "storage",
        "data_path",
        "/tmp/data"
    ]
}
ok: [localhost] => (item=storage,log_path,/tmp/log) => {
    "msg": [
        "storage",
        "log_path",
        "/tmp/log"
    ]
}

这样,我就可以再根据 , 来分割数据,填入 ini 文件里,如下:

- ini_file:
    path: /tmp/test.ini
    create: true
    section: "{{ item.split(',')[0] }}"
    option: "{{ item.split(',')[1] }}"
    value: "{{ item.split(',')[2] }}"
  loop: "{{ ini_items }}"

顺利地把 ini 内容修改了:

cat /tmp/test.ini

[log]
level = warn
max_size = 200

[storage]
data_path = /tmp/data
log_path = /tmp/log
上一篇:云效DevOps训练营第1天打卡任务——熟悉项目源码,并在本地完成构建部署


下一篇:Certbot免费https证书