ansible-根据角色默认变量中的条件自定义列表内容

ansible-根据角色默认变量中的条件自定义列表内容,ansible,Ansible,我希望在基于条件的角色的默认main.yml中定义一个dict列表。你知道怎么做吗 我试过: pkg: "[ {% if 'web' in group_names %} { name: 'pkg-php' }, { name: 'pkg-web' },

我希望在基于条件的角色的默认main.yml中定义一个dict列表。你知道怎么做吗

我试过:

pkg: "[ 
{% if 'web' in group_names %}                                               
        { name: 'pkg-php' },                                                
        { name: 'pkg-web' },                                                
{% endif %}                                                                 
    { name: 'pkg-libs' },                                                   
    { name: 'pkg-core' } ]"
问题是,它返回的是一个字符串,而不是dict的列表

预期输出

当主机位于“web”组中时:

pkg:
  - { name: 'pkg-php' }                                                
  - { name: 'pkg-web' }                                                
  - { name: 'pkg-libs' }                                                   
  - { name: 'pkg-core' }
如果没有:

pkg:
  - { name: 'pkg-libs' }                                                   
  - { name: 'pkg-core' }

它可能有点冗长,但为什么不把外部的块包装起来呢

{% if 'web' in group_names %}                                               
pkg:
  - { name: 'pkg-php' }                                                
  - { name: 'pkg-web' }                                                
  - { name: 'pkg-libs' }                                                   
  - { name: 'pkg-core' }
{% else %}
pkg:
  - { name: 'pkg-libs' }                                                   
  - { name: 'pkg-core' }
{% endif %}

它可能有点冗长,但为什么不把外部的块包装起来呢

{% if 'web' in group_names %}                                               
pkg:
  - { name: 'pkg-php' }                                                
  - { name: 'pkg-web' }                                                
  - { name: 'pkg-libs' }                                                   
  - { name: 'pkg-core' }
{% else %}
pkg:
  - { name: 'pkg-libs' }                                                   
  - { name: 'pkg-core' }
{% endif %}
IMHO,不可能有条件地包含角色的默认变量(字符串除外)

pkg: |
  {% if inventory_hostname in groups['web'] %}
  inventory_hostname IS member of the group 'web'
  {% else %}
  inventory_hostname IS NOT member of the group 'web'
  {% endif %}
有一种选择是有条件的。您可能需要检查并决定这是否适合项目的其他潜在条件

要继续包含变量,请将变量放入文件中

$ cat vars/all.yml
pkg:
  - { name: 'pkg-libs' }
  - { name: 'pkg-core' }
$ cat vars/web.yml
pkg:
  - { name: 'pkg-php' }
  - { name: 'pkg-web' }
如果inventory_主机名(播放应用到的主机)是组web的成员,则包含文件vars/web.yml中的变量。下面的剧本

- hosts: srv-web-01
  vars:
    web:
      pkg: []
  tasks:
    - include_vars:
        file: vars/all.yml
        name: common
    - include_vars:
        file: vars/web.yml
        name: web
      when: inventory_hostname in groups['web']
    - set_fact:
        pkg: "{{ pkg|default([]) + web.pkg + common.pkg }}"
    - debug:
        var: pkg
给予

标准溶液

Ansible标准解决方案包括一组主机的变量,这些变量位于角色默认值的右上方。使用以下组变量可以简单地实现预期输出

高级解决方案

如果公共项发生更改,则更新许多组变量文件是无效的。可以声明模块组特定变量

$ cat group_vars/all.yml
pkg_all:
  - { name: 'pkg-libs' }
  - { name: 'pkg-core' }
$ cat group_vars/web.yml
pkg_web:
  - { name: 'pkg-php' }
  - { name: 'pkg-web' }
并连接主机变量空间中的所有pkg_*变量,即主机所属的组变量中声明的pkg_*变量

- set_fact:
    pkg: "{{ pkg|default([]) + lookup('vars', item) }}"
  loop: "{{  hostvars[inventory_hostname].keys()|
             select('match', '^pkg_(.*)$')|
             list }}"
- set_fact:
    pkg: "{{ pkg|unique }}"
- debug:
    var: pkg
IMHO,不可能有条件地包含角色的默认变量(字符串除外)

pkg: |
  {% if inventory_hostname in groups['web'] %}
  inventory_hostname IS member of the group 'web'
  {% else %}
  inventory_hostname IS NOT member of the group 'web'
  {% endif %}
有一种选择是有条件的。您可能需要检查并决定这是否适合项目的其他潜在条件

要继续包含变量,请将变量放入文件中

$ cat vars/all.yml
pkg:
  - { name: 'pkg-libs' }
  - { name: 'pkg-core' }
$ cat vars/web.yml
pkg:
  - { name: 'pkg-php' }
  - { name: 'pkg-web' }
如果inventory_主机名(播放应用到的主机)是组web的成员,则包含文件vars/web.yml中的变量。下面的剧本

- hosts: srv-web-01
  vars:
    web:
      pkg: []
  tasks:
    - include_vars:
        file: vars/all.yml
        name: common
    - include_vars:
        file: vars/web.yml
        name: web
      when: inventory_hostname in groups['web']
    - set_fact:
        pkg: "{{ pkg|default([]) + web.pkg + common.pkg }}"
    - debug:
        var: pkg
给予

标准溶液

Ansible标准解决方案包括一组主机的变量,这些变量位于角色默认值的右上方。使用以下组变量可以简单地实现预期输出

高级解决方案

如果公共项发生更改,则更新许多组变量文件是无效的。可以声明模块组特定变量

$ cat group_vars/all.yml
pkg_all:
  - { name: 'pkg-libs' }
  - { name: 'pkg-core' }
$ cat group_vars/web.yml
pkg_web:
  - { name: 'pkg-php' }
  - { name: 'pkg-web' }
并连接主机变量空间中的所有pkg_*变量,即主机所属的组变量中声明的pkg_*变量

- set_fact:
    pkg: "{{ pkg|default([]) + lookup('vars', item) }}"
  loop: "{{  hostvars[inventory_hostname].keys()|
             select('match', '^pkg_(.*)$')|
             list }}"
- set_fact:
    pkg: "{{ pkg|unique }}"
- debug:
    var: pkg

这似乎不是正确的语法:有问题的行似乎是:{%if'web'在group_names%}这似乎不是正确的语法:有问题的行似乎是:{%if'web'在group_names%}谢谢Vladimir。但我的问题是我想在一个角色的default/main.yml中声明这个列表,所以我们不必费心在清单中定义它。所以你的建议完全满足了我的需要。但我的问题是我想在一个角色的default/main.yml中声明这个列表,所以我们不必费心在清单中定义它。所以你的建议完全满足了我的需要