Host_vars not working as expected

Hi, I’m very new to Ansible and I’m sure this is me being stupid, but I’m struggling to get host_vars and group_vars working.

I’m trying to configure a few Aruba switches, and obviously some settings are group or host specific, so I want to define them in group_vars and host_vars.

As an example, this works perfectly in my playbook -

  • file = configswitches.yml
- hosts: core
  collections:
    - arubanetworks.aoscx

  tasks:
    - name: VSX configuration 
      aoscx_vsx:
        isl_port: lag99
        keepalive_peer_ip: 10.0.0.2
        keepalive_src_ip:  10.0.0.1
        system_mac: 00:FF:11:EE:22:DD

But if I move the IPs and MAC to the host_vars file then they are ignored -

  • file = host_vars/core01.yml
---
      aoscx_vsx:
        keepalive_peer_ip: 10.0.0.2
        keepalive_src_ip:  10.0.0.1
        system_mac: 00:FF:11:EE:22:DD
  • file = hosts.yml
---
core:
 hosts:
  core01:
   ansible_host: 10.1.1.227
  core02:
   ansible_host: 10.1.1.228

Can anyone please point me in the right direction?

Thanks!

Mike

Once the variables are in host_vars/group_vars, they need to still be included for the specific tasks.

  tasks:
    - name: VSX configuration 
      aoscx_vsx:
        keepalive_peer_ip: "{{ aoscx_vsx.keepalive_peer_ip }}"
        ...

If you’re trying to reduce some repetitive option passing, you might be interested in using module_defaults, which can be set on a play or block.

- hosts: core
  module_defaults:
    aoscx_vsx: "{{ aoscx_vsx }}"  # variable can be defined in host_vars
  tasks:
    aoscx_vsx:
      # Add individual arguments here to override or add to the defaults
2 Likes

Thanks Shertel, that’s awesome!

I needed the fully qualified name for the module_defaults in the playbook -

  module_defaults:
    arubanetworks.aoscx.aoscx_vsx: "{{ aoscx_vsx }}"  # variable can be defined in host_vars

My only issue now is that I have tried to move the isl_port to group_vars and leave the others in host_vars and it appears to be ignoring the group_vars/core.yml file.

This works -

cat host_vars/core01.yml
---
      aoscx_vsx:
        isl_port: lag99
        device_role: primary
        keepalive_peer_ip: 10.0.0.2
        keepalive_src_ip:  10.0.0.1
        system_mac: 00:FF:11:EE:22:DD

but this doesn’t -

cat host_vars/core01.yml
---
      aoscx_vsx:
        device_role: primary
        keepalive_peer_ip: 10.0.0.2
        keepalive_src_ip:  10.0.0.1
        system_mac: 00:FF:11:EE:22:DD

cat group_vars/core.yml
---
      aoscx_vsx:
        isl_port: lag99

Hello @msmith

The host_vars has higher precedence than the group_vars.

https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#understanding-variable-precedence

So, the variable aoscx_vsx in group_vars is ignored.

How about using flatten variable definition as follows?

cat host_vars/core01.yml

---
device_role: primary
keepalive_peer_ip: 10.0.0.2
keepalive_src_ip: 10.0.0.1
system_mac: 00:FF:11:EE:22:DD

cat group_vars/core.yml

---
isl_port: lag99
3 Likes

Hi, let me show you an alternative approach; using ansible.builtin.combine filter.

Define both group_vars and host_vars with different names, and define new combined variable in host_vars:

# group_vars/core.yml
---
_group_aoscx_vsx:
  isl_port: lag99
# host_vars/core01.yml
---
_host_aoscx_vsx:
  device_role: primary
  keepalive_peer_ip: 10.0.0.2
  keepalive_src_ip:  10.0.0.1
  system_mac: 00:FF:11:EE:22:DD

aoscx_vsx: "{{ _group_aoscx_vsx | ansible.builtin.combine(_host_aoscx_vsx, recursive=true) }}"

Now we can use aoscx_vsx that have complete values from group_vars and host_vars:

  module_defaults:
    arubanetworks.aoscx.aoscx_vsx: "{{ aoscx_vsx }}"
4 Likes

Thanks everyone, you’ve really helped me out! :smiley:

2 Likes

Hi all, I figured out another way to do this by just using different variable names and then passing them back through, eg for ‘aoscx_vsx.keepalive_peer_ip’ I just create a new var at the most specific level in the group_vars or host_vars file and then map it in the more general vars file. I think this is what akira suggested with flattened variables, but I was too much of a noob to understand that a few weeks ago!

host_vars/core01.yml
        ka_peer_ip: 10.0.0.2
        ka_src_ip:  10.0.0.1

host_vars/core02.yml
        ka_peer_ip:  10.0.0.1
        ka_src_ip:   10.0.0.2

group_vars/switches.yml
   aoscx_vsx:
        isl_port: lag99
        keepalive_peer_ip: "{{ ka_peer_ip }}"
        keepalive_src_ip:  "{{ ka_src_ip }}"
        system_mac: 00:FF:11:EE:22:DD

Thanks again everyone for your help, I’m learning :slight_smile:

I do, however, have a new question on the same subject.

This time it’s for Dell OS10 switches rather than Aruba and I’m configuring VLANs and ports as shown below. I define ‘nicprefix’ so I can change this on different switches, in this case the servers all have their OCP NICs connected to one switch and their PCI NICs connected to another, so I set ‘nicprefix: PCI’ on the second switch. So the snippet below works perfectly to create a couple of VLANs and set the appropriate interfaces to be tagged -

host_vars/labsw1.yml
	nicprefix: OCP
	portgroup01range: 1/1/1-1/1/8
	portgroup01desc: "{{ nicprefix }}1-VM-Mgmt-vMotion"
	#
	os10_vlan:
	  # VM Mgmt
	  vlan 50:
		vlan-name: V0050-ESXi
		state: present
		tagged_members:
		  - port: range ethernet {{ portgroup01range }},{{ portgroup09range }}
			desc: V0050-ESXi
			state: present
			access_vlan: "false"
	  # VM vMotion
	  vlan "{{vlan-vMotion}}" :
		state: present
		tagged_members:
		  - port: range ethernet {{ portgroup01range }}
			desc: V0203-vMotion
			state: present
			access_vlan: "false"

# Dell S4148 switch -
labsw1# show vlan
Codes: * - Default VLAN, M - Management VLAN, R - Remote Port Mirroring VLANs,
       @ - Attached to Virtual Network, P - Primary, C - Community, I - Isolated,
       S - VLAN-Stack VLAN
Q: A - Access (Untagged), T - Tagged
    NUM    Status    Description                     Q Ports
    50     Inactive                                  T Eth1/1/1-1/1/10
    203    Inactive                                  T Eth1/1/1-1/1/8

But when I come to set the interface descriptions the yml below does not work and I get the error shown below -

host_vars/labsw1.yml
	#
	os10_interface:
	  range ethernet "{{ portgroup01range }}":
		desc: "{{ portgroup01desc }}"


	TASK [dellemc.os10.os10_interface : Provisioning interface configuration for os10] ********************************************************************************************
	fatal: [labsw1]: FAILED! => {
		"changed": false,
		"command": "interface range ethernet\"{{",
		"rc": -32603
	}

	MSG:

	interface range "ethernet{{
	% Error: Illegal parameter.
	labsw1(conf-range-eth1/1/28-1/1/30)#

but this works fine -

	os10_interface:
	  range ethernet 1/1/1-1/1/8:
		desc: "{{ portgroup01desc }}"

I get the same if I try to replace VLAN numbers with vars -

	vlan_vMotion: 203
	os10_vlan:
	  # VM vMotion
	  vlan "{{vlan_vMotion}}" :
		state: present
		tagged_members:
		  - port: range ethernet {{ portgroup01range }}
			desc: V0203-vMotion
			state: present
			access_vlan: "false"


	TASK [dellemc.os10.os10_vlan : Provisioning VLAN configuration for os10] ******************************************************************************************************
	fatal: [labsw1]: FAILED! => {
		"changed": false,
		"command": "interface vlan\"{{",
		"rc": -32603
	}

	MSG:

	interface vlan"{{
	% Error: Illegal parameter.
	labsw1(conf-if-po-47)#

Does anyone have any ideas?

Thanks,

Mike

See this rather long discussion.