Ansible — Inheritance of Variables

In Ansible there are severall ways to pass variables to a Role, Task or a playbook.

I personally was very confused with this, when building my infrastructure.
If every single uses the same variables I could have put everything in a inventorie file. But after building some servers for infrastructure which all should use individual ntp or dns servers. It started to mess up.

Even today there are some quick runs from just a playbook where I for example need a specific log-file to be backed up.
Then I use the playbook file itself to specificy the path to the logfile I need.

I will try to explain where you’ve to put your variables to get them where you need them.

Which places are there?

  • Inventories
  • Group variables
  • Host variables
  • Playbooks
  • Variables in Roles

In the following I will describe those places and how the inharitance goes along…

1. Inventories

Ansible is learning its variables from the :vars section.

# ------------------------------------------------------
hostname.domain.local ansible_host=<ip of your host>
ansible_port=<ssh Port>
ansible_user=<user to connect via ssh>
ansible_become_method=<su or sudo>
ansible_become_user=<user has the needed priviliges>

2. Extended Inventories Group-/Hostvars

2.1 Groupwise

I like to use group directories which contain a file which must be named as the group itself. So for example if you have a group Servergroup you should name your group-var-file Servergroup.yml .

├── group_vars
│ ├── all
│ │ ├── default.yml
│ ├── Servergroup
│ │ └── Servergroup.yml

The Servergroup.yml then contains all variables you need for your group Servergroup.

---# Network Setup
domain_name: domain.local
# Docker vars
docker_installed: true

2.2 Hostwise

You should use this as less as possible. This also will override your groupvars.
I use this for example to provision my infrastructure hosts which have individual DNS or NTP endpoints to use.

├── group_vars
│ ├── [...]
├── host_vars
│ ├── myinfrahost_one.yml
│ ├── myinfrahost_two.yml

The file should be named like your actuall host in your inventorie.
For example:cat host_vars/myinfrahost_one.yml


3. Playbooks

I use playbook variables if I want to do a quick run on one or more hosts.
Everything else which should remain on your hosts longer then one ansible_run should be stored in group_varsor host_vars .

- hosts: hostname.domain.local

4. Roles

In tasks you can easily use jinja2 templating language (see below) to refer to either in the defaults/main.yml or vars/main.yml .

$ cat tasks/main.yml
- name: Install Package
name: apt-transport-https
state: "{{ package_state }}"

4.1 Default Vars

Usually you use the defaults/* dir which really should just contain default variables.
For example, my package should per default be installed.

$ cat defaults/main.yml
package_state: present

4.2. Vars (constants)

The vars/* is more likely for lets say constants which will override any pre-defined-values.
This will always remove or not even install the package.

$ cat vars/main.yml
package_state: absent

5. Inheritance summary


  • Servergroup:vars will be overritten by group_vars , host_vars and playbooks

Extended Inventories group_vars :

  • will be overritten by host_vars and Playbooks

Extended Inventories host_vars :

  • Overritten by Playbooks


  • Just by constants from Roles


  • vars/*.yml will override every pre-defined variable
  • defaults/*.yml will be overritten by basically everything


Working as a IT-Operations engineer at NeXenio, a spin-off by Hasso-Plattner-Institute for products around a digitial workspace.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store