Handling roles across multiple distributions

Hey all,

I’d like to start by saying that Ansible is an awesome piece of software and I’m really enjoying it, especially after having spent the last several years in chef/puppet land. :slight_smile:

Now then, I’m trying to setup an Ansible configuration that looks something like the following layout (pseudo-code):
https://gist.github.com/SegFaultAX/81f07ea0428728ce6e62

Essentially I have different top level roles (web, app, db, etc.) described in the inventory, each with a set of Ansible roles:

web:

  • common
  • nginx

  • app:
  • common
  • jre

Unfortunately my environment uses two completely incompatible operating systems (centos and ubuntu) which will require their own plays to provision and deploy. It would be great if the main.yml for each role just included the appropriate file for the distribution for the host, eg:

roles/common/tasks/main.yml

  • hosts: CentOS
    include: centos.yml
  • hosts: Ubuntu
    include: ubuntu.yml

roles/common/tasks/ubuntu.yml

  • name: install a foo, ubuntu style
  • name: configure a bar, ubuntu style

roles/common/tasks/centos.yml

  • name: install a foo, centos style
  • name: configure a bar, centos style

As far as I can tell, the above syntax (and the syntax linked in the gist) is completely invalid, but that’s my idealized solution. One option I was considering was something like this:

roles/common/tasks/main.yml

  • include: centos.yml
  • include: ubuntu.yml

roles/common/tasks/ubuntu.yml

  • name: install a foo, ubuntu style
    when: ansible_distribution == ‘Ubuntu’
  • name: configure a bar, ubuntu style
    when: ansible_distribution == ‘Ubuntu’

roles/common/tasks/centos.yml

  • name: install a foo, centos style
    when: ansible_distribution == ‘CentOS’

  • name: configure a bar, centos style
    when: ansible_distribution == ‘CentOS’

But the repeated when clauses create a lot of unnecessary duplication.

Anyway, what’s the idiomatic way to structure my configuration?

Cheers,
Michael-Keith

Try this in roles/acme/main.yml:

  • include: centos.yml

when: ansible_distribution == ‘CentOS’

  • include: ubuntu.yml

when: ansible_distribution == ‘Ubuntu’

This will apply the “when” statement automatically to everything within the file.

Both those two includes can live in roles/acme/centos.yml and roles/acme/ubuntu.yml

Awesome, thanks Michael! I wasn’t clear if the condition would be properly scoped for an include, but it seems I missed the last paragraph of conditional execution in the documentation that gives an example of the above syntax. Hooray for Ansible!

http://www.ansibleworks.com/docs/playbooks2.html#conditional-execution

Cheers,
Michael-Keith

Michael,

Will this still tell me that it's skipping all the tasks for the
conditional that's not met? Or do we still have to group_by in order
to suppress those messages?

- James

Yep,

This adds the conditional to each task and that will tell you for what hosts those tasks run and which they do not.

If you use group_by to create a dynamic host group instead you won’t see any task headers if the group size is zero, and won’t see any skipped messages.

–Michael