Currently I'm using the following structure:
hosts/development
hosts/production
hosts/group_vars/development/service1.yml
hosts/group_vars/development/service2.yml
hosts/group_vars/production/service1.yml
hosts/group_vars/production/service2.yml
hosts/group_vars/production/service3.yml
hosts/host_vars/dev1.yml
hosts/host_vars/prod1/something.yml
hosts/host_vars/prod1/something_else.yml
The inventories could look like this:
# hosts/development
dev1 ansible_ssh_host=dev1.example.com
dev2 ansible_ssh_host=dev2.example.com
[development]
dev1
dev2
[service1]
dev1
[service2]
dev2
[service3]
dev1
dev2
And for production:
# hosts/production
prod1 ansible_ssh_host=prod1.example.com
prod2 ansible_ssh_host=prod2.example.com
[production]
prod1
prod2
[service1]
prod1
[service2]
prod2
[service3]
prod1
prod2
This allows for some nice combinations. By using ansible -i hosts
I can target all known hosts. I'm using this, for example, to add all servers in the inventory to a monitoring configuration file.
By using ansible -i hosts/development
I can limit the command to the development (or production) servers. I do this when I want to test a new configuration on the development system before I apply it to production.
I'm currently using this structure for about 25 servers on 3 different stages and it works pretty well for me. It has some weaknesses, though:
- Although in my case the advantages overweigh those weaknesses. My biggest fear is accidentally targeting all inventories in the hosts directory, by forgetting to limit to one of the stages. That would be easier to avoid if the inventories would be completely separate.
- Also, I don't like having to list all servers in the inventory again in the
development
or production
groups, because it's redundant and easy to forget.
- I guess if your system grows it could become a little bit confusing to understand from where and in which order variables are loaded.
That being said, it works pretty well for me, so maybe it works well for you, too.