# Are Roles enough?

**URL:** <https://forum.ansible.com/t/are-roles-enough/15391>\
**Category:** Ansible Project\
**Created:** [June 3, 2014, 4:38am UTC](https://forum.ansible.com/t/are-roles-enough/15391 "2014-06-03T04:38:45Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![David\_Carmean](https://avatars.discourse-cdn.com/v4/letter/d/85f322/32.png) [@David\_Carmean](https://forum.ansible.com/u/David_Carmean)\
**Post date:** [June 3, 2014, 4:38am UTC](https://forum.ansible.com/t/are-roles-enough/15391/1 "2014-06-03T04:38:45Z")

</div>

I was happy to see “roles” when I came back to Ansible after a few months, but i’ve been struggling with how to apply them. I think this is partly because of cognitive dissonance between my mental model and the current terminology.

In my mind, any particular role that a server may fill (and it may fill more than one), in turn requires one or more “features” or “feature-sets” in order to be able to fulfill that role. In other words, I think of a heirarchy that looks like this;

- appstack\_X  
\*\* server\_n  
\*\*\* role\_a  
\*\*\*\* feature\_A  
\*\*\*\* feature\_E  
\*\*\*\* feature\_O  
\*\*\* role\_b  
\*\*\*\* feature\_A  
\*\*\*\* feature\_B  
\*\*\*\* feature\_G

Anyone else gone through this thought process,or organize their configs like this?

---

<div class="post-metadata">

**Author:** ![john.mee](https://avatars.discourse-cdn.com/v4/letter/j/977dab/32.png) [@john.mee](https://forum.ansible.com/u/john.mee)\
**Post date:** [June 3, 2014, 5:37am UTC](https://forum.ansible.com/t/are-roles-enough/15391/2 "2014-06-03T05:37:02Z")

</div>

Yes. I’m only new to ansible but am seriously struggling. The playbooks I can get my head around but the roles are proving very painful. I thought the idea might be to switch features on/off for each host via variables? Would that work?

[Trivial annoyance: i hate the way it requires a bunch of folders with just one file in them each]  
[Related to that sidenote: the folders are going to have lonely main.ymls for quite a while since the only apparent use of a file in the same directory is to be ‘included’ from main.yml? Have I got that wrong?]

---

<div class="post-metadata">

**Author:** ![Joost\_Cassee](https://avatars.discourse-cdn.com/v4/letter/j/898d66/32.png) [@Joost\_Cassee](https://forum.ansible.com/u/Joost_Cassee)\
**Post date:** [June 3, 2014, 11:03am UTC](https://forum.ansible.com/t/are-roles-enough/15391/3 "2014-06-03T11:03:12Z")

</div>

Recently I have changed my Ansible set-up based on roles. I have a very similar dependency structure as yours:

host1 → profile1, profile2  
host2 → profile2, profile3  
profile1 → state1, state2  
profile2 → state2, state3  
…

Both profiles and states are roles, but I separate them into two roles directories. I then use role dependencies between profiles and states (and states and states). A playbook simply ties hosts to profile roles.

A few thing I ran into:

- I needed to use a trick to make sure each state role is run only once. See [1].
- No parameters can be passed to state roles; global variables only. (I use a third role category named “configs” with roles that take parameters.)

Small annoyances:

- Tasks that are skipped because the role already ran still show up in the log.

Other than that, it works great!

I would give details, but I am still working on it. May post more when I am satisfied – or someone bugs me 🙂

[1] [https://groups.google.com/d/msg/ansible-project/nd4wMLsb0Jw/7-svzpNpTIQJ](https://groups.google.com/d/msg/ansible-project/nd4wMLsb0Jw/7-svzpNpTIQJ)

Regards,  
Joost

---

<div class="post-metadata">

**Author:** ![Brian\_Coca1](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@Brian\_Coca1](https://forum.ansible.com/u/Brian_Coca1)\
**Post date:** [June 3, 2014, 12:24pm UTC](https://forum.ansible.com/t/are-roles-enough/15391/4 "2014-06-03T12:24:59Z")

</div>

roles are there to make reusable units of non trivial set of tasks,  
sometimes its just easier to create a simple tasklist and use include:.

If it is becoming 'painful' its a sign of trying to put square peg in round  
hole. Ansible is designed to be simple, also it is very flexible and can be  
used in many different ways. It leaves organization up to you but sometimes  
this becomes an issue, specially if coming from other tools from which you  
got into the habit of complexity.

I recommend taking a step back at this point, go back to you goal and think  
of simpler approaches.

for the original poster, you can use roles == features or even a 'wrapper  
role' that uses the feature roles as dependencies. I generally equate  
'machine roles' == groups and use plays to group 'feature roles'.

---

<div class="post-metadata">

**Author:** ![chris\_snyder](https://avatars.discourse-cdn.com/v4/letter/c/7c8e57/32.png) [@chris\_snyder](https://forum.ansible.com/u/chris_snyder)\
**Post date:** [June 3, 2014, 1:10pm UTC](https://forum.ansible.com/t/are-roles-enough/15391/5 "2014-06-03T13:10:08Z")

</div>

I have to agree with Brian – sounds like you are not breaking your problem down into simple enough parts.

The problem with Ansible (and other similar config management / state management tools) is that most people (well, at least me) come in thinking one way about their requirements which isn’t immediately compatible with how the tool was designed and/or works. You have to learn to think about your problems in terms of Ansible (or whatever tool you’re using).

In this case, Ansible is stupidly simple on purpose. However, I’ve been beating my head against it for about 6 months now and am just starting to really ‘get it’. And most of that was me learning how to simplify what I needed to do into smaller and smaller chunks which made sense for Ansible and then how to relate those chunks together.

One of the big things was determining when and where I did certain things within Ansible. You can put things in playbooks or roles or both, but not all will necessarily be good for you. For example I have a role for my NTP configuration. I then have this role applied to all hosts in my top level play list. However, I then ran into a hurdle as all machines need NTP, but there is one machine that must be an NTP server. I first worked on this with having different roles (ntp-client vs ntp-server) but found for my needs that a single ‘ntp’ role would suffice and within that role I then choose one of two different templates (client vs server) based upon whether or not the host was in the ‘ntp server‘ host group. I do want to point out that I could have used two different roles but I decided against that for reasons that make sense within my hosting environment. My point is, I had many options on how to put the Ansible building blocks together and it took me a while to figure out the best way to put them together for my needs. There was a lot of trial and error. But I’ve finally got there.

Another thing I did was to use the ‘group\_by’ functionality to build host groups on the fly. Then I use those groupings to determine when to apply different roles or even different parts of specific roles. So, originally I just had roles with a single ‘tasks/main.yml’. And I tried to keep it that way. But after working with Ansible for a while and reviewing what I was trying to do, I now have roles with lots of task files that get included within tasks/main.yml. So a lot of my roles use a lot of ‘include/when’ patterns based around groupings I’ve built on the fly via ‘group\_by’.

So, TL;DR – keep pounding on it, keep trying different code arrangements, keep trying to break your requirements into smaller and simpler parts. Also, you have to figure out how best to put all the pieces together. Such as some people don’t use role dependencies, but some people love them. Eventually you’ll get it. And I would say that as you use Ansible expect that you will end up re-writing your entire Ansible code base a couple of times until you find a layout that works best for you.

Thx

Gopher.

---

<div class="post-metadata">

**Author:** ![Adam\_Morris](https://avatars.discourse-cdn.com/v4/letter/a/ecae2f/32.png) [@Adam\_Morris](https://forum.ansible.com/u/Adam_Morris)\
**Post date:** [June 3, 2014, 4:54pm UTC](https://forum.ansible.com/t/are-roles-enough/15391/6 "2014-06-03T16:54:50Z")

</div>

Yes and no…

In the case above I would consider that feature\_A is a separate role but is a dependency of role\_a and role\_b…

In my case I have a “common” role that performs a number of trivial tasks. Each task is a separate, distinct, task so it has it’s own file in role/common/tasks/… The main.yml includes all of those tasks within that role, but order in this case is irrelevant.

So for your example I would have the following structure…

role/role\_a/tasks/  
feature\_E  
feature\_O  
role/role\_b/tasks/  
feature\_B  
feature\_G  
role/feature\_a/tasks/  
feature\_A

and then in both role/role\_a/meta and role/role\_b/meta you would have a main.yml that had  
dependencies:

- {feature\_a}

If you later added a role\_c using features C, D and F it would not include a dependency for feature\_a… I would still have a separate main.yml in role/feature\_a/tasks (although I would not use that name) in case I ever wanted to add an additional task to that feature. That way I can write the new task and then modify the main.yml.

I hope that this helps,

Adan

---

<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:** [June 6, 2014, 12:24pm UTC](https://forum.ansible.com/t/are-roles-enough/15391/7 "2014-06-06T12:24:39Z")

</div>

> Yes. I'm only new to ansible but am seriously struggling. The playbooks I  
> can get my head around but the roles are proving very painful. I thought  
> the idea might be to switch features on/off for each host via variables?  
> Would that work?

I suggest you look at lots of other people's roles and playbooks.

Roles are just a way to group tasks, handlers, and files/templates they  
use, so they are just a basic grouping around normal ansible syntax.

> [Trivial annoyance: i hate the way it requires a bunch of folders with  
> just one file in them each]

Sorry, this will not be changing.

> [Related to that sidenote: the folders are going to have lonely main.ymls  
> for quite a while since the only apparent use of a file in the same  
> directory is to be 'included' from main.yml? Have I got that wrong?]

You can also put things in the main.yaml.

---

<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:** [June 6, 2014, 12:25pm UTC](https://forum.ansible.com/t/are-roles-enough/15391/8 "2014-06-06T12:25:48Z")

</div>

> Both profiles and states are roles, but I separate them into two roles  
> directories. I then use role dependencies between profiles and states (and  
> states and states). A playbook simply ties hosts to profile roles.
> 
> A few thing I ran into:  
> \* I needed to use a trick to make sure each state role is run only once.  
> See [1].

Please don't try to make ansible more complex than it actually is. I'm not  
even sure what a "profile" or "state role" is, and if I don't know, that's  
a problem with someone interpreting ansible to be WAAAAY more complicated  
than it should be.

We're talking servers here, not programming.

Simplify. Keep things easy.

---

<div class="post-metadata">

**Author:** ![Joachim\_Friberg](https://avatars.discourse-cdn.com/v4/letter/j/6a8cbe/32.png) [@Joachim\_Friberg](https://forum.ansible.com/u/Joachim_Friberg)\
**Post date:** [June 6, 2014, 9:02pm UTC](https://forum.ansible.com/t/are-roles-enough/15391/9 "2014-06-06T21:02:09Z")

</div>

I have it as simple as this;  
Playbooks  
\ server1.yml  
\ server2.yml  
\ roles/ldap  
\ roles/Apache...

And so on, its very simple and its easy to manager 🙂

---

<div class="post-metadata">

**Author:** ![Joost\_Cassee](https://avatars.discourse-cdn.com/v4/letter/j/898d66/32.png) [@Joost\_Cassee](https://forum.ansible.com/u/Joost_Cassee)\
**Post date:** [June 6, 2014, 9:35pm UTC](https://forum.ansible.com/t/are-roles-enough/15391/10 "2014-06-06T21:35:07Z")

</div>

Hi Michael and others,

It could be me explaining wrong, or I could be off the path, but let  
me try again. My site playbook is basically only used to tie roles to  
host groups. Those roles are specific for our infrastructure, e.g.  
setting up our frontend server, backend server, etc. I call those  
"profiles". The roles I call "states" are more like shareable  
components: setting up Nginx, fail2ban, etc. The dependencies follow  
the path: playbook -\> profile role -\> state roles (-\> state roles).

This feels quite natural to me, but I do run into the issues I  
described. If this set-up is still too complex I am very interested to  
hear about simplifications.

Regards,  
Joost

---

<div class="post-metadata">

**Author:** ![Dick\_Davies](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@Dick\_Davies](https://forum.ansible.com/u/Dick_Davies)\
**Post date:** [June 7, 2014, 11:57am UTC](https://forum.ansible.com/t/are-roles-enough/15391/11 "2014-06-07T11:57:13Z")

</div>

It's cleaner to have the roles explicitly listed up in site.yml .  
Then site.yml defines the roles on each host group, and you avoid the  
issue with roles running twice when you explicitly define them that way.

You can still have 'states' as you define them just as typical roles, maybe  
with a README in there to explain it's a 'building block' role and  
needs further config  
to be usable (we name those roles base-nginx, base-elasticsearch, etc.  
when they don't have a valid config so will need to be tailored to do  
be functional).

Having said all that, I do use roles/foo/meta/main.yml to 'autoload'  
dependencies sometimes;  
there are several of us working on this playbook so it can be helpful.

Mind you, I've got several years of Puppet baggage so 'wiring' modules  
together is in  
my muscle memory, I'm not sure if that's the Ansible Way..

---

<div class="post-metadata">

**Author:** ![Michael\_Dur](https://avatars.discourse-cdn.com/v4/letter/m/a6a055/32.png) [@Michael\_Dur](https://forum.ansible.com/u/Michael_Dur)\
**Post date:** [June 8, 2014, 4:14am UTC](https://forum.ansible.com/t/are-roles-enough/15391/12 "2014-06-08T04:14:58Z")

</div>

David,  
I’m coming from a similar place in terms of seeing things as roles with features and I’m also just getting started with ansible.

I made a common role considering it as ‘included for all roles and applied conditionally’.  
Tasks are included based on group membership, or host in inventory.  
I organize the files dir into folders for each task, which each represent “features”.  
You can account for configuration differences within tasks based on inventory as well.

Based on ideas in this thread I’m considering breaking as much as I can into “feature” roles, which are added to “functional” roles, and only leaving what is truly common (ie. firewall rules, etc).

---

<div class="post-metadata">

**Author:** ![Aaron\_Hunter](https://avatars.discourse-cdn.com/v4/letter/a/e19adc/32.png) [@Aaron\_Hunter](https://forum.ansible.com/u/Aaron_Hunter)\
**Post date:** [June 8, 2014, 4:45pm UTC](https://forum.ansible.com/t/are-roles-enough/15391/13 "2014-06-08T16:45:05Z")

</div>

I recommend you take a step back and look at the problem from the perspective of your overall Configuration Management (CM) process. For example, what are your configuration items (CIs)? What is your change management process? What is your version control process? First document these processes and then adapt Ansible to fit them. In my experience Ansible is very flexible and can fit whatever process you have in place. I wouldn’t worry about Ansible’s terminology. Roles, Groups, etc. can be whatever you want them to be; they are just arbitrary labels.

The most important thing is to identify your CIs. Then structure your playbooks to manage them. Their level of granularity depends on the level that your CM plan calls for. Each CI should be under version control at the very least. Avoid the mistake of a tool-centric perspective. Focus on good, quality processes and then customize the tools to support them.

–Aaron
