Best practices for provisioning multiple interconnecting environments

Hi,

Here is what I’m trying to achieve.
There are several environments (or clusters) that are relatively independent but still have some connections in between. Let’s say I have ‘production’, ‘staging’ and ‘general’ environments.
The last one contains common machines that are supplementary for the first two, say, DNS servers. When I create a box in ‘production’ or ‘staging’ I want to add a DNS record for that box on the DNS server inside ‘general’ environment.

Each environment is described by a standalone inventory file:
env/general/inventory
env/production/inventory
env/staging/inventory

My current approach is that all three inventories contain DNS servers. The ‘general’ environment has them as they need to be provisioned initially. ‘Production’ and ‘staging’ environments include them because the environments need to know the DNS servers in order to work with them (I use ‘delegate_to:’ to connect to a DNS server to add a record).

I would like to avoid having DNS servers in all the inventory files (the group ‘all’ should preferably refer to the hosts of an environment). I would also avoid having a single inventory for all the environments as it complicates the setup. One approach would be to treat the DNS servers as external resources for ‘production’ and ‘staging’ and to have them set up as inventory variables. But the provisioning playbook would need to ssh to a DNS server to add a record and, therefore, may need some additional arguments like ansible_ssh_host or ansible_ssh_user to connect to it. But how do I set up those if I don’t have the DNS server in the inventory? In no way…

I’d like to point out that the issue is not only about DNS servers. In the ‘general’ environment there can be other boxes, for example, a build machine that is used by both ‘production’ and ‘staging’ environments, or a common monitoring server.

So the question is how do you guys deal with similar situations? Does my setup make sense at all? Maybe I’m doing something very strange?

I suggest you have a look at dynamic inventory.

You can mix dynamic inventory with static groups and even use multiple inventory files by using inventory directories - see http://docs.ansible.com/ansible/intro_dynamic_inventory.html#using-inventory-directories-and-multiple-inventory-sources

Hope this helps,

Jon

Thank you! Yes, I know what it is and I actually use something similar.
But one inconvenience is still here for me: when I write ‘hosts: all’ inside a playbook or set variables inside ‘group_vars/all’, I only want to touch the hosts of a standalone environment (‘production’ or ‘staging’). Of course I can ‘invent’ my own group that would only contain hosts I want it to, but then this would interfere with the variables overriding mechanism (the group ‘all’ is a special kind of group and I want it to stay like that).

My first question is whether you expect to be able to pass different credentials (user,pass,sudo pass, etc.) to ‘general’ and ‘production’ (or ‘staging’) when invoking the master playbook.

No, let’s assume I don’t expect that. The access to all the nodes are the same. But it’s not default (I set ansible_ssh_common_args).