首页 > 解决方案 > ansible 与基于字典的默认变量

问题描述

我的 Ansible 角色中有一些默认变量

sysproperties:
 java_awt_headless:
   key: "java.awt.headless"
   value: "true"
   enabled: "true"
 java_iccprofile_path:
   key: "java.iccprofile.path"
   value: "image/iccprofiles"
   enabled: "true"
...
...

它们最终应该是一个基于 jinja2 模板的 XML 文件

{% for key, value in sysproperties.items() %}
<sysproperty key="{{ value.key }}" value="{{ value.value }}" enabled="{{ value.enabled }}"/>
{% endfor %}

要更改默认值之一,我实际上希望它可以像这样简单:

---
- name: run this
  hosts: myTestHost
  vars:
     sysproperties.java_iccprofile_path.value: "somewhere/else"
  roles:
    - role: myRole

但到目前为止,我只是发现我需要一个额外的任务,只是为了改变这个设置

  pre_tasks:
    - set_fact:
        sysproperties: "{{ sysproperties | combine(new_item, recursive=true) }}"
      vars:
        new_item: "{ 'java_iccprofile_path': { 'value': 'somewhere/else' } }"
      with_dict: "{{ sysproperties }}"

所以我的问题是:有没有更简单的方法呢?我是否应该安排我的默认值有点不同,以便更容易更改?

[编辑]为了更清楚我的实际问题是什么:

我将设置存储在列表/字典中,以通过模板模块将它们写入 XML 文件。我喜欢任何使用我的角色能够轻松更改或添加设置的人。这样做的最佳实践方法是什么?我现在运行 pre_task 的方式是正确的还是有更好的方法来做到这一点?

标签: ansiblejinja2ansible-template

解决方案


您可以做的一件事是在调用角色时覆盖该变量。你可以在你的剧本中这样做:

---
- hosts: localhost
  roles:
    - {role: "myRole", sysproperties.java_iccprofile_path.value: "somwhere/else"}
...

希望这可以帮助。

更新嗯。有趣的。这是我的测试设置:

myRole
+ tasks
| + main.yml
+ vars
| + main.yml
+ testrole.yml

这是 myRole/tasks/main.yml 的内容

---
- name: Debugging
  debug: var=foo
...

这是 myRole/vars/main.yml 的内容

---
foo: "blah"
...

这是 testrole.yml 的内容

---
- hosts: localhost
  roles:
    - myRole
...

如果我跑

ansible-playbook ./testrole.yml

我明白了

PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [defaults : Debugging] ****************************************************
ok: [localhost] => {
    "foo": "blah"
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

如果我将 testrole.yml 更新为以下内容:

---
- hosts: localhost
  roles:
    - {role: "myRole", foo: "yuck"}
...

我明白了

PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [defaults : Debugging] ****************************************************
ok: [localhost] => {
    "foo": "yuck"
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

所以,我试着用字典。

myRole/vars/main.yml:

---
sysproperties:
  java_something_else:
    key: "path"
  java_iccprofile_path:
    value: "i/am/here"
...

如果我将 sysproperties.java_iccprofile_path.value: "some/where/else" 放入 testrole.yml,它会失败。如果我在 testrole.yml 中有以下内容,它会起作用:

---
- hosts: localhost
  roles:
    - {role: "myRole", sysproperties: {java_iccprofile_path: {value: "yuck"}}}
...

上面的输出是

PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [defaults : Debugging] ****************************************************
ok: [localhost] => {
    "sysproperties": {
        "java_iccprofile_path": {
            "value": "yuck"
        }
    }
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

如您所见,它替换了值,但也删除了其他值。

我在这里发现,将 hash_behavior 的值更改为在 ansible.cfg 文件中合并将保留旧内容,并且只会覆盖您告诉它覆盖的内容。

PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [defaults : Debugging] ****************************************************
ok: [localhost] => {
    "sysproperties": {
        "java_iccprofile_path": {
            "value": "yuck"
        }, 
        "java_something_else": {
            "key": "path"
        }
    }
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0   

推荐阅读