# Looking for feedback on content organization

**URL:** <https://forum.ansible.com/t/looking-for-feedback-on-content-organization/13145>\
**Category:** Ansible Project\
**Created:** [July 17, 2013, 6:54pm UTC](https://forum.ansible.com/t/looking-for-feedback-on-content-organization/13145 "2013-07-17T18:54:34Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alex\_Trevino](https://avatars.discourse-cdn.com/v4/letter/a/a8b319/32.png) [@Alex\_Trevino](https://forum.ansible.com/u/Alex_Trevino)\
**Post date:** [July 17, 2013, 6:54pm UTC](https://forum.ansible.com/t/looking-for-feedback-on-content-organization/13145/1 "2013-07-17T18:54:34Z")

</div>

Hi,

I’ve been using ansible for a few months, and just got around to reorganizing our playbooks to follow the latest best practices. I wanted to share my project structure, hoping that someone can spot if I’m doing something terribly wrong and can suggest a better approach. At the very least I hope that this is an interesting read to someone. 🙂

Our environment / use cases:

1. We have three environments (dev, stage, prod), and while a given app is deployed the same way across all envs, it runs as a different user in each env (e.g dev-appsvc, stg-appsvc, prd-appsvc).

2. We use jenkins to run our playbooks. We have jobs named “upgrade environment - staging”, and such.

3. Need flexibility when working with certain config files. For example: we’re testing an nginx site config in staging, but this change isn’t ready for prod. Meanwhile, we need to update prod with a hotfix! We’d like to update the app in prod, but let it keep its current nginx config (since the config in staging isn’t ready yet).

To address #1 and #3, I used the following folder structure:

> 

±- roles

> 

±- fooapp

> 

±- files

> ±- nginx\_config\_development  
> ±- nginx\_config\_staging  
> ±- nginx\_config\_production  
> ±- vars  
> ±- development\_vars.yml  
> ±- staging\_vars.yml  
> ±- production\_vars.yml

Where environment-specific variables are defined in each vars file:

# file: staging\_vars.yml

---

<div class="post-metadata">

**Author:** ![seanosh](https://avatars.discourse-cdn.com/v4/letter/s/9fc29f/32.png) [@seanosh](https://forum.ansible.com/u/seanosh)\
**Post date:** [July 18, 2013, 3:28pm UTC](https://forum.ansible.com/t/looking-for-feedback-on-content-organization/13145/2 "2013-07-18T15:28:50Z")

</div>

Hey Alex,

Thanks for this! An interesting read for me anyway as I’m similarly geared on my end (3 different environments), with a few different tweaks:

- Use of group\_vars to set the “environment” var and other environment specific vars (to avoid passing in --extra-vars=“environment=” and/or “-i environment” each time). Keeps vars for an environment like staging or dev in one place, but I do like your approach of coupling the vars to the roles that use them. I believe though based on my understanding of variable precedence that if you wanted to override any of those role based vars you’d have to use --extra-vars (perhaps my needs are different where I opted to override a var on a per host level, if needed).
- To keep configs as “DRY” as possible, I use one template with logic for handling different environments (such as having output caching disabled in dev, but not on stage or prod). If I need to test a config change I can just run the related tasks against dev/staging first, test, then run against production. What I like about your approach (with separate configs for environments) is that it can keep the configs a bit more readable without all this conditional environment logic. Just a trade off that updates have to then be made in multiple configs (in my use case).

Would definitely be curious to hear the feedback from others as well!

Sean

---

<div class="post-metadata">

**Author:** ![Leen\_Besselink](https://avatars.discourse-cdn.com/v4/letter/l/a183cd/32.png) [@Leen\_Besselink](https://forum.ansible.com/u/Leen_Besselink)\
**Post date:** [July 18, 2013, 3:38pm UTC](https://forum.ansible.com/t/looking-for-feedback-on-content-organization/13145/3 "2013-07-18T15:38:18Z")

</div>

Alex/Sean,

> Hey Alex,
> 
> Thanks for this! An interesting read for me anyway as I'm similarly geared  
> on my end (3 different environments), with a few different tweaks:
> 
> \* Use of group\_vars to set the "environment" var and other environment  
> specific vars (to avoid passing in --extra-vars="environment=" and/or "-i  
> environment" each time). Keeps vars for an environment like staging or dev  
> in one place, but I do like your approach of coupling the vars to the roles  
> that use them. I believe though based on my understanding of variable  
> precedence that if you wanted to override any of those role based vars  
> you'd have to use --extra-vars (perhaps my needs are different where I  
> opted to override a var on a per host level, if needed).  
> \* To keep configs as "DRY" as possible, I use one template with logic for  
> handling different environments (such as having output caching disabled in  
> dev, but not on stage or prod). If I need to test a config change I can  
> just run the related tasks against dev/staging first, test, then run  
> against production. What I like about your approach (with separate configs  
> for environments) is that it can keep the configs a bit more readable  
> without all this conditional environment logic. Just a trade off that  
> updates have to then be made in multiple configs (in my use case).
> 
> Would definitely be curious to hear the feedback from others as well!

We've been thinking of deploying Ansible, but we haven't put in the time to create our structure.

Have you considered using version control to keep 3 seperate branches and deploy from that ?

We have a few places in our configuration files where we specify what the environment is that the  
application is running in where we could just make these files into a template a simple  
variable substitution with 'test' 'prod' or 'dev' would be enough.

---

<div class="post-metadata">

**Author:** ![seanosh](https://avatars.discourse-cdn.com/v4/letter/s/9fc29f/32.png) [@seanosh](https://forum.ansible.com/u/seanosh)\
**Post date:** [July 18, 2013, 3:51pm UTC](https://forum.ansible.com/t/looking-for-feedback-on-content-organization/13145/4 "2013-07-18T15:51:12Z")

</div>

For me, I do keep separate branches for changes and then just apply those updates from that branch to test. If it all checks out, I’ll pull request the branch and deploy everywhere, but I don’t keep separate long-lived branches where each branch represents an environment…

I’m also in the process of marching towards using Ansible and Vagrant together to better test updates before they go to any stage or production environments (instead of testing updates directly against say, staging, where other devs/clients are using actively using it)…

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [July 18, 2013, 8:56pm UTC](https://forum.ansible.com/t/looking-for-feedback-on-content-organization/13145/5 "2013-07-18T20:56:18Z")

</div>

So, a couple of things.

(A)

You wouldn’t want to put /everything/ in branches, because you don’t want to tweak development environment specific values to production values when merging.

I recommend using different inventory locations for QA/Stage/Prod and also putting hosts into different groups, so that you can apply group\_vars for different things, like if the development/stage environments had a different branch name or something similar.

(B)

“environment” is a reserved variable in Ansible, I’d name this something like “env”. The reason for this is environment is the hash table of environment values to pass to the server, as set by the “environment” keyword.

Do not pass “environment” as a variable and life should be good.

(C)

Branches are generally good otherwise to reflect _VERSIONS_ of context, but branches shouldn’t be used to keep _differences_

For instance, if I am working on the 1.8.5 release of my app, I’d like to be able to keep the development and prod variables for this in the same branch. Let’s call this branch “devel”. When I want to maintain the release, I can branch to “1.8.5” for a maintainance branch.

Hope this makes sense and would be happy to offer other suggestions/etc.

TLDR – group vars good, and branch for versions, not environmental differences. Also seperate inventory files are VERY good to prevent deploying a set of servers when you don’t want to! 🙂

---

<div class="post-metadata">

**Author:** ![David\_Tauzell](https://avatars.discourse-cdn.com/v4/letter/d/ecae2f/32.png) [@David\_Tauzell](https://forum.ansible.com/u/David_Tauzell)\
**Post date:** [August 13, 2013, 8:57pm UTC](https://forum.ansible.com/t/looking-for-feedback-on-content-organization/13145/6 "2013-08-13T20:57:50Z")

</div>

If you want to deploy off of that “1.8.5 maintenance branch” would you check it out on you ansible deploy server?

I can imagine that app "foo"has a playbook to install. In verison 1.8.6 it changes. I want to use the 1.8.6 version to deploy to “dev” but the “1.8.5 maintenance” version to deploy to “production”. Can these all be on the ansible server at the same time? Or do I need to checkout the version of my ansible files first and then run the commands?

-Dave

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [August 14, 2013, 12:35am UTC](https://forum.ansible.com/t/looking-for-feedback-on-content-organization/13145/7 "2013-08-14T00:35:05Z")

</div>

I would likely check out each branch in different locations if you want to use both at more or less the same time.
