Ansible:定义剧本;“违约”;在角色上具有优先权但在资源清册中可重写的变量 TL;博士
使用Ansible,我试图在playbook级别定义某种默认变量—我们称之为playbook默认值—它优先于其他角色默认值,但可以被库存库存组_vars/all变量覆盖 如何定义某种playbook默认值变量,该变量优先于其他角色默认值,但可被库存(环境)覆盖Ansible:定义剧本;“违约”;在角色上具有优先权但在资源清册中可重写的变量 TL;博士,ansible,ansible-2.x,ansible-inventory,Ansible,Ansible 2.x,Ansible Inventory,使用Ansible,我试图在playbook级别定义某种默认变量—我们称之为playbook默认值—它优先于其他角色默认值,但可以被库存库存组_vars/all变量覆盖 如何定义某种playbook默认值变量,该变量优先于其他角色默认值,但可被库存(环境)覆盖 当前Ansible 2.x变量优先级如下: 角色默认值 清单文件或脚本组变量 库存组\变量/全部 剧本组\u vars/all 我希望实现的目标是: 角色默认值 剧本默认设置 清单文件或脚本组变量 库存组\u变量/全部 剧本组\u
当前Ansible 2.x变量优先级如下:
- 角色默认值
- 清单文件或脚本组变量
- 库存组\变量/全部
- 剧本组\u vars/all
- 角色默认值
- 剧本默认设置
- 清单文件或脚本组变量
- 库存组\u变量/全部
- 剧本组\u vars/all
- “外部”组件变量(来自Galaxy的角色)
- “应用程序”变量(剧本变量)
- “环境”变量(开发、测试等)
让我们考虑一个由几个与Web服务器交互的服务组成的应用程序。这些服务是通用的,并在我的组织的其他部分重复使用,但在我的情况下,我使用了apache2。我有以下角色:
- 阿帕奇
- 绿色环保服务
- blue_服务
- 红濸服务
# roles/apache/defaults/main.yml
apache_listen_port: 80
# roles/green_service/defaults/main.yml
green_service_port: 80
# roles/blue_service/defaults/main.yml
blue_service_port: 80
# roles/red_service/defaults/main.yml
red_service_port: 80
每个服务都必须知道apache端口,这在缺省值中表示。如果其他应用程序需要Nginx或其他web服务器的绿色服务,它们只需要包含相关的角色
现在,如果我想在一个或多个环境中将端口从80 ot 8081更改,该怎么办
“直截了当”的方式
。。我最终不得不在每个环境中复制所有这些变量,例如:
# production/group_vars/all/all.yml
apache_listen_port: 8081
green_service_port: 8081
blue_service_port: 8081
red_service_port: 8081
# ... and so on in each environments inventory!
在这个简单的示例中,这可能很好,但当您有10+个服务和5+个环境时,这将成为一场噩梦。。。更新一个简单的变量可能会对许多服务产生影响,并且很难维护和理解
从回答“您的服务设计可能是错误的…”中可以看出,我正在寻找避免这种情况的方法
我想达到的目标
我希望实现的是能够在playbook级别表示我的服务和Web服务器之间的变量链接,例如:
# somewhere in my playbook .yml
# these variables override roles default
# but can be overriden in my inventories
myapp_port: 80
apache_listen_port: "{{ myapp_port }}"
green_service_port: "{{ myapp_port }}"
blue_service_port: "{{ myapp_port }}"
red_service_port: "{{ myapp_port }}"
现在,在每个环境中,我只需覆盖一个且仅覆盖一个变量,例如:
# production/group_vars/all/all.yml
myapp_port: 8081
我没有找到一个明智的方法,不把我的剧本复杂化,以达到类似的效果
有了Ansible,有没有合适的方法来实现这个剧本变量优先于其他默认变量而不是清单变量 请记住,在Ansible
{{…}
中,表达式通常是以惰性方式模板化的(除了set\u fact
),因此您不会“分配”变量,而是告诉Ansible如何在运行时获取值
如果您可以控制角色:
您可以设置角色/apache/defaults/main.yml
:
apache_listen_port: "{{ myapp_port | default(80) }}"
green_service_port: "{{ myapp_port | default(80) }}"
和角色/green\u服务/defaults/main.yml
:
apache_listen_port: "{{ myapp_port | default(80) }}"
green_service_port: "{{ myapp_port | default(80) }}"
在这种情况下,当Ansible在某个表达式中遇到apache\u listen\u port
时,它会将值模板化为myapp\u port
的值(如果在该特定时刻可用)或使用80
如果您在所需清单中定义了myapp\u端口
,则apache\u监听\u端口
和green\u服务\u端口
将获得其值
如果您无法控制角色:
您可以在playbook中使用以下技巧:
vars:
myapp_port_playbook: "{{ myapp_port | default(80) }}"
apache_listen_port: "{{ myapp_port_playbook }}"
green_service_port: "{{ myapp_port_playbook }}"
在本例中,
apache\u listen\u port
和green\u service\u port
直接模板化为myapp\u port\u playbook
的值,但其值依次为myapp\u port
的值或默认值为80
。谢谢您的回答。在您的“您没有控制权”中,您建议将这些vars
放在任务文件中?不确定“任务文件”是什么意思。。。在剧本或包含的vars_文件中的某个地方。