我想知道是否有一种标准/推荐的方法来修改 Ansible 中的角色变量。
作为角色作者,您可以分析角色的一组默认值,用户可以自由覆盖这些默认值。
当默认值是列表或字典(也可能是大列表或字典(时,就会出现问题。您不想强迫使用者复制/粘贴它们,因此您确实希望合并它们,允许使用者添加额外的值,甚至可能覆盖字典的某些键。
默认情况下,Ansible 不会合并,这很好。我希望没有人疯狂到试图改变他们的配置中的hash_behavior值。
我在野外看到的是人们添加第二个变量,如myrole_filelist_extend
,它在运行时与包含定义值的myrole_filelist
组合在一起。
还有硬币的另一面,用户可能希望从默认列表中删除某些内容,同时保留其余部分,并且可能避免复制默认值,因为他希望从直接在角色内部进行的默认值更改中受益。
我有点发现这种方法有点丑陋,因为它会产生更多的变量,有时会产生额外的set_fact将两者结合起来的步骤,甚至混淆,有些人错过了使用正确的方法。
有没有更清洁的方法可以做到这一点?
我不确定以下内容是否会完全达到您的目标,因为它仍然需要添加一些额外的变量。但这可以在没有额外set_fact
的情况下工作.
您没有举例说明要管理的列表类型。由于您在变量名称中提到了filelist
,因此我怀疑它是一个简单的字符串列表。尽管您可以使用相同的模式管理更复杂的对象列表,但可能会有点头疼。
测试playbook.yml
---
- hosts: localhost
gather_facts: false
roles:
- role1
在role1/tasks/main.yml
---
- name: Show file list
debug:
var: role1_files
在role1/vars/main.yml
.关于该文件的有趣部分是它比下面的defaults/main.yml
更难覆盖。因此,这在一定程度上保护了其中的变量,并且用户实际上不应该弄乱这些变量。有关详细信息,请参阅 ansible 变量优先级。
---
role1_files_default:
- /home/user/file1.sh
- /tmp/test.txt
- /etc/toto.cfg
role1_files: "{{ (role1_files_default | difference(role1_files_blacklist)) + role1_files_add }}"
终于在role1/defaults/main.yml
.这些实际上是您将向想要自定义角色的用户公开的唯一变量。
---
role1_files_blacklist: []
role1_files_add: []
现在,您可以轻松地将文件列入黑名单,并将文件添加到受保护的默认值中。为了方便起见,我在下面的证明测试中使用extra_vars
,但这些声明应该放在您的剧本/库存中
$ ansible-playbook playbook.yml
PLAY [localhost] **************************************************************************************************************************************************************************************************
TASK [role1 : Show file list] *************************************************************************************************************************************************************************************
ok: [localhost] => {
"role1_files": [
"/home/user/file1.sh",
"/tmp/test.txt",
"/etc/toto.cfg"
]
}
PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ ansible-playbook playbook.yml -e "{'role1_files_blacklist':['/etc/toto.cfg']}" -e "{'role1_files_add':['/some/other/file','/var/lib/supp']}"
PLAY [localhost] **************************************************************************************************************************************************************************************************
TASK [role1 : Show file list] *************************************************************************************************************************************************************************************
ok: [localhost] => {
"role1_files": [
"/home/user/file1.sh",
"/tmp/test.txt",
"/some/other/file",
"/var/lib/supp"
]
}
PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0