group_vars in ansible 在 vars_prompt 之前没有被读取吗?

Are group_vars in ansible not read before any vars_prompt?

我在 Ansible inventory/group_vars/all/vars 中定义了一个文件路径变量 sys_labels 指向一个 JSON 文件。

我正在通过 lookup('file', sys_labels) | from_json 在剧本的 vars 部分加载它。

在一个简单的剧本中调试它是可行的。但是,如果我包含一个使用 JSON 数据的 vars_prompt,它就会失败。但是,用实际路径替换 vars 部分中的 sys_labels 变量是可行的。
为什么会这样?

作品:

---
- hosts: localhost
  gather_facts: false
  vars:
    json: "{{ lookup('file', sys_labels) | from_json }}"
  tasks:
    - name: debug
      debug:
        msg: "{{ json }}"

其中 sys_labels 指向包含 JSON 结构的文件 labels.json,例如,

{ 
  "labels": { 
    "label1":"true",
    "label1":"false",
    "label2":"true",
    "label3":"true" 
  } 
}

添加 vars_prompt 失败:

---
- hosts: localhost
  gather_facts: false
  vars:
    json: "{{ lookup('file', sys_labels) | from_json }}"
  vars_prompt:
    - name: label_choice
      prompt: |
        {% for key in json.labels %}
        {{ loop.index0 }} - {{ key }}={{ json.labels[key] }}
        {% endfor %}
        Choose labels to apply [none]
      private: no
  tasks:
    - name: debug
      debug:
        msg: "{{ json }}\n\n{{ label_choice }}"

错误是

ERROR! {{ lookup('file', sys_labels) | from_json }}: 'sys_labels' is undefined.

用实际路径替换上面的文件路径变量 sys_labels 再次起作用:

---
- hosts: localhost
  gather_facts: false
  vars:
    json: "{{ lookup('file', '/path/to/labels.json') | from_json }}"
  vars_prompt:
    - name: label_choice
      prompt: |
        {% for key in json.labels %}
        {{ loop.index0 }} - {{ key }}={{ json.labels[key] }}
        {% endfor %}
        Choose labels to apply [none]
      private: no
  tasks:
    - name: debug
      debug:
        msg: "{{ json }}\n\n{{ label_choice }}"

这对我来说似乎很奇怪,看起来 vars_prompt 在全局 group_vars 被评估之前运行?

如果是这样,为什么 vars_prompt 仍然查看剧本的 vars 部分,但不承认 group_vars 中的映射?

感谢任何指点。

我在 ansible core 2.12.1,python 3.10.1,jinja 3.0.3

看起来确实是预期的行为。

来自 @bcoca,Ansible 的维护者:

at the time vars_prompt runs only extra vars are defined, so the when [the issue on which @bcoca was answering was about a when on vars_prompt, but it applies the same here -- Ed.] will not work with host/group vars nor facts.

来源:https://github.com/ansible/ansible/issues/13263#issuecomment-159037298

要解决这个问题,您可以使用 pause 模块。


鉴于剧本:

- hosts: localhost
  gather_facts: false
  vars: 
    json: "{{ lookup('file', sys_labels) | from_json }}"

  tasks:
    - pause: 
        prompt: |-
          {% for key in json.labels %}
          {{ loop.index0 }} - {{ key }}={{ json.labels[key] }}
          {% endfor %}
          Choose labels to apply [none]
      register: label_choice

    - name: debug
      debug:
        msg: "{{ json }}\n\n{{ label_choice.user_input }}"

这产生:

TASK [pause] **********************************************************************
[pause]
0 - foo=bar
1 - baz=qux
Choose labels to apply [none]:
foo
ok: [localhost]

TASK [debug] **********************************************************************
ok: [localhost] => 
  msg: |-
    {'labels': {'foo': 'bar', 'baz': 'qux'}}
  
    foo