Search code examples
ansiblersync

Split parameter and use it as multiple arguments


I'm trying to create a reusable role that does a synchronize where I pass in the src, dest and an exclude parameters.

I'd like to split that exclude parameter into multiple --exclude= parameters if it's defined.

So, effectively what would be running is:

With exclude undefined:

- name: Copy extracted files to remote
  synchronize:
    src: "{{ src }}"
    dest: "{{ dest }}"
    rsync_opts:
      - "--no-motd"

With exclude=logs,conf:

- name: Copy extracted files to remote
  synchronize:
    src: "{{ src }}"
    dest: "{{ dest }}"
    rsync_opts:
      - "--no-motd"
      - "--exclude=logs"
      - "--exclude=conf"

I figure I need to split the variable, but I'm not sure how to add the --exclude= to each one, whilst not adding any if there's nothing passed.


Solution

  • Given that you are passing the exclude parameter to your role via:

    roles:
      - role: demo_role
        src: /path/to/src
        dest: /path/to/dest
        exclude:
          - logs
          - conf
    

    Then, in your synchronize task, you could use a product filter, in order to construct the exclusions path along with the --exclude flag:

    rsync_opts: >-
      {{
        ['--no-motd']
        + ['--exclude=']
          | product(exclude | default([]))
          | map('join')
      }}
    

    From there:

    • when exclude is a list:

      exclude:
         - logs
         - conf
      

      rsync_opts will be:

      - --no-motd
      - --exclude=logs
      - --exclude=conf
      
    • when exclude is an empty list:

      exclude: []
      

      rsync_opts will be:

      - --no-motd
      
    • when exclude is undefined:

      - role: demo_role
        src: /path/to/src
        dest: /path/to/dest
      

      rsync_opts will be:

      - --no-motd
      

      thanks to the usage of the default filter