我正在寻求有关从一个剧本部署具有相同角色的应用程序的多个版本(不同变量)的问题的帮助。
我们有一个具有多个产品系列的应用程序,这些产品系列是不同的代码版本。每个版本都有单独的uWSGI vassal配置和Nginx virtualhost配置(/ api / v2,/ api / v3,...)。
理想的状态是运行剧本并为服务器配置所有指定的版本。
可悲的是,ansible的import_role/import_tasks
无法与with_items
一起使用,因此必须使用include_role/include_tasks
(可怜,因为它们不遵守角色标签)。
include_role
方法不是最大的问题,但是我们使用处理程序来通知 uWSGI touch重新加载-代码更改,链接更改,virtualenv更改,app_config更改。 ..)。
但是使用循环(with_items
)时,从循环传递的变量无法正确传播到 handlers 。
我尝试了这种情况
问题:处理程序仅在循环的第一次迭代中运行。
#!/usr/bin/env ansible-playbook
# HAndler is run only once, from first notifier
- hosts: localhost
gather_facts: no
vars:
app_root: "/tmp/test_ansible"
app_versions:
- app_product_family: 1
app_release: "v1.0.2"
- app_product_family: 3
app_release: "v4.0.7"
tasks:
- name: Deploy multiple versions of app
include_role:
name: app
with_items: "{{ app_versions }}"
loop_control:
loop_var: app_version
vars:
app_product_family: "{{ app_version.app_product_family }}"
app_release: "{{ app_version.app_release }}"
tags:
- app
- app_debug
问题:处理程序以“默认值”中的默认值运行
#!/usr/bin/env ansible-playbook
- hosts: localhost
gather_facts: no
roles:
- app_v2
vars:
app_v2_root: "/tmp/test_ansible_v2"
app_v2_versions:
- app_v2_product_family: 1
app_v2_release: "v1.0.2"
- app_v2_product_family: 3
app_v2_release: "v4.0.7"
任务roles/app_v2/main.yml
---
# Workaround because import_tasks can't be run with_items
- include_tasks: deploy.yml
when: app_v2_versions
with_items: "{{ app_v2_versions }}"
loop_control:
loop_var: app_v2
vars:
app_v2_product_family: "{{ app_v2.app_v2_product_family }}"
app_v2_release: "{{ app_v2.app_v2_release }}"
tags:
- app_v2
- app_v2_deploy
...
一个想法是为每个产品系列编写一个单独的角色,但是它们共享 nginx 和 uWSGI ,因此将有很多复制粘贴和共享任务(因此标记无法正常工作。)
现在,我用shell脚本包装程序解决了它,但这不是理想的解决方案,在Ansible塔中也无法使用。
带有任务重现问题的示例回购(已通过ansible 2.4、2.5、2.6测试) https://github.com/mmitucha/ansible_with_items_handlers
非常欢迎任何想法和建议。
答案 0 :(得分:0)
Ansible中的include打破了变量的替代顺序。 F.e.甚至默认角色中的set_fact
也将被角色默认设置遮盖。
查看此错误:https://github.com/ansible/ansible/issues/22025
它已关闭,但未固定。我的建议:认真使用include和变量。
在实践中,我从不使用带有循环的角色包含。如果需要循环,请在此循环中包含一个任务列表(该任务列表又可以import_role
)。
答案 1 :(得分:0)
好吧,这是@George Shuklin发布的错误。
我将使用我的外壳包装程序,该包装程序读取group_vars yaml,然后根据变量列表的长度多次运行剧本。
可悲的是,过去几周我在ansible中遇到了多个烦人的bug,有点失去了对它的信任):
可能每个人都在使用微服务和kubernetes,因此需要加快我们的迁移(: