Include only if an item exists

Right now I have yaml that look like:

applications:

  • name: app1
    type: type1

  • name: app2
    type: type2

  • name: app3
    type: type1

With lots of roles that look like this:

  • { role: ‘type1’ }
  • { role: ‘type2’ }
  • { role: ‘type3’ }

And inside these roles on every task I have to do something like this:

  • name: task
    with_items: applications
    when: item.type == type1

The issue is that is has to run every one of these roles and all the tasks within it. It complicates things having to add the when item.type == type1 to every task within the role. I am trying to figure out a way so that these roles are not even included if they do not exist in the list. Something like:

  • { role: ‘app1’, when: applications|exist(‘type’, ‘type1’) }

  • { role: ‘app1’, when: applications.type == type1 }

  • { role:“{{ item.type }}”, data: {{ item }}, with_items: applications, when: item.type == type1 }

If your applications are roles I don’t think you would need to check the type of the application inside the role, because the role would just contain what it would need to do.

I think I’d need to see a more specific example of that arbitrary task to provide a suggestion or to understand more about what you are doing.

I am working on getting everything on github but for a more specific example I have this:

applications:
apps:

  • name: web1
    type: wordpress
    path: /var/www/web1

  • name: web2
    type: symfony
    path: /var/www/web2

  • name: web3
    type: wordpress
    path: /var/www/web3

  • { role: wordpress }

  • { role: symfony }

  • { role: laravel }

  • { role: phpbb }

  • { role: yii }

Inside the roles I still have to do with_items: applications.apps when: item.type == wordpress

If I have dozens of these “applications”, they would all be processed unless I can add something like process wordpress sites, when a wordpress application exists, etc. By being able to skip over all the roles and all the tasks within the role if they are not applicable.

I am open for any ideas, the goal is just to either dynamically include the roles that are in the yaml, or skip over the ones that are not.

“Inside the roles I still have to do with_items: applications.apps when: item.type == wordpress”

You shouldn’t have to, and what you’ve pasted below seems to be overthinking it a bit.

Inside the role you should have just the tasks for wordpress.

I’d need to see your playbooks to understand more of what you’re doing though.

I don’t have a specific playbook for this aspect since I have to figure out how to get the roles included. However this is the current project and playbooks I am working on https://github.com/protobox/protobox#applications-coming-soon

The wordpress role for example does have all the wordpress tasks. However I still have to do when: item.type == wordpress because I am iterating over a list of applications the user wishes to install (some of which may not be wordpress). In theory I would like to avoid running the wordpress role at all if none of the applications listed in the yml are not wordpress.

I included the sample yml that would be used with this below. I hope it makes a little more sense. If it still does not, I will have to get a semi-working example on github to hopefully show you something concrete.

applications:
install: 1
apps:

  • type: wordpress
    install: 1
    path: /srv/www/web/wordpress
    settings:
    user: patrickheeney
  • type: symfony
    install: 1
    path: /srv/www/web/symfony
    settings:
    user: patrickheeney
  • type: repo
    install: 1
    path: /srv/www/web/custom
    options:
    provider: git
    source: ‘git@github.com:protobox/web-install.git’
    revision: ‘master’
    pre_install:

“However I still have to do when: item.type == wordpress because I am iterating over a list of applications the user wishes to install (some of which may not be wordpress).”

Sounds like you shouldn’t carry that list between various roles and just reference it in one place to me.

You may wish to leverage role dependencies, for instance, and put those in a common role, if you don’t want to put the wordpress specifics in the wordpress role. Though I think you should.

It would be best to not assign the wordpress role to the host if you didn’t want wordpress to be installed.

This could be done as follows:

roles:

  • { role: wordpress, when: ‘wordpress’ in installed_apps }

  • { role: pastebin, when: ‘pastebin’ in installed_apps }

You could also use “group_by” module to create a dynamic group of machines that have the “wants_wordpress” variable set in inventory or something similar.