Search code examples
ansibleansible-inventory

How to organize Ansible inventory with datacenter and environment?


If we have 2 data centers, East and West.

Then we have 3 environments DEV, QA, PROD.

Each data center and environment has a their own Consul cluster.

Now I want to reference the Consul cluster from inventory for example:

consul_servers: "{{ groups['consul'] | to_json }}"

How do I organize my inventory and group_vars to only result in the proper Consul cluster hosts for that data center and environment?

An idea I had would be to have an inventory file per data center and environment.

For example:

  • west-dev.ini
  • west-qa.ini
  • west-prod.ini
  • east-dev.ini
  • east-qa.ini
  • east-prod.ini

Which seems reasonable but now how do I address environment only or data center only variables in group_vars? Do I make them children groups?


Solution

  • One of approaches is to use symlinks. Define all your common environment and datacenter variables in separate files and then make all required combinations as subfolders with group_vars/all containing links to appropriate var files.

    Here is example for two datacenters east/west and two environments dev/prod:

    virt_inv/
    ├── dc_east.yml
    ├── dc_west.yml
    ├── east-prod
    │   ├── group_vars
    │   │   └── all
    │   │       ├── dc.yml -> ../../../dc_east.yml
    │   │       └── env.yml -> ../../../env_prod.yml
    │   └── hosts
    ├── env_dev.yml
    ├── env_prod.yml
    └── west-dev
        ├── group_vars
        │   └── all
        │       ├── dc.yml -> ../../../dc_west.yml
        │       └── env.yml -> ../../../env_dev.yml
        └── hosts
    

    I've defined only east-prod and west-dev combinations here, but you can make others in similar way.

    This is demo content:

    $ find virt_inv -type f -print -exec cat {} \;
    virt_inv/dc_east.yml
    datacenter: east-02
    virt_inv/dc_west.yml
    datacenter: west-01
    virt_inv/east-prod/hosts
    [servers]
    host4
    host5
    virt_inv/env_dev.yml
    env: developer
    virt_inv/env_prod.yml
    env: production
    virt_inv/west-dev/hosts
    [servers]
    host1
    host2
    

    And result:

    $ ansible all -i virt_inv/east-prod/hosts -m debug -a 'msg={{datacenter}}-{{env}}'
    host5 | SUCCESS => {
        "msg": "east-02-production"
    }
    host4 | SUCCESS => {
        "msg": "east-02-production"
    }
    
    $ ansible all -i virt_inv/west-dev/hosts -m debug -a 'msg={{datacenter}}-{{env}}'
    host2 | SUCCESS => {
        "msg": "west-01-developer"
    }
    host1 | SUCCESS => {
        "msg": "west-01-developer"
    }