If you are managing your inventory as a static file, then you can define variables in the inventory, either for a specific managed node or for a group of managed nodes.
However, this is not the best practice.
As your environment grows in both size and variety, the inventory file becomes large and difficult to read.
A better approach is to move variable definitions from the inventory file into separate variable files.
Assigning Variables to Inventory Groups
You can create a subdirectory named group_vars in the same directory as your Ansible project.
In the group_vars subdirectory, create a file for each group in your inventory and then add variables specific to that group of managed nodes:
[user@host project]$ tree -F group_vars/
group_vars/
├── arista.yml
├── ios.yml
└── junos.yml
The above organizational structure makes it easier to locate configuration variables for any of the arista, ios, or junos inventory groups.
That structure is sufficient when each inventory group does not contain too many variable definitions.
As playbook complexity increases, however, even these files can become long and difficult to understand.
An even better approach for large, diverse environments is to create subdirectories for each inventory group of managed nodes under the group_vars subdirectory, such as the groups_vars/ios/ subdirectory, in your project directory.
Ansible parses any YAML or JSON files in these subdirectories and associates the variables with an inventory group based on the parent directory.
For example, you might initially define the ansible_network_os and ansible_connection variables for the ios inventory group in the inventory file:
[ios:vars]
ansible_network_os = cisco.ios.ios
ansible_connection = ansible.netcommon.network_cli
Instead of defining those variables in your inventory file, create a YAML file in the group_vars/ios path in your project directory and the ansible_network_os and ansible_connection variables in the new file:
ansible_network_os: cisco.ios.ios
ansible_connection: ansible.netcommon.network_cli
If you use this organizational structure for variables, then place group variables with a common theme into the same file, and use a file name that indicates that common theme.
A project organized according to this convention might appear as follows:
[user@host project]$ tree -F group_vars/
group_vars/
├── all/
│ └── common.yml
├── arista/
│ ├── acl.yml
│ ├── connection.yml
│ └── vlan.yml
├── ios/
│ ├── acl.yml
│ ├── connection.yml
│ ├── security.yml
| └── vlan.yml
└── junos/
├── acl.yml
├── connection.yml
├── snmp.yml
└── vlan.yml
With this organizational structure for a project, you can quickly see the variables that are defined for each group of managed nodes.
Ansible merges all the variables present in files in directories under the group_vars directory with the rest of the variables.
Separating variables into files grouped by functionality makes the project easier to understand and maintain.
Assigning Variables to Inventory Hosts
Likewise with inventory groups, you can create a subdirectory named host_vars in your Ansible project directory.
Then, create a file named after an inventory managed node with the variable definitions for that managed node.
Variables defined for a managed node have a higher precedence than variables defined for the managed node's inventory group.
The group_vars and host_vars subdirectories can exist not only in your project directory, which is where your playbook is located, but in the directory where your inventory file is located.
These two locations might not be the same directory.
For the group_vars and host_vars subdirectories relative to the inventory, the following is true:
If you have group_vars and host_vars subdirectories in the same directory as your playbook, then Ansible automatically includes those variables for managed nodes and groups of managed nodes.
If you use a flat inventory file in a directory other than the one the playbook is in, then Ansible also automatically includes the group_vars and host_vars directories in the inventory file directory.
If you use an inventory directory in your project directory, and that inventory file contains multiple inventory files, then Ansible includes the group_vars and host_vars subdirectories of your inventory directory.
Important
The variables that Ansible includes from the playbook directory override the variables from the inventory directory if there is a conflict.