16. Multiple Environments

Multiple Environments e.g test & prod

16.1. Using separate inventories

  • use different inventory files/folders for your environments!
  • you can specify the path to a inventory file with the option -i for ansible and ansible-playbook
  • to create a multistage inventory, you’ve to work with children
  • create a parent group for your environment and add all other host groups, so you can define variables for the whole environment (for example: use different sshd settings for test and prod)
# file: production
[web]
web1.pascal.lab

[db]
db.pascal.lab

[production:children]
web
db
# file: test
[web]
web2.pascal.lab

[db]
db2.pascal.lab

[test:children]
web
db

Now we’ve got these groups:

  • web
  • db
  • production
  • test
# list all hosts of a inventory
ansible -i test all --list-hosts

I can use the defined host groups with ansible or ansible-playbook in combination with the separted inventory files.

# run ping on the inventory production
ansible -i production -m ping all

db.pascal.lab | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
web1.pascal.lab | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Hint

The defined groups are now important for setting different variable values per environment.

Hint

Set the test inventory as your default inventory in ansible.cfg => inventory = test. So it’s only needed to use -i for your prod environment.

16.2. Settings variables for environments

  • define environment variables in your created parent group production and test
  • define variables that can be used on all hosts
  • define variables for db or web
# file: group_vars/all.yml   <- value for all servers
db_host: db.pascal.lab
# file: group_vars/production.yml   <- only on production
db_password: myProdPW
prod_var: 'this is a production env variable'
# file: group_vars/test.yml   <- only on test
test_var: 'this is a test env variable'
db_password: testPW
# file: group_vars/db.yml     <- equal for test & prod, but only for db
db_setting: limit5
# file: group_vars/web.yml    <- equal for test & prod, but only for web
web_port: 8080
  • tree structure
├── group_vars
│   ├── all.yml
│   ├── db.yml
│   ├── production.yml
│   ├── test.yml
│   └── web.yml
├── production
├── test

Hint

Ansible will search for the group_vars and host_vars in the same directory like the inventory file.

Important

There are many ways to define the directory structure.

Check out the variables:

# get the prod variables
ansible -m debug -a "msg={{ prod_var }}" -i production all

# will fail
ansible -m debug -a "msg={{ test_var }}" -i production all

# will fail on the db host
ansible -m debug -a "msg={{ web_port }}" -i test all

Hint

The structure depends on the amount of servers and needed groups. Sometimes it’s better to use a dynamic invetory for create the whole structure for the groups.

16.3. Define a new playbook

# plays/debug.yml
---
- hosts: all

  tasks:
  - name: debug some variables
    debug:
      msg: '{{ prod_var }}'


ansible-playbook playbooks/debug.yml -i test
ansible-playbook playbooks/debug.yml -i production