ansible - 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 的方式是正确的还是有更好的方法来做到这一点?
解决方案
您可以做的一件事是在调用角色时覆盖该变量。你可以在你的剧本中这样做:
---
- 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
推荐阅读
- database - MS 访问 年龄限制在 18 岁或以上
- c# - 基于属性数量的自定义 JSON 格式
- javascript - 如何使用 $geowithin 查找文档,然后使用 $geonear 聚合管道创建距离场?
- javascript - 问题检查元素是否在 javascript 中处于“活动状态”
- html - 不同列中第一个 div 的高度相等(引导程序 4)
- arrays - 在具有 React 状态的 div 网格中跟踪选定的 div
- python - 使用 django 形式执行一些计算。哪个框架?
- php - 模型观察者:restored() 和 restore()
- html - 如何让图像和其他元素保持原位
- swift - 这个 RxAlamofire 源代码中的实际 API 调用在哪里?