# Role patterns

**URL:** <https://forum.ansible.com/t/role-patterns/18482>\
**Category:** Ansible Project\
**Created:** [June 12, 2015, 8:35am UTC](https://forum.ansible.com/t/role-patterns/18482 "2015-06-12T08:35:54Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jose\_Riguera\_Lopez](https://avatars.discourse-cdn.com/v4/letter/j/aeb1de/32.png) [@Jose\_Riguera\_Lopez](https://forum.ansible.com/u/Jose_Riguera_Lopez)\
**Post date:** [June 12, 2015, 8:35am UTC](https://forum.ansible.com/t/role-patterns/18482/1 "2015-06-12T08:35:54Z")

</div>

Hi all,

I have started with Ansible some months ago, and as I like having a kind of patterns in order to have reusable pieces of code. I have created this sort of example role with some of them (ofc, it is not functional). The idea is having something to clone and start working … What do you think about the idea (and also, about the implementation)? [https://github.com/jriguera/ansible-role-pattern](https://github.com/jriguera/ansible-role-pattern)

Cheers

---

<div class="post-metadata">

**Author:** ![Barry\_Kaplan](https://avatars.discourse-cdn.com/v4/letter/b/48db29/32.png) [@Barry\_Kaplan](https://forum.ansible.com/u/Barry_Kaplan)\
**Post date:** [June 13, 2015, 2:53am UTC](https://forum.ansible.com/t/role-patterns/18482/2 "2015-06-13T02:53:29Z")

</div>

This is very nice. An excellent guide over the ansible docs.

---

<div class="post-metadata">

**Author:** ![Barry\_Kaplan](https://avatars.discourse-cdn.com/v4/letter/b/48db29/32.png) [@Barry\_Kaplan](https://forum.ansible.com/u/Barry_Kaplan)\
**Post date:** [June 13, 2015, 5:46am UTC](https://forum.ansible.com/t/role-patterns/18482/3 "2015-06-13T05:46:07Z")

</div>

On the topic patterns, something I have been experiment with is to not try to define attributes for config files that are then substituted via a template by the role. Rather I have been using native configuration.

It seems to me that there is little value trying to turn every type of config into native yaml only to have to regenerate the native format. By using the native format directly the configuration is much clearer with less cognitive load due the the translation.

Here’s an example using my logstash role:

`  
roles:

- role: logstash  
logstash\_configs:  
00\_mesos: |  
input {  
file {  
path =\> [“/var/log/mesos/mesos-slave.INFO”]  
exclude =\> [“_.log._”, “_.gz"]  
tags =\> [“infra”, “mesos”, “mesos-slave”]  
add\_field =\> { “level” =\> “INFO” }  
}  
file {  
path =\> [“/var/log/mesos/mesos-slave.WARN”]  
exclude =\> ["_.log._", "_.gz”]  
tags =\> [“infra”, “mesos”, “mesos-slave”]  
add\_field =\> { “level” =\> “WARN” }  
}  
file {  
path =\> [“/var/log/mesos/mesos-slave.ERROR”]  
exclude =\> [“_.log._”, “\*.gz”]  
tags =\> [“infra”, “mesos”, “mesos-slave”]  
add\_field =\> { “level” =\> “ERROR” }  
}  
}

00\_consul: |  
input {  
file {  
type =\> “consul”  
path =\> [“/var/log/consul.log”]  
exclude =\> [“_.log._”, “\*.gz”]  
tags =\> [“consul”]  
}  
}

00\_vimana: |  
input {  
file {  
type =\> “vimana”  
path =\> [“{{vi\_log\_dir}}/_.log"]  
exclude =\> ["_.log._", "_.gz”]  
tags =\> [“vimana”]  
codec =\> json  
}  
}

50\_env\_filter: |  
filter {  
add\_field =\> { “env”, “{{env}}” }  
}

99\_rabbitmq\_output: |  
output {  
rabbitmq {  
host =\> “rabbitmq.service.ops.consul”  
port =\> {{rabbitmq\_port}}  
user =\> “{{elk\_rabbitmq\_logstash\_user}}”  
password =\> “{{elk\_rabbitmq\_logstash\_password}}”  
vhost =\> “logstash”  
exchange =\> “logs\_json”  
exchange\_type =\> “direct”  
durable =\> true  
}  
}

99\_debug\_output: |  
output {  
stdout {  
codec =\> rubydebug  
}  
}  
`

---

<div class="post-metadata">

**Author:** ![Jose\_Riguera\_Lopez](https://avatars.discourse-cdn.com/v4/letter/j/aeb1de/32.png) [@Jose\_Riguera\_Lopez](https://forum.ansible.com/u/Jose_Riguera_Lopez)\
**Post date:** [June 13, 2015, 9:40am UTC](https://forum.ansible.com/t/role-patterns/18482/4 "2015-06-13T09:40:28Z")

</div>

Yep, I think that is a good pattern as well. With your permission, when I have enough time I will add that example to the repo, or you can do it by yourself if you want 🙂

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [June 13, 2015, 6:23pm UTC](https://forum.ansible.com/t/role-patterns/18482/5 "2015-06-13T18:23:25Z")

</div>

I used to just make them templates, keep the file in native format  
and only template out the options that vary per my different  
classifications (stage, location, purpose). Where stage was  
devel/qa/staging/prod, location had to do with datacenter or network  
(ntp, routes, dns servers, gateways) and purpose was the function the  
machine was dedicated for (could be multiple, but mostly webapp, load  
balancer, db, infrastructure, etc).

---

<div class="post-metadata">

**Author:** ![Barry\_Kaplan](https://avatars.discourse-cdn.com/v4/letter/b/48db29/32.png) [@Barry\_Kaplan](https://forum.ansible.com/u/Barry_Kaplan)\
**Post date:** [June 14, 2015, 2:19am UTC](https://forum.ansible.com/t/role-patterns/18482/6 "2015-06-14T02:19:25Z")

</div>

I have found (in my very short time with ansible, but informed by years of creating  
templates in chef) that all the context I need is already abstracted in the playbook,  
so creating the configuration directly in the play (with substitution) and passing the  
final config to the role yields the most flexibility. By that I mean the role did not have  
decide up front what bits the config I might and and might want to parameterize. Also,  
some configs are soooo big, with so much optional stuff it seems best to leave declaring  
the config to the playbook.

---

<div class="post-metadata">

**Author:** ![Barry\_Kaplan](https://avatars.discourse-cdn.com/v4/letter/b/48db29/32.png) [@Barry\_Kaplan](https://forum.ansible.com/u/Barry_Kaplan)\
**Post date:** [June 14, 2015, 2:20am UTC](https://forum.ansible.com/t/role-patterns/18482/7 "2015-06-14T02:20:01Z")

</div>

Either way is fine by me.
