I have a working task to migrate (copy) a specific part of my homedir (second to last line is the important one):

- name: "Migrate my-pc module home files"
    src: "{{ migration_source_path }}{{ item }}"
    dest: "{{ migration_destination_path }}{{ item }}"
  loop: "{{ migration_paths_my_pc }}"
    - not is_migrating_all
    - "'{{ migration_source_path }}{{ item }}' is exists"
    - m_my_pc | bool

Both of the ..._path variables always end with a forward slash (/).

Explanation: It takes a list of file paths from migration_paths_my_pc and copies them from migration_source_path to migration_destination_path). This will only happen if: the flag for that module has been set (m_my_pc); and the path exists at source; and I'm not already migrating all files from homedir anyway (is_migrating_all).

My current working solution (above) gives me the warning:

[WARNING]: conditional statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: '{{ migration_source_path }}{{ item }}' is exists

I understand that I am supposed to remove the curly braces {{ from when: section because conditionals have implied curly braces around them anyway. The problem is I cannot figure out how to get it to work. Some of the many unsuccessful attempts are:

    - vars["" + migrate_source_path + item] is exists
    - vars[migrate_source_path + item] is exists
    - vars[migrate_source_path ~ item] is exists
    - vars[migrate_source_path]vars[item] is exists
    - '' + migrate_source_path + item is exists
    - lookup('/home/k/test/test2/' + item) is exists
    - "{{ lookup('vars', 'migrate_source_path' + 'item') is exists }}"
    - "{{ lookup('vars', 'migrate_source_path') + lookup('vars', 'item') is exists }}"
    - lookup('vars', 'migrate_source_path')lookup('vars', 'item') is exists


I am automating personal PC setups for practical reasons as well as to learn more about Ansible and Ansible-playbooks.

Any other recommendations or advice welcome (in the comments, I guess) as well.


My design goals (functional aspirations) for the migration are:

  • I want to keep the maintenance cost low, but I would like to have the information which paths were copied and which were skipped if I need it. So I thought the script should copy the paths that exist at source without halting or throwing an error in case of a path missing a source. Warnings or other plain messages would be great. My current script does this acceptably.
  • It would be nice to be able to easily toggle which paths get a copy attempt and which don't (e.g. something might change in relevance to a migration). Doing this in project/vars/ seemed intuitive and therefore maybe a better design than toggling them inside the task. Other variables that are more likely to get commented out or changed are at project/vars/ as well. Commenting something out or uncommenting something is a single hotkey in most text editors and IDE-s. So quite convenient.

2 Answers 2


Your attempts are over-complicated. Jinja delimiters should not be used in conditions because you are already in something that is interpreted as a Jinja expression, so they just need to be replaced with something that provides the desired result.

In this case you are creating a string that is the concatenation of two variables, so you should replace it with concatenation:

    - (migration_source_path ~ item) is exists

You used both migrate_source_path and migration_source_path in your examples, so I have arbitrarily chosen migration_source_path as the correct one.

You were kind of close with:

    - '' + migration_source_path + item is exists

but you have an unnecessary leading empty string which the YAML parser won't like, and once you corrected that by quoting it correctly or removing the unnecessary string:

    - "'' + migration_source_path + item is exists"
    - migration_source_path + item is exists

it would try to add migration_source_path and item is exists, since you didn't force the correct order with parentheses.


Try to rewrite it a little bit different. Instead of looping through an array with loop, specify the directories you wanna copy in a with or with_fileglob. If you really wanna have a list of files which you wanna copy from one destination to another, you can write the list in the with part. The module will test if the source file exists and display an error, which in that case is something good, since otherwise your migration would be flawed.

Remember that we use when to tell Ansible when to run or not some task, not to control the task itself or its behavior. To accomplish that, we use handlers, registers, and other resources.

Best regards.

  • I added clarifications on my functional aspirations with the script.
    – Carolus
    Jan 23, 2020 at 10:40
  • So what do you think would be the proper way to address this if it is not broken but part of the design that migration prints a message or continues silently if a source file doesn't exist? I want to give it a default list, and what exist gets copied and what doesn't, gets ignored. To reduce maintenance and configuration costs.
    – Carolus
    Feb 15, 2020 at 11:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .