Answers: <p>I would recommend to structure the code as defined in <a href="http://docs.ansible.com/ansible/latest/playbooks_best_practices.html" rel="nofollow noreferrer">the Ansible Best Practices document</a>:</p>
  
  <p><a href="https://i.sstatic.net/ntTF6.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ntTF6.png" alt="enter image description here"></a></p>
  
  <p>and to follow the structure that major contributors to the ansible galaxy platform use, like <a href="https://galaxy.ansible.com/geerlingguy/" rel="nofollow noreferrer">geerlingguy</a>.</p>
  
  <p>If one will follow a significant different structure then it will be really hard in the future to reuse roles from the <a href="https://galaxy.ansible.com/" rel="nofollow noreferrer">ansible galaxy</a> community and one has to reinvent the wheel.</p>
  
Answers: CC BY-SA 3.0
Answers: 2017-11-26T15:40:10.750Z
Answers: Thanks. And concrete in regards to my question: How will you decouple and reuse e.g. javajdk installation and the reuse of it in a tomcat installation? When they are decoupled than the variables e.g. pat to javaddk will need to be "in" the role. How do you handle this in a tomcat installation with out changing variables all over the place? Is there a common concept to use variable precedence? Is so which?
Answers: Michael Hoeller
Answers: CC BY-SA 3.0
Answers: 2018-01-04T21:46:54.153Z
Answers: I would check ansible galaxy and install a jdk and tomcat role. I will not write a role myself unless it is unavailable. For example, https://github.com/silpion/ansible-tomcat and `ansiblebit.oracle-java`
Answers: 030
Answers: CC BY-SA 3.0
Answers: 2018-01-04T21:52:18.743Z
Answers: Note that I did not test the tomcat role. You could test the tomcat role locally. If that does not work, you could use another tomcat role from galaxy.
Answers: 030
Answers: CC BY-SA 3.0
Answers: 2017-11-26T12:39:10.020Z
Answers: 2017-11-26T12:39:10.020Z
Answers: 030
Answers: <p>Short Answer: You do programming here. Consider Programming Standards (cleancode) like "package by feature" and build role which are reusable and express the reason of the role.
  e.g. </p>
  
  <pre><code>roles:
    - role: jdk
    - role: tomcat  
        (contains tasks with 'install tomcat', 'configure tomcat' ) 
        (requires jdk)
    - role: the_wepapp 
        (requires tomcat)
  </code></pre>
  
  <p>Futhermore: The underlying role e.g. the jdk should never know about the tomcat role etc...</p>
  
Answers: CC BY-SA 4.0
Answers: 2019-07-31T05:49:27.473Z
Answers: 2019-07-31T05:54:29.343Z
Answers: 2019-07-31T05:54:29.343Z
Answers: schmichri
Body: <p>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.</p>
  
  <p>The product is a webapp on a windows server. The following steps are needed to deploy (high level):</p>
  
  <ul>
  <li>install javajdk</li>
  <li>install tomcat</li>
  <li>install win_service</li>
  <li>configure java regkes</li>
  <li>configure tomcat</li>
  <li>install webapp</li>
  <li>start service</li>
  </ul>
  
  <p>I use static inventories for prod and staging, group_vars, roles (created with ansible-galaxy) so there is some kind of structure.</p>
  
  <hr>
  
  <p><strong>Solution 1</strong> 
  Put everything in one huge playbook. That does not sound well, but has the advantage that you know the variables from previous installations e.g. <code>tomcat</code> needs to know where <code>JAVA_HOME</code> is... that was with the <code>javajdk</code> installation, due to more than one java on the machines there is no global <code>JAVA_HOME</code>...</p>
  
  <hr>
  
  <p><strong>Solution 2</strong> 
  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. <code>install_tomcat</code>, <code>config_tomcat</code> and set up a playbook which has the mentioned roles in sequence? </p>
  
  <p>But how does one role know about, e.g. a path name which is needed in the next role. -> Installation sets the path, config needs to know.. I an really unsure to make roles independent.</p>
  
  <hr>
  
  <p><strong>Solution 3</strong> 
  Kind of solution 2. Have a main playbook which contains only roles, split as much as possible to roles. Have independent variable names in <code>./roles/vars/main.yml</code></p>
  
  <p>Somehow(?) find a place higher in the variable precedence with the playbook where all needed <code>var</code> definitions go. Internally either path a variable to the role or simply over-rule a role variable. </p>
  
  <p>E.g. a product has a service, the service name is generally part of a path name for <code>tomcat</code>. The <code>tomcat</code> name should not depend on the service, so there should be a <code>tomcat_install_path</code> in the role but also a <code>service_name</code> with the product. So in case the playbook for the product is called the service name should be part of the name, the <code>tomcat_install</code> is called with a total different deployment there should be no fiddling with a service name.</p>
  
  <hr>
  
  <p><em>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 4th solution?</em></p>
  
Tags: <ansible><structure>
Title: Three solutions to structure a deployment with Ansible?
UserDisplayName: Michael Hoeller
ThreadText: # Three solutions to structure a deployment with Ansible?
  
  (Asked by: username_0 on 2017-11-24)
  
  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 staging, 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 previous 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_tomcat`, `config_tomcat` and set up a playbook which has the mentioned roles in sequence?
  
  But how does one role know about, e.g. a path name which is needed in the next role. -> Installation sets the path, config needs to know.. I an really unsure to make roles independent.
  
  ---
  
  **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 the variable precedence with the playbook where all needed `var` definitions go. Internally either path a variable to the role or simply over-rule a role variable.
  
  E.g. a product has a service, the service name is generally part of a path name 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 service name should be part of the name, 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 4th solution?*
  
  **Tags:** ansible, structure
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2017-11-26. Score: 3
  
  I would recommend to structure the code as defined in [the Ansible Best Practices document](http://docs.ansible.com/ansible/latest/playbooks_best_practices.html):
  
  [![enter image description here](https://i.sstatic.net/ntTF6.png)](https://i.sstatic.net/ntTF6.png)
  
  and to follow the structure that major contributors to the ansible galaxy platform use, like [geerlingguy](https://galaxy.ansible.com/geerlingguy/).
  
  If one will follow a significant different structure then it will be really hard in the future to reuse roles from the [ansible galaxy](https://galaxy.ansible.com/) community and one has to reinvent the wheel.
  
  > **Comments:**
  > **username_0**: Thanks. And concrete in regards to my question: How will you decouple and reuse e.g. javajdk installation and the reuse of it in a tomcat installation? When they are decoupled than the variables e.g. pat to javaddk will need to be "in" the role. How do you handle this in a tomcat installation with out changing variables all over the place? Is there a common concept to use variable precedence? Is so which?  
  > **username_1**: I would check ansible galaxy and install a jdk and tomcat role. I will not write a role myself unless it is unavailable. For example, https://github.com/silpion/ansible-tomcat and `ansiblebit.oracle-java`  
  > **username_1**: Note that I did not test the tomcat role. You could test the tomcat role locally. If that does not work, you could use another tomcat role from galaxy.  
  
  ---
  
  ### Answer by username_2 on 2019-07-31. Score: 1
  
  Short Answer: You do programming here. Consider Programming Standards (cleancode) like "package by feature" and build role which are reusable and express the reason of the role.
  e.g.
  
  ```
  roles:
    - role: jdk
    - role: tomcat  
        (contains tasks with 'install tomcat', 'configure tomcat' ) 
        (requires jdk)
    - role: the_wepapp 
        (requires tomcat)
  
  ```
  
  Futhermore: The underlying role e.g. the jdk should never know about the tomcat role etc...
  
  
  ---
  
  