仅在未指定标签的情况下运行ansible任务

时间:2019-01-29 20:57:50

标签: tags ansible

说我仅在命令行提供的标签列表中特定标签为 NOT 时才运行任务,即使指定了其他标签也是如此。在这些情况下,只有最后一个在所有情况下都可以正常工作:

- hosts: all
  tasks:
    - debug:
        msg: 'not TAG (won't work if other tags specified)'
      tags: not TAG

    - debug:
        msg: 'always, but not if TAG specified (doesn't work; always runs)'
      tags: always,not TAG

    - debug:
        msg: 'ALWAYS, but not if TAG in ansible_run_tags'
      when: "'TAG' not in ansible_run_tags"
      tags: always

尝试使用不同的CLI选项,您将希望看到为什么我觉得有些困惑:

ansible-playbook tags-test.yml -l HOST
ansible-playbook tags-test.yml -l HOST -t TAG
ansible-playbook tags-test.yml -l HOST -t OTHERTAG

问题:(a)这是预期的行为吗? (b)是否有更好的方法或我缺少的逻辑?

令我惊讶的是我不得不深入研究(未记录的AFAICT)变量ansible_run_tags


修正:建议我发布我的实际用例。我正在使用ansible来驱动Debian系列系统上的系统更新。我试图在最后通知是否需要重新启动,除非提供了标签reboot,除非重新启动,否则将导致重新启动(并等待系统重新启动)。这是相关的代码段:

- name: check and perhaps reboot
  block:
  - name: Check if a reboot is required
    stat:
      path: /var/run/reboot-required
      get_md5: no
    register: reboot
    tags: always,reboot

  - name: Alert if a reboot is required
    fail:
      msg: "NOTE: a reboot required to finish uppdates."
    when:
      - ('reboot' not in ansible_run_tags)
      - reboot.stat.exists
    tags: always

  - name: Reboot the server
    reboot:
      msg: rebooting after Ansible applied system updates
    when: reboot.stat.exists or ('force-reboot' in ansible_run_tags)
    tags: never,reboot,force-reboot

我认为我最初的问题仍然值得,但是我也愿意接受实现此功能的替代方法。

3 个答案:

答案 0 :(得分:1)

我知道这是一个古老的问题,但我有类似的要求。

这可能是用另一种方法实现的最好的方法……但是……有时它可能是有用的。

我可以通过设置一个事实(如果指定了标签)来实现,然后仅在未设置事实的情况下才输出消息,例如:

---
- name: "test task runs only if tag missing"
  hosts: all
  tasks:
    - name: "suppress message if tag given"
      set_fact: suppress_message=yes
      tags: reboot,never

    - name: "message"
      debug:
        msg: "You didn't say 'reboot'"
      when: suppress_message is not defined

答案 1 :(得分:1)

出于完整性考虑,由于只有@ paul-sweeney提供了任何替代解决方案,因此我将用当前的最佳解决方案回答我自己的问题,并让人们选择/投票赞成他们最喜欢的解决方案:

---
- name: run only if 'TAG' not specified
  debug:
    msg: 'ALWAYS, but not if TAG in ansible_run_tags'
  when: "'TAG' not in ansible_run_tags"
  tags: always

答案 2 :(得分:0)

我认为我们具有控制状态(例如:启动,重新启动,停止),安装状态(存在,不存在)和组件(网络服务器,数据库等)。 Ansible缺乏对这三个维度的良好分离,并且将这三个维度混合在一个标签系统中会导致混乱。

例如,如果您具有“ webserver”和“ DB”标签,则要使用“ restart”标签“重新启动”数据库而不是“ webserver”。 但是,如果数据库和Web服务器的“重新启动”任务位于具有相同“重新启动”标签的相同任务文件中,则不会起作用,因为“重新启动”标签将同时启动数据库和Web服务器...

因此,您可能必须将Web服务器和数据库任务划分为2个单独的文件,并在包含级别使用标记。

使用标签意味着您拥有选项树,而不是选项矩阵。

我喜欢标记的概念,但是无法在条件表达式中使用它的事实使得标记的吸引力降低了。

我建议在角色中声明标签,但将其映射为变量作为第一个任务。因此,“ restart”和“ db”标记将成为我角色中的布尔变量,并在以下情况下使用:而不是标记: