在循环中使用with_items的Ansible 2条件

时间:2017-03-05 12:20:49

标签: ansible ansible-2.x

我尝试运行一些Ansible命令,具体取决于我的任务中基于布尔值的条件检查的结果,并将自己绑在试图让它工作的结。

所需的结果如下,并且应为hosts数组中的每个项目运行

  • 检查lynchburg变量是true还是false
  • 如果lynchburg变量为true
    • 设置文件夹结构(如果它尚不存在)
    • 从包含的模板文件创建gulpfile.js(如果它尚未存在)
  • 如果lynchburg变量为false
    • 不要设置文件夹结构
    • 不要创建gulpfile.js
  • 无论lynchburgtrue还是false,都要跳过后续重新投放的所有任务,因为文件夹结构和gulpfile.js将会在那里(尽管是否存在)这应该由条件中的逻辑来处理)

从下面的代码中,我看到了以下结果:

  • lynchburgtrue时,该预设会按预期运行 第一次和任何后续的重新配置也起作用 预期。
  • lynchburgfalse时,inc文件夹结构 已创建,但gulpfile.js 不是

任务应该贯穿的主循环如下:

vhosts:
  - site_name: sample
    lynchburg: true

任务如下:

# Create variable to check whether Lynchburg has already been installed
- name: Check if Lynchburg assets folders have been previously created
  stat:
    path: /var/www/{{ item.site_name }}/inc
  with_items: "{{ vhosts }}"
  when: item.lynchburg == true
  register: lynchburg_assets

- name: Check if Lynchburg gulpfile.js has been previously created
  stat:
    path: /var/www/{{ item.site_name }}/gulpfile.js
  with_items: "{{ vhosts }}"
  when: item.lynchburg == true
  register: lynchburg_gulpfile

- name: Create inc folder
  with_items: "{{ lynchburg_assets.results }}"
  file:
    path: /var/www/{{ item.item.site_name }}/inc
    state: directory
  when: item.stat.isdir is undefined and item.item.lynchburg == true

- name: Create scss folder
  with_items: "{{ lynchburg_assets.results }}"
  file:
    path: /var/www/{{ item.item.site_name }}/inc/scss
    state: directory
  when: item.stat.isdir is undefined and item.item.lynchburg == true

- name: Create js folder
  with_items: "{{ lynchburg_assets.results }}"
  file:
    path: /var/www/{{ item.item.site_name }}/inc/js
    state: directory
  when: item.stat.isdir is undefined and item.item.lynchburg == true

- name: Create img folder
  with_items: "{{ lynchburg_assets.results }}"
  file:
    path: /var/www/{{ item.item.site_name }}/inc/img
    state: directory
  when: item.stat.isdir is undefined and item.item.lynchburg == true

- name: Create fonts folder
  with_items: "{{ lynchburg_assets.results }}"
  file:
    path: /var/www/{{ item.item.site_name }}/inc/fonts
    state: directory
  when: item.stat.isdir is undefined and item.item.lynchburg == true

- name: Create gulpfile.js
  with_items: "{{ lynchburg_gulpfile.results }}"
  template:
    src: gulpfile.js
    dest: /var/www/{{ item.item.site_name }}/gulpfile.js
  when: item.stat.exists is defined and item.stat.exists == false and item.item.lynchburg == true

NB 如果还有其他任何方式可以轻松创建完整的文件夹结构而无需运行五个不同的任务 - 每个文件夹/子文件夹一个 - 并且有人可以建议那是什么,那&# 39;也值得赞赏!

3 个答案:

答案 0 :(得分:1)

  

lynchburgfalse时,inc文件夹结构 已创建,但gulpfile.js 不是

我知道如何解决它,我还不知道如何解释它:

更改条件中表达式的顺序:

when: item.item.lynchburg == true and item.stat.isdir is undefined

出于某种原因:

when: dummy.key is undefined and false

when: false and dummy.key is undefined

给出不同的结果。

仅在检查顶级变量(dummy is undefined)时才能正常工作。

答案 1 :(得分:0)

我似乎已经在盲目的实验中解决了这个问题。我已从文件夹结构任务中删除了条件检查,因此它只是检查原始vhosts循环,而不是先循环遍历它们,然后在循环结果上运行任务。

我的任务现在看起来如下,这看起来完全像我希望的那样:

---
- name: Create inc folder
  with_items: "{{ vhosts }}"
  file:
    path: /var/www/{{ item.site_name }}/inc
    state: directory
  when: item.lynchburg == true

- name: Create scss folder
  with_items: "{{ vhosts }}"
  file:
    path: /var/www/{{ item.site_name }}/inc/scss
    state: directory
  when: item.lynchburg == true

- name: Create js folder
  with_items: "{{ vhosts }}"
  file:
    path: /var/www/{{ item.site_name }}/inc/js
    state: directory
  when: item.lynchburg == true

- name: Create img folder
  with_items: "{{ vhosts }}"
  file:
    path: /var/www/{{ item.site_name }}/inc/img
    state: directory
  when: item.lynchburg == true

- name: Create fonts folder
  with_items: "{{ vhosts }}"
  file:
    path: /var/www/{{ item.site_name }}/inc/fonts
    state: directory
  when: item.lynchburg == true

- name: Check if Lynchburg gulpfile.js has been previously created
  stat:
    path: /var/www/{{ item.site_name }}/gulpfile.js
  with_items: "{{ vhosts }}"
  when: item.lynchburg == true
  register: lynchburg_gulpfile

- name: Create gulpfile.js
  with_items: "{{ lynchburg_gulpfile.results }}"
  template:
    src: gulpfile.js
    dest: /var/www/{{ item.item.site_name }}/gulpfile.js
  when: item.stat.exists is defined and item.stat.exists == false and item.item.lynchburg == true 

我会留给社区告诉我这是否正确,但正如我所说,它似乎完美无缺。

答案 2 :(得分:0)

我可能会遗漏某些内容,但看起来对我来说就像stat任务一样,并且不需要进行条件检查:

  • 对于文件夹结构,第一次运行任务时,将创建目录。但是如果它在同一主机上再次运行,那么任务将被跳过,你将获得如下输出:

    localhost                  : ok=3    changed=0    unreachable=0    failed=0
    
  • 如果是template任务,您可以将its force option设置为false,这意味着如果该文件已存在,任务将无法运行。

最后,您可以使用the with_nested style of loop (Ansible < 2.5)a lookup (Ansible ≥ 2.5)在一项任务中轻松创建文件夹结构。

我会重新创建你的剧本看起来像这样(注意它会在自己的目录中创建文件结构):

---
- hosts: localhost

  vars:
    vhosts:
      - site_name: sample
        lynchburg: true
      - site_name: sample2
        lynchburg: false

  tasks:
    - name: Create required folder structure.
      file:
        path: "{{ playbook_dir }}/var/www/{{ item.0.site_name }}/inc/{{ item.1 }}"
        state: directory
      with_nested:
        - "{{ vhosts }}"
        - ["scss", "img", "js", "fonts"]
      when: item.0.lynchburg

    - name: Template gulpfile into place.
      template:
        src: "{{ playbook_dir }}/gulpfile.js.j2"
        dest: "{{ playbook_dir }}/var/www/{{ item.site_name }}/gulpfile.js"
        force: false
      with_items: "{{ vhosts }}"
      when: item.lynchburg

运行此第一个时间会创建以下结果和文件夹结构。请注意:

  • Ansible报告两项已更改的任务

     ____________
    < PLAY RECAP >
     ------------
            \   ^__^
             \  (oo)\_______
                (__)\       )\/\
                    ||----w |
                    ||     ||
    
    localhost                  : ok=3    changed=2    unreachable=0    failed=0
    
  • 仅创建sample主机目录和文件

    var
    └── www
        └── sample
            ├── gulpfile.js
            └── inc
                ├── fonts
                ├── img
                ├── js
                └── scss
    

如果我们再次运行ansible-playbook playbook.yml

  • 文件夹和文件结构未更改,
  • Ansible报告零更改

     ____________
    < PLAY RECAP >
     ------------
            \   ^__^
             \  (oo)\_______
                (__)\       )\/\
                    ||----w |
                    ||     ||
    
    localhost                  : ok=3    changed=0    unreachable=0    failed=0