1

I have got the following ansible directory layout

inventories/
   group_vars/     # common variables production and staging
      all
   production/
      hosts              
      group_vars/     
         all      # common to all production 
         groupN.yml
      host_vars/
         all     # common to all production 
         hostnameN.yml

   staging/
      hosts               
      group_vars/     
         all      # common to all staging 
         groupN.yml
      host_vars/
         all     # common to all staging 
         hostnameN.yml      

site.yml
production.yml
staging.yml

roles/
    docker/
         defaults
             # let's assume there defaults contain default_docker_version=a.b.c
         tasks
         ...
    webtier/
  • My questions are:

- How do I override the values in roles/common/default using host specific values?

That is, I want to have the default value of roles specific to the environment.

Example I want production hosts to have docker version of x.y.z and staging have docker_version of a.b.c

I tried adding the variable to the host_vars - but ansible is still not able to find it.


- Is there an improvement on the structure layout that can be made?

RPT
  • 728
  • 1
  • 10
  • 29

2 Answers2

2

You can have the value of docker version in your inventory specific to the environments. Then while calling the role in your playbook you need to pass the value to override the default value within the role.

Below is snippet to call the role from playbook by overriding the value

 roles:
   - { role: roles/common, docker_version: "{{ docker_version }}" }

docker_version is variable which is passed to the role to override the value and its value coming from the inventory of playbook.

refer here for checking the precedence of the variables in ansible, it's very helpful.

Mahattam
  • 5,405
  • 4
  • 23
  • 33
  • It does not seem to work. I tried ` roles: - role: docker docker_version: " {{ docker_version }} " ` I tried but ansible throws - `unhandled exception occurred while templating ' {{ docker_version }}` – RPT Nov 08 '19 at 00:54
2

Q: "How do I override the values in roles/common/default using host-specific values?"

A: For staging put the variables into the directory

inventories/staging/host_vars

For production put the variables into the directory

inventories/production/host_vars

For example

$ cat inventories/production/hosts
prod-001
prod-002
prod-003

$ cat inventories/production/hosts/host_vars/prod-001
docker_version: "x.y.z"

$ cat inventories/production/hosts/host_vars/prod-002
docker_version: "x.y.z"

$ cat inventories/production/hosts/host_vars/prod-003
docker_version: "x.y.z"

It would be more efficient to use group-specific values. For example

$ cat inventories/production/hosts
[group_01]
prod-001
prod-002
prod-003

$ cat inventories/production/group_vars/group_01
docker_version: "x.y.z"

, or all. For example

$ cat inventories/production/group_vars/all
docker_version: "x.y.z"

Q: " Is there an improvement in the structure layout that can be made?"

A: Your case is Alternative Directory Layout with production and staging inventory in separate directories. It's necessary to configure inventory. For example

ansible-playbook -i inventories/staging/hosts site.yml

In this case, the inventory variables in the directories staging/hosts/host_vars and staging/hosts/group_vars are used. It's possible to test it

ansible-inventory -i inventories/staging/hosts --list

There are other options rather than improvements depending on your use-cases.


Notes

  • inventories/group_vars/all is useless
  • inventories/production/host_vars/all is useless (staging the same)
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
  • Thanks Vladimir. Why is inventories/group_vars/all not valid? If i wanted common properties between production and staging - how would i achieve it? – RPT Nov 08 '19 at 09:47
  • What hosts would use inventories/group_vars/all? Why do you separate inventories when you want common properties? – Vladimir Botka Nov 08 '19 at 09:56
  • There is one specific property that both production and staging hosts share. And I was hoping to achieve it someway – RPT Nov 08 '19 at 09:57
  • At what preference level would you like to share it? Defaults <-> Extra vars? For example, use [ansible-pull](https://docs.ansible.com/ansible/latest/cli/ansible-pull.html#ansible-pull) at the beginning of a playbook triggered at remote and you can build any architecture you can imagine if you want to. – Vladimir Botka Nov 08 '19 at 10:05
  • share as defaults – RPT Nov 08 '19 at 10:06
  • Share defaults in the roles. It's not productive. Such a discussions should be moved to chat. I quit here. – Vladimir Botka Nov 08 '19 at 10:08
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/202042/discussion-between-rpt-and-vladimir-botka). – RPT Nov 08 '19 at 10:10
  • One last query - I've got vault file under inventory/staging/group_vars. I am trying to access the vault secret from inventory/staging/group_vars/all.yml but it throws undefined. Is it related to directory structure? Both those files are under the same directory inventory/staging/group_vars – RPT Nov 08 '19 at 10:13
  • See https://stackoverflow.com/questions/55048340/using-vault-in-playbooks/ – Vladimir Botka Nov 08 '19 at 10:16
  • that link does not seem to answer my query – RPT Nov 08 '19 at 10:20