<p>Different approaches can be useful for different setups. You can use <em>tags</em> in some cases, or <em>conditional includes</em> (as you describe) in other cases.</p>

<blockquote>
  <p>On the other hand, it generates quite a payload of “skipped” tasks in ansible logs, which raises a red sign to me.</p>
</blockquote>

<p>You should get familiar with <a href="https://serverfault.com/questions/875247/whats-the-difference-between-include-tasks-and-import-tasks">difference between static and dynamic includes</a> in Ansible.</p>

<p>So if you use static includes, you will get a lot of skipped tasks, because every task in every file is added to execution queue but most of them are skipped because of <code>when</code> statement.</p>

<p><code>tasks/main.yml</code> of your role with actions <code>install</code>/<code>uninstall</code>:</p>

<pre><code>- include: install.yml
  when: action == 'install'
- include: uninstall.yml
  when: action == 'uninstall'
</code></pre>

<p>But if you use dynamic includes, only required tasks are added to execution queue and <code>skipped</code> message is displayed for skipped includes.</p>

<p><code>tasks/main.yml</code>:</p>

<pre><code>- include_tasks: install.yml
  when: action == 'install'
- include_tasks: uninstall.yml
  when: action == 'uninstall'
</code></pre>

<p>More on that, you can avoid <code>skipped</code> message altogether like this:</p>

<p><code>tasks/main.yml</code>:</p>

<pre><code>- include_tasks: '{{ action }}.yml'
</code></pre>

<p>The drawback of dynamic includes is that you can't do complete static analysis of your playbook (like syntax checks, etc.) because many things are know only in runtime.</p>

CC BY-SA 3.0
2018-03-01T15:45:39.180Z
2018-03-01T15:45:39.180Z
Konstantin Suvorov
<p>My understanding of Ansible roles is that they are the unit of reusability when implementing processes using Ansible, similarly to what a class or a package is in some computer languages.</p>

<p>It therefore seems natural to use roles to make all tasks understanding a given data structure in a specific role, but this yields the question of how to select the actual tasks to perform?  Is it a good design to use the <code>main.yml</code> file in the task as an entrypoint to select actual tasks according to role parameters?</p>

<p>For instance a <code>framework</code> role could feature:</p>

<ul>
<li><p>a <code>defaults/main.yml</code> file that understands the <code>framework</code> variable that could be define by a vars file shared by all playbooks in a project like</p>

<p>framework:
  java: [tomcat, mysql]
  php: yes</p></li>
</ul>

<p>so that after processing the <code>defaults/main.yml</code> file the following variables:</p>

<pre><code>framework__enable_java_core: yes
framework__enable_java_tomcat: yes
framework__enable_java_mysql: yes
framework__enable_php_core: yes
</code></pre>

<p>are defined and can be used by the role to actually know which tasks to perform.</p>

<ul>
<li><p>several tasks like <code>java.yml</code>, <code>php.yml</code> pro framework, which select actions to perform according to a <code>when: action == 'WHATEVER-ACTION</code> is to perform; the <code>main.yml</code> then leek all the corresponding tasks.</p></li>
<li><p>playbooks that say</p></li>
</ul>

<p>for instance</p>

<pre><code>roles:
- { role: framework, action: apt-setup }
</code></pre>

<p>or</p>

<pre><code>roles:
- { role: framework, action: install }
</code></pre>

<p>or</p>

<pre><code>roles:
- { role: framework, action: uninstall }
</code></pre>

<p>This kind of approaches turns out to <a href="https://github.com/michipili/bsdowl" rel="nofollow noreferrer">scale very well when working with Makefiles</a>.  It is therefore tempting to use it again when writing complex ansible systems.  On the one hand, it seems to fit quite naturally in the language used by ansible. On the other hand, it generates quite a payload of “skipped” tasks in ansible logs, which raises a red sign to me.</p>

<p>Is the approach I describe a sensible way to group data structures with the processes using it? (That is, to implement reutilisation!)  If not, what would be a better way?</p>

<ansible><architecture>
In ansible how to select specific tasks in a role according to the playbook or a more general parameter?
Michaël Le Barbier
# In ansible how to select specific tasks in a role according to the playbook or a more general parameter?

(Asked by: username_0 on 2018-03-01)

My understanding of Ansible roles is that they are the unit of reusability when implementing processes using Ansible, similarly to what a class or a package is in some computer languages.
It therefore seems natural to use roles to make all tasks understanding a given data structure in a specific role, but this yields the question of how to select the actual tasks to perform?  Is it a good design to use the main.yml file in the task as an entrypoint to select actual tasks according to role parameters?
For instance a framework role could feature:

a defaults/main.yml file that understands the framework variable that could be define by a vars file shared by all playbooks in a project like
framework:
  java: [tomcat, mysql]
  php: yes

so that after processing the defaults/main.yml file the following variables:
framework__enable_java_core: yes
framework__enable_java_tomcat: yes
framework__enable_java_mysql: yes
framework__enable_php_core: yes

are defined and can be used by the role to actually know which tasks to perform.

several tasks like java.yml, php.yml pro framework, which select actions to perform according to a when: action == 'WHATEVER-ACTION is to perform; the main.yml then leek all the corresponding tasks.
playbooks that say

for instance
roles:
- { role: framework, action: apt-setup }

or
roles:
- { role: framework, action: install }

or
roles:
- { role: framework, action: uninstall }

This kind of approaches turns out to scale very well when working with Makefiles.  It is therefore tempting to use it again when writing complex ansible systems.  On the one hand, it seems to fit quite naturally in the language used by ansible. On the other hand, it generates quite a payload of “skipped” tasks in ansible logs, which raises a red sign to me.
Is the approach I describe a sensible way to group data structures with the processes using it? (That is, to implement reutilisation!)  If not, what would be a better way?

**Tags:** ansible, architecture


---

## 1 answers

### Answer by username_1 on 2018-03-01. Score: 8 | Accepted answer

Different approaches can be useful for different setups. You can use tags in some cases, or conditional includes (as you describe) in other cases.

On the other hand, it generates quite a payload of “skipped” tasks in ansible logs, which raises a red sign to me.

You should get familiar with difference between static and dynamic includes in Ansible.
So if you use static includes, you will get a lot of skipped tasks, because every task in every file is added to execution queue but most of them are skipped because of when statement.
tasks/main.yml of your role with actions install/uninstall:
- include: install.yml
  when: action == 'install'
- include: uninstall.yml
  when: action == 'uninstall'

But if you use dynamic includes, only required tasks are added to execution queue and skipped message is displayed for skipped includes.
tasks/main.yml:
- include_tasks: install.yml
  when: action == 'install'
- include_tasks: uninstall.yml
  when: action == 'uninstall'

More on that, you can avoid skipped message altogether like this:
tasks/main.yml:
- include_tasks: '{{ action }}.yml'

The drawback of dynamic includes is that you can't do complete static analysis of your playbook (like syntax checks, etc.) because many things are know only in runtime.


---

