使用ansible从csv文件中读取变量名并替换为值

read variable names from csv file with ansible and substitute with values

我正在尝试创建一个特定于环境的配置文件,该文件由从 csv 文件读取的键 = 值对组成。 csv 文件包含许多环境的配置设置,我需要根据 playbook 使用的清单为每个环境生成一个配置文件。

CSV 文件settings.csv

Key|siteA-test|siteA-prod|siteB-test|siteB-prod|Comment
param1|true|true|false|false|Comment for param1
param2|http://test|http://prod|||Comment for param2
param3|ansible_variable_A_test|ansible_variable_A_prod|ansible_variable_B_test|ansible_variable_B_prod|Variable must be taken from secret vault
param4|ansible_variable_C_test|ansible_variable_C_prod|ansible_variable_D_test| ansible_variable_D_prod|Another variable from variable file

siteA-test 的预期文件如下所示:

param1=true # Comment for param1
param2=http://test # Comment for param2
param3=secret_value_from_vault # Variable must be taken from secret vault 
param4=1984 # Another variable from variable file

我将使用 lineinfile 模块将其写入文件。

到目前为止,我已经(有点难看)弄清楚了如何为特定环境获取值,首先创建一个键字典,然后迭代该字典。 我不喜欢我必须读取 CSV 文件两次,但这有效。

- hosts: hostgroupA
  tasks:
  - name: Read CSV file and return a dictionary
    community.general.read_csv:
      path: settings.csv
      delimiter: '|'
      key: Key
      strict: yes
    register: config
    delegate_to: localhost

  - ansible.builtin.debug:
      msg: "Key {{ lookup('csvfile', '{{item.key}} file=settings.csv col=1 delimiter=|') }}, value: {{ lookup('csvfile', '{{item.key}} file=settings.csv col=2 delimiter=|')}} "
    loop: "{{ config.dict| dict2items }}"
    delegate_to: localhost

问题是我不知道是否可以用 vault 或其他变量文件中的实际值替换 param3 和 param4 的变量名。

使用 lookup 插件 vars。参见 ansible-doc -t lookup vars。例如,给定简化库存。 (如果需要,请加密 test*_var。最好的选择可能是将变量放入存储在 host_vars 中的加密文件中)。

shall> cat hosts
testA testA_var="A"
testB testB_var="B"

和简化的 CSV 文件 settings.csv,例如

shell> cat settings.csv
Key|testA|testB|Comment
param1|true|false|Comment for param1
param2|testA_var|testB_var|Var from vault

剧本

- hosts: all
  tasks:
  - read_csv:
      path: settings.csv
      delimiter: '|'
      key: Key
      strict: yes
    register: config
    delegate_to: localhost
    run_once: true

  - debug:
      msg: "param1: {{ _p1 }}, param2: {{ _p2 }}"
    vars:
      _p1: "{{ config.dict.param1[inventory_hostname] }}"
      _p2: "{{ lookup('vars', config.dict.param2[inventory_hostname]) }}"

给予

ok: [testB] => 
  msg: 'param1: false, param2: B'
ok: [testA] => 
  msg: 'param1: true, param2: A'

如果您想迭代主机,例如

  - debug:
      msg: "{{ item }} param1: {{ _p1 }}, param2: {{ _p2 }}"
    loop: "{{ ansible_play_hosts }}"
    vars:
      _p1: "{{ config.dict.param1[item] }}"
      _varname: "{{ config.dict.param2[item] }}"
      _p2: "{{ hostvars[item][_varname] }}"
    run_once: true

给予

  msg: 'testA param1: true, param2: A'
  msg: 'testB param1: false, param2: B'