# 3 Solutions to structure a deployment ?

**URL:** <https://forum.ansible.com/t/3-solutions-to-structure-a-deployment/26124>\
**Category:** Ansible Project\
**Tags:** windows, galaxy-ng\
**Created:** [November 24, 2017, 10:08am UTC](https://forum.ansible.com/t/3-solutions-to-structure-a-deployment/26124 "2017-11-24T10:08:28Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![akazia.info](https://avatars.discourse-cdn.com/v4/letter/a/6de8d8/32.png) [@akazia.info](https://forum.ansible.com/u/akazia.info)\
**Post date:** [November 24, 2017, 10:08am UTC](https://forum.ansible.com/t/3-solutions-to-structure-a-deployment/26124/1 "2017-11-24T10:08:28Z")

</div>

Hello

I am currently deploying a new product and came across some problems to structure my Playbook and roles. I have three different solutions and hope to get some input which path might be the best.

The product is a webapp on a windows server. The following steps are needed to deploy (high level):  
install javajdk  
install tomcat  
install win\_service  
configure java regkes  
configure tomcat

install webapp  
start service

I use static inventories for prod and stageing, group\_vars, roles (created with ansible-galaxy) so there is some kind of structure …

\*\* Solution 1 \*\*  
put everything in one huge playbook. That does not sound well, but has the advantage that you know the variables from prev installations e.g. tomcat needs to know where JAVA\_HOME is… that was with the javajdk installation, due to more than one java on the machines there is no global JAVA\_HOME…

\*\* Solution 2 \*\*  
break all out in small roles. Sounds great but roles should be independent from each other.I did not found a method to decouple tasks. Would it make sense to have single roles for e.g. install\_tomcet, config\_tomcat and set up a playbook which has the mentioned roles in sequence? but how does on role know about e.g. a path name which is needed in the next roll. → Installation sets the path, config needs to know… I an really unsure to make roles independend.

\*\* Solution 3 \*\*  
Kind of solution 2. Have a main playbook which contains only roles, Split as much as possible to roles. Have independent variable names in ./roles//vars/main.yml Somehow(?) find a place higher in der variable precedence with the playbook where all needed var definitions go. Inernallay either path a variable to the role or simply overrule a rolevariable.  
e.b. a product has a service, the service name is generally part of a pathname for tomcat.  
the tomcat name should not depend on the service, so there should be a tomcat\_install\_path in the role but also a service\_name with the product  
So in case the playbook for the product is called the servcie name should be part of the name,  
In case the tomcat\_install is called with a total different deployment there should be no fiddling with a service name

I would go with Solution 3 but I have not yet found a way to set that up.

What is the experts opinion, is solution 3 doable, is one of the other once better or is there a solution 4 ??

Thanks a lot  
Michael

---

<div class="post-metadata">

**Author:** ![j.r.hawkesworth](https://avatars.discourse-cdn.com/v4/letter/j/a3d4f5/32.png) [@j.r.hawkesworth](https://forum.ansible.com/u/j.r.hawkesworth)\
**Post date:** [November 28, 2017, 11:38am UTC](https://forum.ansible.com/t/3-solutions-to-structure-a-deployment/26124/2 "2017-11-28T11:38:17Z")

</div>

I am no expert. I am big fan of doing the simplest thing that works for now, and then refactoring things when the simplest thing becomes too simple.

Some things that might help you decide what is going to work best for you.

You can have mulitple files in your tasks folder in your role. This lets you split up say installing tomcat and configuring it. your tasks/main.yml then just includes the files with the tasks that you need. This starts to pay off when you can start using include\_role: and tasks\_from so you can reuse bits of a role as appropriate in other roles.  
see [http://docs.ansible.com/ansible/latest/include\_role\_module.html](http://docs.ansible.com/ansible/latest/include_role_module.html)

You may find using role defaults useful, as you can have say a default version of java but override it with playbook or inventory vars if you need to have a different version for one particular situation.

You can pass parameters to roles, which might help you with solution 3. You can probably make the parameters optional by using the default filter [http://docs.ansible.com/ansible/latest/playbooks\_filters.html#defaulting-undefined-variables](http://docs.ansible.com/ansible/latest/playbooks_filters.html#defaulting-undefined-variables) if its not always appropriate to pass a parameter to your role.

I think what you wind up with will depend very much on your situation. If you are hosting many apps for many different customers at different versions then you will wind up with something different from somewhere where you are hosting an application that is shared by one or more clients.

Hope this helps,

Jon
