首页 文章

在检查模式下运行时跳过Ansible任务?

提问于
浏览
42

我正在编写一本Ansible剧本,并且有一项任务在检查模式下总是会失败:

hosts: ...
tasks:
    - set_fact: filename="{{ansible_date_time.iso8601}}"
    - file: state=touch name={{filename}}
    - file: state=link src={{filename}} dest=latest

在检查模式下,将不会创建该文件,因此 link 任务将始终失败 . 有没有办法在检查模式下运行时标记要跳过的任务?就像是:

- file: state=link src={{filename}} dest=latest
  when: not check_mode

6 回答

  • 0

    Ansible 2.1支持 ansible_check_mode magic变量,在检查模式(official docs)中设置为 True . 这意味着您将能够这样做:

    - file:
        state: link
        src: '{{ filename }}'
        dest: latest
      when: not ansible_check_mode
    

    要么

    - file:
        state: link
        src: '{{ filename }}'
        dest: latest
      ignore_errors: '{{ ansible_check_mode }}'
    

    无论你喜欢什么 .

  • 42

    这是一种hacky解决方案:

    hosts: ...
    tasks:
      - command: /bin/true
        register: noop_result
      - set_fact: check_mode={{ noop_result|skipped }}
    
      - set_fact: filename="{{ansible_date_time.iso_8601}}"
      - file: state=touch name={{filename}}
      - file: state=link src={{filename}} dest=latest
        when: not check_mode
    

    在检查模式下,将跳过 command 任务,因此 check_mode 将设置为 true . 不处于检查模式时,任务应始终成功, check_mode 将设置为 false .

  • -1

    unarchive 我遇到了同样的情况:

    如果存档不存在,则 unarchive 在检查模式下失败(均在 unarchive 之前的步骤中完成) . 我通过将 always_run: true 设置为准备步骤来解决此问题,以便它们也以检查模式执行:

    ---
    
    - name: create artifact directory
      file: {{ artifact_dest_dir }} state=directory
      always_run: true
    
    - name: download artifact on the remote host
      get_url:
        url={{ artifact_url }}
        dest={{ artifact_dest_dir }}/{{ artifact_filename }}
        force=yes
      always_run: true
    
    - name: unpack build artifact
      unarchive: src={{ artifact_dest_dir }}/{{ artifact_filename }}
                 dest={{ artifact_dest_dir }}
                 copy=no
    

    它适用于我的情况,但对于时间相关的目录,这可能不是一个好的解决方案 .

  • 2

    虽然已经有accepted answer,但我想提一下augurar提到的解决方案对我不起作用,因为我不断收到以下错误: skipped expects a dictionary

    最终为我工作的是通过使用 -e 标志传递和使用额外变量的一个稍微不那么糟糕的解决方案,如下所示:

    # On the terminal
    ansible-playbook [...] --check -e '{"check_mode":true}'
    
    # In the playbook or role
    when: [...] and not check_mode
    
    # In the proper `group_vars/` file
    check_mode: false
    

    让我知道你们的想法!

  • 11

    你可能只需要为所有任务设置一个 when: filename is defined . 如果没有定义 filename ,则在正常模式下,您不能失败 .

    hosts: ...
    tasks:
        - set_fact: filename="{{ansible_date_time.iso_8601}}"
        - file: state=present name={{filename}}
          when: filename is defined
        - file: state=link src={{filename}} dest=latest
          when: filename is defined
    
  • -1

    其他需要注意的选项是标签或 --step 选项 .

    Tags

    tasks:
        - set_fact: filename="{{ansible_date_time.iso8601}}"
        - file: state=touch name={{filename}}
        - file: state=link src={{filename}} dest=latest
          tags:
            - test
    

    然后要使用的Ansible命令是:

    ansible-playbook example.yml --skip-tags "test" --check

    还有其他示例可以使用Ansible tags documentation中的标记来跳过/指定要运行的任务 .

    Start and Step

    Ansible还使用 --step 选项提供了一个很好的逐步调试模式 .

    运行 ansible-playbook example.yml --step --check 将以交互方式引导您完成游戏手册中的每项任务

    来自Ansible documentation的"Start and Step"部分:

    这将导致ansible停止每个任务,并询问它是否应该执行该任务 . 假设您有一个名为“configure ssh”的任务,playbook run将停止并询问:执行任务:configure ssh(y / n / c):回答“y”将执行任务,回答“n”将跳过任务,并且回答“c”将继续执行所有剩余的任务而不询问 .

相关问题