# Ansible Patterns

**URL:** <https://forum.ansible.com/t/ansible-patterns/15908>\
**Category:** Ansible Project\
**Created:** [August 11, 2014, 9:02am UTC](https://forum.ansible.com/t/ansible-patterns/15908 "2014-08-11T09:02:22Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rob\_Zissou](https://avatars.discourse-cdn.com/v4/letter/r/0ea827/32.png) [@Rob\_Zissou](https://forum.ansible.com/u/Rob_Zissou)\
**Post date:** [August 11, 2014, 9:02am UTC](https://forum.ansible.com/t/ansible-patterns/15908/1 "2014-08-11T09:02:22Z")

</div>

Hi All,

I’ve been trying to work out the best layout for our playbooks and roles. I’ve been attempting to conform to DRY principles but trying to leave things as loosely coupled as possible.

Our infrastructure involves many similar apps that have minor differences which is why I’ve been looking specifically at how it might be possible to parameterise playbooks/roles to avoid many very similar files.

Initially I had something like this:

## apps described in ‘meta roles’ (roles with only meta/main.yml that include other roles)

# app1.yml

roles:

- app1

# app2.yml

roles:

- app2

# roles/app1/meta/main.yml

dependencies:

- { role: pre\_deploy\_common\_stuff }

- { role: deploy\_app\_1 }

- { role: deploy\_other\_stuff }

- { role: post\_deploy\_common\_stuff }

# roles/app2/meta/main.yml

dependencies:

- { role: pre\_deploy\_common\_stuff }

- { role: deploy\_app\_2 }

- { role: post\_deploy\_common\_stuff }

## —

Then I tried moving the contents of ‘meta/main.yml’ for each app into playbooks like this:

## apps described in playbooks

# app1.yml

- roles:

- { role: pre\_deploy\_common\_stuff }

- { role: deploy\_app\_1 }

- { role: deploy\_other\_stuff }

- { role: post\_deploy\_common\_stuff }

# app2.yml

- roles:

- { role: pre\_deploy\_common\_stuff }

- { role: deploy\_app\_2 }

- { role: post\_deploy\_common\_stuff }

## —

Then thinking in DRY terms, I tried this:

## templated playbook with parameterization

# app1.yml

- vars:  
my\_roles:
- { role: deploy\_app\_1 }
- { role: deploy\_other\_stuff }

include: foo.yml my\_roles=“{{ my\_roles }}”

# app2.yml

- vars:  
my\_roles:
- { role: deploy\_app\_2 }

include: foo.yml my\_roles=“{{ my\_roles }}”

# foo.yml

- roles:
- { role: pre\_deploy\_common\_stuff }

# this won’t work because ‘roles’ expects a list but gets string ‘my\_roles’

- roles: “{{ my\_roles }}”

# neither will this because with\_items doesn’t work in playbooks

- roles: “{{ item }}”  
with\_items: my\_roles # or “{{ my\_roles }}”

# ‘role’ is equivalent to including various main.yml files manually.

# we still can’t use with\_items or pass a list as a single argument to include so

# using include: in place of role: wouldn’t work either

- roles:
- { role: post\_deploy\_common\_stuff }

# a possibility would be to test with\_items in a meta/main.yml file but

# at that point we’re moving back towards ‘meta role’ territory..!

## –

The last example doesn’t work for reasons described in the comments. I had a quick and nasty go at getting ansible ‘roles:’ to allow lists or with\_items but to no avail.

I think the last pattern may work in a ‘meta’ style role (rather than playbook) but I’m hesitant to introduce this concept of meta-roles when it seems like that information should be stored in playbooks.

I’d be interested to hear how other people approach this type of configuration or whether I’ve made any mistakes in my understanding of how to write playbooks/roles.

Thanks!

Rob

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [August 11, 2014, 6:10pm UTC](https://forum.ansible.com/t/ansible-patterns/15908/2 "2014-08-11T18:10:40Z")

</div>

For those who have not seen this yet, I’d recommend reading:

[http://docs.ansible.com/playbooks\_best\_practices.html](http://docs.ansible.com/playbooks_best_practices.html)

Other discussion of course welcome.

I can’t answer “doesn’t work” comments because I don’t know what “doesn’t work” means.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [August 11, 2014, 6:11pm UTC](https://forum.ansible.com/t/ansible-patterns/15908/3 "2014-08-11T18:11:33Z")

</div>

"

# neither will this because with\_items doesn’t work in playbooks

- roles: “{{ item }}”  
with\_items: my\_roles # or “{{ my\_roles }}”"

This is not a valid syntax, and the docs doesn’t mention this.

Ultimately, I think this would be easiest if we seperate the “best practices for organization” questions with the “I have questions about syntax” questions. Let’s address the syntax questions first.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [August 11, 2014, 6:12pm UTC](https://forum.ansible.com/t/ansible-patterns/15908/4 "2014-08-11T18:12:14Z")

</div>

"

# app1.yml

- vars:  
my\_roles:
- { role: deploy\_app\_1 }
- { role: deploy\_other\_stuff }

include: foo.yml my\_roles=“{{ my\_roles }}”  
"

You also can’t stick an “include” and “vars” together in the same item.

---

<div class="post-metadata">

**Author:** ![Rob\_Zissou](https://avatars.discourse-cdn.com/v4/letter/r/0ea827/32.png) [@Rob\_Zissou](https://forum.ansible.com/u/Rob_Zissou)\
**Post date:** [August 11, 2014, 8:04pm UTC](https://forum.ansible.com/t/ansible-patterns/15908/5 "2014-08-11T20:04:31Z")

</div>

Hi,

Apologies for not being clearer. The third example I posted as an example of a potentially nicer way of structuring playbooks/roles if Ansible had the ability to function in that way, i.e: by ‘roles:’ supporting lists or with\_items.

> You also can’t stick an “include” and “vars” together in the same item.

My mistake.

Thanks,

Rob

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [August 11, 2014, 8:52pm UTC](https://forum.ansible.com/t/ansible-patterns/15908/6 "2014-08-11T20:52:12Z")

</div>

Yeah, roles are not going to support with\_items, it’s basically not possible.

The solution is to pass the variable into the role and loop internally.

The problem is most people try to pass in inventory variables, and that will _NOT_ work, as the number of tasks generated by the system must be equivalent, and it’s not possible to upconvert loops into nested loops.
