Aaron
Aaron

Reputation: 1

How to run playbook across multiple environments with their own group_vars?

My current ansible structure looks something like this:

 - inventory
    - prod
        - prod1
            - hosts.yml
            - group_vars
                - all.yml
        - prod2
            - hosts.yml
            - group_vars
                - all.yml
        - prod3
            - hosts.yml
            - group_vars
                - all.yml
    - nonprod
        - dev
            - hosts.yml
            - group_vars
                - all.yml
        - qa
            - hosts.yml
            - group_vars
                - all.yml
        - uat
            - hosts.yml
            - group_vars
                - all.yml
 - roles
    - main.yml (this isn't accurate just a sample playbook for the question)

I'd like to be able to run something like this: ansible-playbook main.yml -i inventory/prod and have it automatically cycle through the environments (each with distinct group_vars values).

Currently the command will find the hosts in each environment but not the vars which stops the playbook from running, but if I run ansible-playbook main.yml -i inventory/prod/prod1 it runs fine.

Upvotes: 0

Views: 665

Answers (1)

larsks
larsks

Reputation: 311606

I would suggest restructuring your inventory. Ansible looks for the group_vars directory adjacent to your inventory files. If you run with ansible -i inventory ..., it won't find the group_vars file (it will only find it when running e.g. ansible -i inventory/prod/prod1).

Consider a layout like this:

inventory/
├── group_vars
│   ├── prod1.yaml
│   ├── prod2.yaml
│   └── prod3.yaml
└── prod
    ├── prod1.yaml
    ├── prod2.yaml
    └── prod3.yaml

Where each inventory file places hosts into a similarly named hostgroup. E.g., inventory/prod/prod1.yaml contains:

all:
  children:
    prod1:
      hosts:
        prod1-node0:
        prod1-node1:
        prod1-node2:

If we have a variable defined with a different value for each group:

$ grep . inventory/group_vars/*
inventory/group_vars/prod1.yaml:location: datacenter1
inventory/group_vars/prod2.yaml:location: datacenter2
inventory/group_vars/prod3.yaml:location: datacenter3

And a playbook like this:

- hosts: all
  gather_facts: false
  tasks:
    - debug:
        var: location

We can run it against all the hosts (I'm only using two groups here, prod1 and prod2, in order to keep the output shorter):

$ ansible-playbook playbook.yaml -i inventory
TASK [debug] ********************************************************************************************
ok: [prod1-node0] => {
    "location": "datacenter1"
}
ok: [prod1-node1] => {
    "location": "datacenter1"
}
ok: [prod1-node2] => {
    "location": "datacenter1"
}
ok: [prod2-node0] => {
    "location": "datacenter2"
}
ok: [prod2-node1] => {
    "location": "datacenter2"
}
ok: [prod2-node2] => {
    "location": "datacenter2"
}

Or you can run the playbook against a specific group:

$ ansible-playbook playbook.yaml -i inventory -l prod2
TASK [debug] ********************************************************************************************
ok: [prod2-node0] => {
    "location": "datacenter2"
}
ok: [prod2-node1] => {
    "location": "datacenter2"
}
ok: [prod2-node2] => {
    "location": "datacenter2"
}

In each case, hosts will use the values from the appropriate group_vars file based on their hostgroup.

Upvotes: 2

Related Questions