Answers: <p>The layout of your repository depends in many ways upon the context you are developing the automation in.  If, for example, you are building out the infrastructure for a product as part of a product team, then it would make sense to tie the infrastructure to the product - i.e. keep the infrastructure in the same repository as the software source code.</p>
  
  <p>If however, you are building out common infrastructure components to stand-up basic infrastructure for DNS, File Storage, Email, etc. then it probably makes more sense to have a single <code>common-infrastructure</code> repository.  Some of this will be tied to the tool you are using, Terraform for example leads you down the path of having a single repository for all of your environments to support the <a href="https://www.terraform.io/docs/state/" rel="noreferrer"><code>terraform.tfstate</code> construct</a>.</p>
  
  <h1>Reusability</h1>
  
  <p>You quite rightly called out reusability and code sharing as a problem you are going to encounter sooner rather than later.  This is an important principle in Software Development called <strong>Don't Repeat Yourse - or DRY</strong> for short.  Most all DevOps tools allow you to modularize your code in such a way that you don't need to copy/paste code:</p>
  
  <ul>
  <li><a href="https://www.terraform.io/docs/modules/usage.html" rel="noreferrer">Terraform Modules</a></li>
  <li><a href="https://docs.ansible.com/ansible/2.4/playbooks_reuse.html" rel="noreferrer">Ansible Roles</a></li>
  <li><a href="https://docs.chef.io/libraries.html" rel="noreferrer">Chef Libraries</a></li>
  <li><a href="https://plugins.jenkins.io/" rel="noreferrer">Jenkins Plugins</a></li>
  </ul>
  
  <h1>Conceptual Consistency</h1>
  
  <p>I <strong>advise</strong> that you don't use too many tools, try and standardise on a single tool rather than changing tools for each project, typically you see sets of tools being used across an organization:</p>
  
  <ul>
  <li>Jenkins, Terraform and Ansible</li>
  <li>TeamCity, Octopus Deploy and Desired State Configuration</li>
  </ul>
  
  <p>This makes it easier to share code across projects, document what has been done so far and handover the code to other or future developers.</p>
  
Answers: CC BY-SA 3.0
Answers: 2018-01-09T21:05:32.543Z
Answers: Talking about shared code, would it make sense to use a git submodule? This allows it to be versioned and different projects to use different versions while being easy to upgrade. It’s basically a poor mans VCS.
Answers: Moritz
Answers: CC BY-SA 3.0
Answers: 2018-01-10T10:00:19.350Z
Answers: @Moritz you have to be a bit careful of submodules, and incorporate them into your workflow with the full agreement of the whole team otherwise, it tends to descend into chaos.  See [effective use of submodules](https://www.philosophicalhacker.com/post/using-git-submodules-effectively/).
Answers: Richard Slater
Answers: CC BY-SA 3.0
Answers: 2018-01-10T12:32:04.230Z
Answers: Agreed, using submodules requires the team to be fairly familiar with Git. Had a few problems at the beging because Git was treated like SVN
Answers: Moritz
Answers: CC BY-SA 3.0
Answers: 2018-01-10T17:59:04.177Z
Answers: Thanks Richard. currently my Infrastructure-as-Code will be separated based on projects, according to what you suggest. and I already have ansible roles for my project1. About code reusability, how will the future projects make use of the roles in my project1? should I move roles of  directory project1 from project1 to a top directory so that project2 can also use it? all the tutorials of ansible put roles directory in its project. so I do not know how roles is reused.
Answers: user389955
Answers: CC BY-SA 3.0
Answers: 2018-01-11T09:47:24.047Z
Answers: @user389955 I generally follow the Open Source model, anything that could be shared across multiple projects is extracted out to a `shared` project.
Answers: Richard Slater
Answers: CC BY-SA 4.0
Answers: 2020-12-27T16:13:36.490Z
Answers: @user389955 Usually roles should live in their own repository. Roles is reusable piece. They should be tailored to be environment agnostic and should be as dumb as possible. All the project specific "magic" should happen in the playbooks and mby even nested playbooks.
Answers: Dzintars
Answers: CC BY-SA 3.0
Answers: 2018-01-08T09:54:08.567Z
Answers: 2018-01-08T09:54:08.567Z
Answers: Richard Slater
Body: <p>I have completed an Infrastructure-as-Code project using Terraform and Ansible. Currently, I organize my project as follows:</p>
  
  <pre><code>Project1
      Terraform
        ec2.tf
        rds.tf
        …
        variables.tf
        scripts\&lt;some script files&gt;
        templetes\&lt;some tfl files as templates&gt;
      Ansible
        Playbooks&lt;some playbook yml files&gt; 
           playbook1.yml
           playbook2.yml
           ……
        ansible_hosts
        vars\&lt;some variable files used by vars_file&gt;
        files\&lt;files to be copied to remote hosts&gt;
        templates\&lt;jinja2 templated files&gt;
        roles\&lt;some roles such as webserver, dbserver, etc.&gt;
  </code></pre>
  
  <p>Note I did not layout Ansible code using the following links yet:</p>
  
  <ul>
  <li><a href="https://leucos.github.io/ansible-files-layout" rel="nofollow noreferrer">https://leucos.github.io/ansible-files-layout</a></li>
  <li><a href="http://docs.ansible.com/ansible/latest/playbooks_best_practices.html" rel="nofollow noreferrer">http://docs.ansible.com/ansible/latest/playbooks_best_practices.html</a></li>
  </ul>
  
  <p>e.g. I did not put <code>vars/</code>, <code>templates/</code>, <code>files/</code> to individual role folder since Most of my roles did not have vars and templates. Besides, I want to manage <code>vars</code>, <code>templates</code>, <code>files</code> in one file instead of multiple roles, so I moved <code>vars/</code>, <code>templates/</code> and <code>files/</code> out of <code>roles/</code>.</p>
  
  <p>For my next project, I may build an Infrastructure-as-code project using CloudFormation/Terraform and Ansible/Chef. Next, I may work on Jenkins, code pipeline, and so on.</p>
  
  <p>In general, should I organize my DevOps projects based on projects, in this way:</p>
  
  <pre><code>Project1:
    Terraform
    Ansible
  Project2:
    Terraform
    Ansible
    ......
  </code></pre>
  
  <p>Or should I organize my DevOps projects based on tools, in this way:</p>
  
  <pre><code>Terraform
    Project1
    Project2
  Ansible
    Project1
    Project2
  Cloudformation
    Project3
    Project4
  </code></pre>
  
  <p>I believe separate with projects makes more sense. but then how do we reuse code? for example, what if project1 and project2 use similar terraform code and some ansible roles. and I want to reuse the code of project1 to project2?</p>
  
  <p>or is there any typical samples online I can refer? </p>
  
Tags: <ansible><terraform><infrastructure-as-code><repository>
Title: How to organize infrastructure as code projects?
UserDisplayName: user389955
ThreadText: # How to organize infrastructure as code projects?
  
  (Asked by: username_0 on 2018-01-08)
  
  I have completed an Infrastructure-as-Code project using Terraform and Ansible. Currently, I organize my project as follows:
  
  ```
  Project1
      Terraform
        ec2.tf
        rds.tf
        …
        variables.tf
        scripts\<some script files>
        templetes\<some tfl files as templates>
      Ansible
        Playbooks<some playbook yml files> 
           playbook1.yml
           playbook2.yml
           ……
        ansible_hosts
        vars\<some variable files used by vars_file>
        files\<files to be copied to remote hosts>
        templates\<jinja2 templated files>
        roles\<some roles such as webserver, dbserver, etc.>
  
  ```
  
  Note I did not layout Ansible code using the following links yet:
  
  * <https://leucos.github.io/ansible-files-layout>
  * <http://docs.ansible.com/ansible/latest/playbooks_best_practices.html>
  
  e.g. I did not put `vars/`, `templates/`, `files/` to individual role folder since Most of my roles did not have vars and templates. Besides, I want to manage `vars`, `templates`, `files` in one file instead of multiple roles, so I moved `vars/`, `templates/` and `files/` out of `roles/`.
  
  For my next project, I may build an Infrastructure-as-code project using CloudFormation/Terraform and Ansible/Chef. Next, I may work on Jenkins, code pipeline, and so on.
  
  In general, should I organize my DevOps projects based on projects, in this way:
  
  ```
  Project1:
    Terraform
    Ansible
  Project2:
    Terraform
    Ansible
    ......
  
  ```
  
  Or should I organize my DevOps projects based on tools, in this way:
  
  ```
  Terraform
    Project1
    Project2
  Ansible
    Project1
    Project2
  Cloudformation
    Project3
    Project4
  
  ```
  
  I believe separate with projects makes more sense. but then how do we reuse code? for example, what if project1 and project2 use similar terraform code and some ansible roles. and I want to reuse the code of project1 to project2?
  
  or is there any typical samples online I can refer?
  
  **Tags:** ansible, terraform, infrastructure-as-code, repository
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2018-01-08. Score: 4 | Accepted answer
  
  The layout of your repository depends in many ways upon the context you are developing the automation in. If, for example, you are building out the infrastructure for a product as part of a product team, then it would make sense to tie the infrastructure to the product - i.e. keep the infrastructure in the same repository as the software source code.
  
  If however, you are building out common infrastructure components to stand-up basic infrastructure for DNS, File Storage, Email, etc. then it probably makes more sense to have a single `common-infrastructure` repository. Some of this will be tied to the tool you are using, Terraform for example leads you down the path of having a single repository for all of your environments to support the [`terraform.tfstate` construct](https://www.terraform.io/docs/state/).
  
  # Reusability
  
  You quite rightly called out reusability and code sharing as a problem you are going to encounter sooner rather than later. This is an important principle in Software Development called **Don't Repeat Yourse - or DRY** for short. Most all DevOps tools allow you to modularize your code in such a way that you don't need to copy/paste code:
  
  * [Terraform Modules](https://www.terraform.io/docs/modules/usage.html)
  * [Ansible Roles](https://docs.ansible.com/ansible/2.4/playbooks_reuse.html)
  * [Chef Libraries](https://docs.chef.io/libraries.html)
  * [Jenkins Plugins](https://plugins.jenkins.io/)
  
  # Conceptual Consistency
  
  I **advise** that you don't use too many tools, try and standardise on a single tool rather than changing tools for each project, typically you see sets of tools being used across an organization:
  
  * Jenkins, Terraform and Ansible
  * TeamCity, Octopus Deploy and Desired State Configuration
  
  This makes it easier to share code across projects, document what has been done so far and handover the code to other or future developers.
  
  > **Comments:**
  > **username_2**: Talking about shared code, would it make sense to use a git submodule? This allows it to be versioned and different projects to use different versions while being easy to upgrade. It’s basically a poor mans VCS.  
  > **username_1**: @username_2 you have to be a bit careful of submodules, and incorporate them into your workflow with the full agreement of the whole team otherwise, it tends to descend into chaos.  See [effective use of submodules](https://www.philosophicalhacker.com/post/using-git-submodules-effectively/).  
  > **username_2**: Agreed, using submodules requires the team to be fairly familiar with Git. Had a few problems at the beging because Git was treated like SVN  
  > **username_0**: Thanks username_1. currently my Infrastructure-as-Code will be separated based on projects, according to what you suggest. and I already have ansible roles for my project1. About code reusability, how will the future projects make use of the roles in my project1? should I move roles of  directory project1 from project1 to a top directory so that project2 can also use it? all the tutorials of ansible put roles directory in its project. so I do not know how roles is reused.  
  > **username_1**: @username_0 I generally follow the Open Source model, anything that could be shared across multiple projects is extracted out to a `shared` project.  
  > **username_3**: @username_0 Usually roles should live in their own repository. Roles is reusable piece. They should be tailored to be environment agnostic and should be as dumb as possible. All the project specific "magic" should happen in the playbooks and mby even nested playbooks.  
  
  ---
  
  