Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ansible/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ansible:定义剧本;“违约”;在角色上具有优先权但在资源清册中可重写的变量 TL;博士_Ansible_Ansible 2.x_Ansible Inventory - Fatal编程技术网

Ansible:定义剧本;“违约”;在角色上具有优先权但在资源清册中可重写的变量 TL;博士

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,我试图在playbook级别定义某种默认变量—我们称之为playbook默认值—它优先于其他角色默认值,但可以被库存库存组_vars/all变量覆盖

如何定义某种playbook默认值变量,该变量优先于其他角色默认值,但可被库存(环境)覆盖


当前Ansible 2.x变量优先级如下:

  • 角色默认值
  • 清单文件或脚本组变量
  • 库存组\变量/全部
  • 剧本组\u vars/all
我希望实现的目标是:

  • 角色默认值
  • 剧本默认设置
  • 清单文件或脚本组变量
  • 库存组\u变量/全部
  • 剧本组\u vars/all
从我以前使用的大多数工具和应用程序来看,在环境级别定义的变量(dev、test、QA、prod等)优先于其他“应用程序”变量,而这些变量本身优先于其他“外部”组件。另一个优先顺序是:

  • “外部”组件变量(来自Galaxy的角色)
  • “应用程序”变量(剧本变量)
  • “环境”变量(开发、测试等)
环境优先。但我找不到用Ansible复制这种模式的方法。在Chef和Puppet中,这样的事情很容易(外部cookbooks默认值被包装器cookbook默认值覆盖),但我找不到一种方法来实现Ansible的相同功能

一个简单应用程序的示例

让我们考虑一个由几个与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_文件中的某个地方。