Search code examples
ansibleinfrastructure-as-code

Ansible - can I condense multiple tasks into one using dual loops and the correct data structure


I have the following data and conditions:

1. file_1 when condition_1
2. file_2 when condition_2
3. file_3 when condition_3
4. file_4 when condition_4

Each of conditions1-4 are made up of two sub-conditions. Condition_1 = (condition_a and condition_b) and so on. I'm thinking, though, that I can 'pre-compound' conditions_a and so on such that all I have to deal with are 1-4.

when:
  - condition_a [an ansible fact]
  - condition_b [another ansible fact]

I'm currently using four tasks for 1., 2., 3., 4. like this:

  - name: task 1
    copy:
      src: file_x
      dest: /some/place
    when:
      - condition_x

There must be a way to construct this using loops if I assemble the files/conditions into an appropriate data structure. Two lists, two loops? Some sort of dictionary structure. The 'items' would seem to be part of the 'file' and 'when' fields and I'm not quite sure how to deal with this. Should I be using the zip filter?

As you can see, my thinking is jumbled with a few concepts (it's still early Ansible days for me) and I'd like some help calrifying this all. Any suggestions would be most appreciated.


Solution

  • If I understand your question correctly, you can iterate over a list of dicts - something like this should do the trick:

    - set_fact:
        files_and_conditions:
          - src: file_x
            dest: dest_x
            condition: "{{ condition_x }}"
          - src: file_y
            dest: dest_y
            condition: "{{ condition_y }}"
    
    - name: task 1
      copy:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
      when: item.condition
      loop: "{{ files_and_conditions }}"
        
    

    Note that the condition should be evaluated as a boolean so you have to put the whole condition between the curly braces - see the linked question for details.