【问题标题】:Ansible iterate over hash with conditionAnsible 使用条件迭代哈希
【发布时间】:2018-02-06 15:57:55
【问题描述】:

我使用 ansible 已经有一段时间了,偶然发现了一个超出我的谷歌搜索技能的问题。我在这个 sn-p 中有一个 vars 结构:

artifacts:

  - name: demo
    version: v1

    templates:
      - source: "/opt/source/file.txt"
        destination: "/opt/destination/file.txt"

我现在想在下一个 sn-p 中迭代这个结构:

- name: "Archive files"
  synchronize:
    src: "{{ item.1.destination }}"
    dest: "/some/backup/dir/"
    archive: yes
  delegate_to: "{{ inventory_hostname }}"
  when: item[1].destination.isfile
  with_subelements:
    - "{{ artifacts }}"
    - templates

它显然是因为错误定义的when条件而失败:

  when: item[1].destination.isfile

我正在寻找最优雅的方式来编写我的剧本,以检查文件系统中是否存在工件模板目标中定义的文件。我最初正在考虑使用 stat 模块并添加一个块,我将在其中迭代同一组子元素,但根据此链接,ansible 目前不支持:https://github.com/ansible/ansible/issues/13262

【问题讨论】:

  • 您不能将看起来有点像 Python 中 os.path 对象的方法的东西附加到字符串上,并期望它在 Jinja2 模板中工作。・读你的代码,很难说出你想要实现什么。
  • 更大的图景是我需要使用固定的变量结构。这些文件应该已经放置在目标服务器上。有一个极端情况,有人为尚未在目标服务器上的文件添加模板条目,我想保护我的剧本免受这种情况的影响。对我来说最大的问题是找到一种方法,要么在一个 with_subelements 语句中编写它,要么在 2 个任务上迭代 with_subelements。一个会检查文件是否存在(stat),另一个会在文件存在时根据设置的条件复制文件第一个任务。

标签: python configuration ansible devops


【解决方案1】:

不,这种when 声明似乎是不可能的。它应该依赖于已有的事实。

所以你要么把它分成两个任务,比如stat + archive...

如果您不关心丢失的文件,或者只需添加--ignore-missing-args,例如:

- name: "Archive files"
  synchronize:
    src: "{{ item.1.destination }}"
    dest: "/some/backup/dir/"
    archive: yes
    rsync_opts: ['--ignore-missing-args']
  delegate_to: "{{ inventory_hostname }}"
  with_subelements:
    - "{{ artifacts }}"
    - templates

请注意,--ignore-missing-args 在 rsync 3.06+ 中可用。

【讨论】:

  • 感谢您的回答。不幸的是,我的 rsync 版本不支持这个功能,所以我不得不坚持将它分成两个任务。我使用stackoverflow.com/questions/30785281/… 中的方法迭代多个任务。我觉得它有些丑陋和不必要的复杂。这是处理这个问题的正确方法还是有一些我不熟悉的更简洁的方法?
【解决方案2】:

根据 Konstantin 的建议,我最终将其分为两个任务:

- include: archive.yml artifact="{{item}}"
  with_subelements:
    - "{{ artifacts }}"
    - templates

archive.yml:

- name: "Check if the file exists"
  stat:
    path: "{{ artifact.1.destination }}"
  register: stat_result

- name: "Archive files"
  synchronize:
    src: "{{ artifact.1.destination }}"
    dest: "/some/backup/dir/"
    archive: yes
  delegate_to: "{{ inventory_hostname }}"
  when: stat_result.stat.exists == True

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    • 2014-12-15
    • 2017-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多