ansible:使用带有通知处理程序的with_items

时间:2014-09-05 21:30:32

标签: ansible

我想将变量传递给通知处理程序,但无法在SO,文档或github存储库中的问题中找到它的任何位置,如何做到这一点。我正在做的是部署多个Web应用程序,当其中一个Web应用程序的代码发生更改时,它应该重新启动该Web应用程序的服务。

this SO question,我得到了这个,有点:

- hosts: localhost
  tasks:
  - name: "task 1"
    shell: "echo {{ item }}"
    register: "task_1_output"
    with_items: [a,b]
  - name: "task 2"
    debug:
      msg: "{{ item.item }}"
    when: item.changed
    with_items: task_1_output.results

(将其放入test.yml并使用ansible-playbook test.yml -c local运行。)

但是这会记录第一个任务的结果,并在第二个任务中有条件地循环。我的问题是当你有两个或更多需要通知第二个任务的任务时它会变得混乱!例如,如果代码已更新或配置已更改,请重新启动Web服务。

AFAICT,无法将变量传递给处理程序。那会干净利落地为我解决。我在github上发现了一些问题,其他人遇到了同样的问题,并提出了一些语法,但实际上都没有。

包含子剧本也不会有效,因为不推荐将with_itemsinclude一起使用。

在我的Playbooks中,我有site.yml列出了一个组的角色,然后在该组的group_vars中我定义了应该安装的webapps列表(包括版本)。这似乎对我来说是正确的,因为这样我可以使用相同的剧本进行分期和制作。但也许唯一的解决方案是多次定义角色,并复制分段和生产的角色列表。

那么这里的智慧是什么?

4 个答案:

答案 0 :(得分:16)

Ansible中的变量是全局的,因此没有理由将变量传递给处理程序。如果您试图以一种试图在处理程序名称中使用变量的方式对参数进行参数化,那么您将无法在Ansible中执行该操作。

你可以做的是创建一个足够容易地循环遍历服务列表的处理程序,这是一个可以在本地测试的工作示例:

- hosts: localhost
  tasks:
  - file:  >
      path=/tmp/{{ item }}
      state=directory
    register: files_created
    with_items:
      - one
      - two
    notify: some_handler

  handlers:
    - name: "some_handler"
      shell: "echo {{ item }} has changed!"
      when: item.changed
      with_items: files_created.results

答案 1 :(得分:5)

我终于通过将应用程序拆分到同一角色的多个实例上来解决它。这样,角色中的处理程序可以引用定义为角色变量的变量。

在site.yml:

- hosts: localhost
  roles:
  - role: something
    name: a
  - role: something
    name: b

在角色/ something / tasks / main.yml中:

- name: do something
  shell: "echo {{ name }}"
  notify: something happened

- name: do something else
  shell: "echo {{ name }}"
  notify: something happened

在roles / something / handlers / main.yml中:

- name: something happened
  debug:
    msg: "{{ name }}"

似乎比第一个解决方案少得多的hackish!

答案 2 :(得分:1)

要更新上述jarv的答案,Ansible 2.5将with_items替换为loop。获得结果时,item本身将不起作用。您需要明确获得名称,例如item.name

- hosts: localhost
  tasks:
  - file:  >
      path=/tmp/{{ item }}
      state=directory
    register: files_created
    loop:
      - one
      - two
    notify: some_handler

  handlers:
    - name: "some_handler"
      shell: "echo {{ item.name }} has changed!"
      when: item.changed
      loop: files_created.results

答案 3 :(得分:0)

我有这样的工作-我必须加一些大括号

tasks:
    - name: Aktivieren von Security-, Backport- und Non-Security-Upgrades
      lineinfile:
        path: /etc/apt/apt.conf.d/50unattended-upgrades
        regexp: '^[^"//"]*"\${distro_id}:\${distro_codename}-{{ item }}";'
        line: '        "${distro_id}:${distro_codename}-{{ item }}";'
        insertafter: "Unattended-Upgrade::Allowed-Origins {"
        state: present
      register: aenderung
      loop:
        - updates
        - security
        - backports
      notify: Auskommentierte Zeilen entfernen

    handlers:
        - name: Auskommentierte Zeilen entfernen
          lineinfile:
            path: /etc/apt/apt.conf.d/50unattended-upgrades
            regexp: '^\/\/.*{{ item.item }}";.*'
            state: absent
          when: item.changed
          loop: "{{ aenderung.results }}"