Question

I'm looking for a way to conditionally include a file in an Ansible play, if the file exists. Using "include" unfortunately throws a fatal error if the file doesn't exist. I'm looping through a bunch of packages and installing them and I want to check for an optional config file for each package. See simplified example below:

---
- name: Basic setup of an Ubuntu box
  hosts: all
  vars:
    packages:
      - ack-grep
      - vim
      - zsh
      - htop
      - openssh-server
      - cowsay
  tasks:
    - name: Run package configuration
      action: apt name=$item
      include: "packages/${item}.yml"
      with_items: $packages

As soon as the script tries to include a file that doesn't exist, it stops with an error. I'm sure I'm just trying to do something in the wrong way, but I've been at this for hours and tried everything I can think of, with no results.

Was it helpful?

Solution

You shouldn't do that as it is described on https://github.com/ansible/ansible/issues/2726 Take a special look at this comment:

Yeah include + with_items is not something folks should use.

We should not have documented it.

While I understand you have that particular structure in your variables now, it's better to use with_items inside the task.

It doesn't work with inventory variables, so this is why you want to put loops in your tasks/roles instead.

It is not even supported on Ansible 1.5. If you try to run it, you will get this error:

ERROR: [DEPRECATED]: include + with_items is a removed deprecated feature. Please update your playbooks. Ansible failed to complete successfully. Any error output should be visible above. Please fix these errors and try again.

The best way to use include other variables and tasks on your playbook is using roles. Take a look at http://docs.ansible.com/playbooks_roles.html#task-include-files-and-encouraging-reuse

OTHER TIPS

I personally use

- include: ...
  when: condition

So you can tune your includes based on if a certain var is true or false or set, etc. These vars can even be set in the in inventory files.

I am using Ansible version 2.9.20

---
- name: Basic setup of an Ubuntu box
  hosts: all
  vars:
    packages:
      - ack-grep
      - vim
      - zsh
      - htop
      - openssh-server
      - cowsay
  tasks:
    - name: check if file exists
      local_action: stat path=packages/{{ item }}.yml
      with_items: "{{ packages }}"
      register: check_file

    - name: Run package configuration
      action: apt name={{ item.item }}
      with_items: "{{ check_file.results }}"
      when: item.stat.exists

Here, I have created 2 tasks in one playbook:

  • Task 1 will check if file exists and will feed the output to check_file variable which will be read in the second task to perform the action.
  • Task 2 will perform the action depending on the file status, i.e., if file exists then it will do the action otherwise not.

'include' is a task, used for including plays, roles or more tasks not data files. Also tasks must execute separately (- blocks). As suggested above you need to use 'vars_files' to include files with variables for use in the play.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top