我正在使用ansible管理生产配置以及流浪盒。 我的文件包含默认值: group_vars / all 。
---
env: prod
wwwuser: www-data
db:
root_pwd: root_pwd
pdo_driver: pdo_mysql
host: localhost
name: test
user: test
pwd: test
charset: utf8
domain: somedomain
projectdir: /var/www/application
webrootdir: "{{ projectdir }}/web"
在 host_vars / vagrantbox 中我希望有类似的内容:
db:
root_pwd: super_easy_password
但是这个完全超越db dictrionary,而我想覆盖单键。 如何实现?
更新1 刚用ansible.cfg检查:
[defaults]
host_key_checking=false
hash_behaviour=merge
groups_vars /所有
db:
root_pwd: some_strong_pwd
pdo_driver: pdo_mysql
host: localhost
name: dbname
user: dbuser
pwd: some password
charset: utf8
host_vars / vagrantbox
db:
root_pwd: root
我收到以下错误:
One or more undefined variables: 'dict object' has no attribute 'name'
我做错了什么?
答案 0 :(得分:16)
默认情况下,Ansible会覆盖第一级的变量。如果您希望能够合并字典,则必须更改ansible.cfg
文件并设置:
hash_behaviour=merge
(默认值为replace
)。
请注意Ansible团队does not recommend this(但不解释原因)。
我想这是用户之间真正的划分设置。一种为所有人做过的决定:当你开始使用这个功能时,你不能回去,而你可能无法与replace
类型的人共享你的剧本。
然而,您仍然可以从那里的剧本中受益(我不会将剧本作为“特征”使用replace
行为)。这就像拥有AB血型,是一个通用的接收器......但由于魔法通常以可变分辨率发生,而不是在任务或模板内部,我认为通常可以在不做任何改动的情况下分享你的角色。
如果您需要覆盖单个键,比如角色参数,则必须以某种复杂的方式传递参数。
例如,要覆盖特定角色的post_max_size
字典中的upload_max_size
和php5
个键,您必须这样做:
- { role: php5-fpm, php5: { post_max_size: 40M,
upload_max_filesize: 20M }}
这就是说,我从一开始就使用merge
行为,我对它很满意。保持变量组织非常方便。
答案 1 :(得分:14)
从Ansible 2.0开始,您可以使用Jinja2 combine
过滤器合并YAML哈希/词典,而无需在hash_behavior=merge
文件中的全局级别设置ansible.cfg
。
相关文档:http://docs.ansible.com/ansible/playbooks_filters.html#combining-hashes-dictionaries
答案 2 :(得分:5)
我找到的最好的方法是使用变量作为字典项的值,并覆盖它。我发现这允许简单而强大的变量优先级与ansible的变量顺序
有关---
root_pw_value: ParentPassword
parent_dict:
- root_pw: "{{ root_pw_value }}"
注意:role/child/meta/main.yml
包含dependencies: - { role: parent }
---
root_pw_value: ChildPassword
---
- hosts: all
roles:
- child
- debug: var=parent_dict
运行ansible -i localhost, --connection="local" play-me.yml
,您将获得以下输出:
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [localhost]
TASK: [parent | debug var=parent_dict] ****************************************
ok: [localhost] => {
"var": {
"parent_dict": [
{
"root_pw": "ParentPassword"
}
]
}
}
TASK: [child | debug var=parent_dict] *****************************************
ok: [localhost] => {
"var": {
"parent_dict": [
{
"root_pw": "ChildPassword"
}
]
}
}
PLAY RECAP ********************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
这些都是默认值。如果您在更具体的优先级别指定root_pw_value
,例如库存组/主机变量,角色变量,命令行上的extra_vars,或者优先顺序[0]中的任何内容,您将获得这些优先级。 / p>
答案 3 :(得分:0)
刚尝试使用ansible 1.9.3,它运行正常。不确定,但似乎你只是在group_vars
目录(不是groups_vars
)的名称中输入错字。