具有动态 key/value 的 Ansible 设置事实

Ansible Setting fact with dynamic key/value

我正在尝试从我从另一个角色调用的命令任务的标准输出中设置 ansible 事实。

角色A:

- name: example command
  command: client get -s {{ service }}
  register: vars_string

- name: set vars
  set_fact: vars={{ vars_string.stdout.split('\n')}}
  when:
    - vars_string.stdout | length > 0

- name: set vars as facts
  set_fact: "{{ item }}"
  with_items: "{{ vars }}"

变量输出:

"vars": [
        "tst=ansible", 
        "example=values"
]

角色B:

- debug:
    var: tst

角色 B 的结果:

预期:{ "tst": "ansible" }

现实:{ "tst": "VARIABLE IS NOT DEFINED!" }

我曾尝试将 vars 吐入字典并使用 set_fact: "{{ item.key }}" : "{{ item.value }}"。这返回了相同的结果。

我希望在以后的角色中能够通过命令返回的变量名来调用。有什么想法吗?

关于您的代码片段的两点您可能感兴趣:

  • 您的命令的输出已经有换行符版本,它是 vars_string.stdout_lines
  • 我不知道你是否只是偶然选择了那个变量,或者你试图实际 分配 vars 内置变量,但是要么别这样

据我所知,不存在仅从任务中分配任意顶级主机事实的受支持语法。

您有两个选择:将这些变量写入文件,然后使用 include_vars: 将它们读入——这会将它们指定为宿主事实,或者按照 set_fact: 想要的方式让步事情并满足于生活在 hostfacts

中已知键下的那些动态变量

我们先展示后者,因为它更短:

- set_fact:
    my_facts: >-
      {{ "{" + (vars_string.stdout_lines
      | map('regex_replace', '^([^=]+)=(.+)', '"": ""')
      | join(",")) + "}"
      }}
  when:
  - vars_string.stdout | length > 0

当然,请注意,如果您的键或值中包含非 JSON 友好字符,则欺骗将不起作用,但如果该简单版本不起作用,请提出后续问题,因为同样的技巧还有很多

include_vars:方式是:

- tempfile:
    state: file
    suffix: .json
  register: vars_filename

- copy:
    dest: '{{ vars_filename.path }}'
    content: >-
       {{ "{" + (vars_string.stdout_lines
       | map('regex_replace', '^([^=]+)=(.+)', '"": ""')
       | join(",")) + "}"
       }}

- include_vars:
    file: '{{ vars_filename.path }}'

- file:
    path: '{{ vars_filename.path }}'
    state: absent