如何在 Ansible 中设置 playbook 级别的变量?

How can I set playbook-level variables in Ansible?

我正在尝试在 playbook 中设置变量,以便在 playbook 级别而不是主机级别的整个 playbook 其余部分都可以访问它们。示例(其中 machine_mode 变量从命令行传入):

- name: configure and install everything for the new boxes
  sudo: True
  hosts: new_hosts
  vars: [
      docker_required_roles: "['app_server', 'other_app_server']",
      pip_required_roles: "['some_server', 'other_server']",
      docker_required: "{{ machine_mode }} in docker_required_roles",
      pip_required: "{{ machine_mode }} in pip_required_roles"
    ]
  pre_tasks:
  - name: Gathering ec2 facts
    action: ec2_facts
  roles:
  #install docker and pip when required
  - { role: bobbyrenwick.pip, when: "pip_required"}
  - { role: angstwad.docker_ubuntu, when: "docker_required"}

不幸的是,当我 运行 这个时,它用 error while evaluating conditional: dev in pip_required_roles 中断了。有没有其他方法可以定义这些变量,以便在整个剧本中访问它们?

这个 vars as booleans 事情变得棘手。这是我能够开始工作的:

vars:
  docker_required_roles: ['app_server', 'other_app_server']
  pip_required_roles: ['some_server', 'other_server']
  docker_required: '{{"{{machine_mode}}" in docker_required_roles}}'
  pip_required: '{{"{{machine_mode}}" in pip_required_roles}}'
tasks:
  - debug: var=pip_required
  - debug: var=pip_required
    when: '{{pip_required | bool}}'

注意角色名称字符串列表,请使用实际的 YAML 正确表示它们,而不是 python 代码字符串。

对于引用,您需要在它周围加上额外的大括号,以便通过 jinja2 对它进行 运行 处理并计算 "in" 表达式,而不是只留下字符串 "dev in docker_required_roles".

引用变量时,您必须始终记住使用bool过滤器以避免字符串"False"被解释为真值。

看来你误解了你的剧本在哪里。

错误告诉您它无法评估您在 pip 角色上设置的条件,因为您将字符串文字 "dev in pip_required_roles" 而不是 truefalse.

相反,您需要让 Ansible 正确评估您的条件语句,以便为您的条件角色提供一个布尔值。你可以通过改变你的 vars 块来做到这一点:

- name: configure and install everything for the new boxes
  sudo: True
  hosts: all
  vars:
    - docker_required_roles: ['app_server', 'other_app_server']
    - pip_required_roles   : ['some_server', 'other_server']
    - docker_required      : machine_mode in docker_required_roles
    - pip_required         : machine_mode in pip_required_roles
  roles:
  #install docker and pip when required
  - { role: bobbyrenwick.pip, when: "pip_required"}
  - { role: angstwad.docker_ubuntu, when: "docker_required"}

这会将 docker_require_rolespip_required_roles 变量的字符串文字更改为列表,然后使用 Python 将 docker_requiredpip_required 变量更改为条件in 运算符(注意它们周围缺少双引号)。

作为一个小说明,我还调整了 vars 块以使用 YAML's list syntax 而不是您选择的 Python 样式语法,但这更多是个人偏好而不是其他任何东西。您也可以像这样分解 docker_require_rolespip_required_roles 变量的列表以使用 YAML 语法,但出于某种原因,这对我来说看起来有点尴尬:

  ...
  vars:
    - docker_required_roles:
      - 'app_server'
      - 'other_app_server'
    - pip_required_roles   :
      - 'some_server'
      - 'other_server'
    - docker_required      : machine_mode in docker_required_roles
    - pip_required         : machine_mode in pip_required_roles
  roles:
    ...

至于你想要完成什么的更广泛的想法,看起来你最好用不同的清单文件和组变量来做这件事。