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

时间:2019-06-22 21:18:59

标签: ansible

我正在基于条件在角色的默认main.yml中定义字典列表。你知道怎么做吗?

我尝试过:

pkg: "[ 
{% if 'web' in group_names %}                                               
        { name: 'pkg-php' },                                                
        { name: 'pkg-web' },                                                
{% endif %}                                                                 
    { name: 'pkg-libs' },                                                   
    { name: 'pkg-core' } ]"

问题在于,它返回的字符串不是字典列表

期望输出

当主机位于“网络”组中时:

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

否:

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

2 个答案:

答案 0 :(得分:0)

可能有些冗长,但为什么不只包装外面的块呢?

{% 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 %}

答案 1 :(得分:0)

恕我直言,对于Jinja2,不可能有条件地包括角色的默认变量,而不是字符串。

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 %}

可以选择有条件地include_vars。您可能需要查看Variable precedence: Where should I put a variable?并确定这是否适合项目的其他潜在条件。

要继续进行 include_vars ,请将变量放入文件中

$ cat vars/all.yml
pkg:
  - { name: 'pkg-libs' }
  - { name: 'pkg-core' }
$ cat vars/web.yml
pkg:
  - { name: 'pkg-php' }
  - { name: 'pkg-web' }

如果 inventory_hostname (应用播放的主机)是 web 组的成员,则来自文件 vars / web.yml <的变量/ em>。下面的游戏

- 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

给予

"pkg": [
    {
        "name": "pkg-php"
    }, 
    {
        "name": "pkg-web"
    }, 
    {
        "name": "pkg-libs"
    }, 
    {
        "name": "pkg-core"
    }
]

标准解决方案

group_vars包括一组主机变量的一个可行的标准解决方案是角色默认值上方的Variable precedence。可以使用以下 group_vars

简单地实现预期的输出
$ cat group_vars/all.yml 
pkg:
  - { name: 'pkg-libs' }
  - { name: 'pkg-core' }
$ cat group_vars/web.yml 
pkg:
  - { name: 'pkg-libs' }
  - { name: 'pkg-core' }
  - { name: 'pkg-php' }
  - { name: 'pkg-web' }

高级解决方案

如果公用项目发生更改,更新许多 group_vars 文件效率不高。可以声明模块化组特定变量

$ 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_ *,即在主机 group_vars 中声明的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