Ansible-角色在循环中运行时,var不会正确传播到处理程序

时间:2018-09-10 14:53:50

标签: ansible

我正在寻求有关从一个剧本部署具有相同角色的应用程序的多个版本(不同变量)的问题的帮助。

我们有一个具有多个产品系列的应用程序,这些产品系列是不同的代码版本。每个版本都有单独的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

我尝试了这种情况

playbook.yml-剧本内部的with_items循环

问题:处理程序仅在循环的第一次迭代中运行。

#!/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

playbook_v2.yml-角色任务内的with_items循环

问题:处理程序以“默认值”中的默认值运行

#!/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

非常欢迎任何想法和建议。

2 个答案:

答案 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,因此需要加快我们的迁移(: