Ansible variables acess in host_vars/file

Currently have a playbook that is creating template configs for our cisco switches. Most generic variables are kept in group_vars and we're currently using individual host_var file per switch to store variables unique to each sw e.g hostname, IP address etc..
Our host_var structure is as follows:
host_vars/tor01.a01
host_vars/tor02.a01

Within the INI inventory we reference each switch as follows:
[cisco_tor]
tor01.a01
tor02.a01

Is it possible to create a single file instead in host_vars that contains a dict of all switches and access those variables in ansible play instead?
host_vars/tor_switches

Similiar to example looping over hashes given on Ansible documentaion?
Ive tried to do this by including with_dict: tor_switches in playbook but it errors during play run with "with_dict must contain dict"

Should this be referenced in role/task/main.yml instead?

Amanda

You can use inventory groups as lists to iterate over

  • debug:
    with_items: groups [‘cisco_switches’

Brian
Can you elaborate please? Im relatively new to using Ansible so not sure where the with_items should be placed? Does this go into playbook or task YAML file within role?

My playbook is very simple and looks like this currently my inventory file is underneath.

[vagrant@dev4 RTR-TEMPLATE]$ more site.yml

ansible has 2 iterators, the main one is the play, it iterates over hosts

- hosts: routers

iterates over every host in the routers group

the second iterator is with_ which acts at task level

- debug: msg={{item}}
  with_items:
     - 1
     - 2

this will iterate over 1 and 2 for every host in the play.

sometimes you want to target hosts from a different group from the one
you are targetting in play, most common examples is load balancers

- hosts: webnodes
  tasks:
      - shell: disable node {{inventory_hostname}}
        delegate_to: "{{item}}"
        with_items: groups['loadbalancers']

As to the specifics on how this fits with your setup that requries not
as much the structure of your files but what is your intent, what you
want to accomplish.

Brian so the basic idea is using ansible to build out switch templates leveraging variables that are specific to each switch device.

For the purpose of this test I’ve made the template very simple I need to populate the variable {{ from inventory_hostname }} and {{ip}} into the template below for each switch.

The {{ inventory hostname }} variable is retrieved from iterating over the hosts:routers in the play as you mention above

The {{ip}} variable is retrieved from host_vars/tor01.a01.yml and host_vars/tor01.a02.yml file

See example below for one of these switches. Again this is being kept very simple for demo purposes.

[vagrant@dev4 host_vars]$ more tor01.a01.yml
hostname: tor01.a01
ip : 10.1.1.1

[vagrant@dev4 host_vars]$

The basic template is below:

[vagrant@dev4 templates]$ more base.j2
!
hostname {{ inventory_hostname}}
!
!
interface GigabitEthernet0/0
ip access-group INTERNET in
ip address {{ ip }}
no ip redirects
no ip proxy-arp
ip nat outside
ip virtual-reassembly
duplex auto
speed auto
no cdp enable
!

[vagrant@dev4 templates]$

When I run the playbook it combines the variables and the templates to create a populated file for each switch that can be uploaded to the device.

[vagrant@dev4 RTR-TEMPLATE]$ ansible-playbook -i test site.yml

PLAY [Generate router configuration files] ************************************

TASK: [router | Generate configuration files] *********************************
changed: [tor01.a02]
changed: [tor01.a01]

PLAY RECAP ********************************************************************
tor01.a01 : ok=1 changed=1 unreachable=0 failed=0
tor01.a02 : ok=1 changed=1 unreachable=0 failed=0

This is fine as currently I only have two devices to template tor01.a01 and tor01.a02 but if this was several hundred devices I’d prefer to keep variables in single YAML file below and loop over this to extract the {{ip}} for each hostname?

Is this currently possible with Ansible?
I’ve tried to do this but can’t seem to access the variable {{ip}} within tor_switches.yml and not sure how I load variables from this file into Ansible for use in playbook?

[vagrant@dev4 RTR-TEMPLATE]$ cat host_vars/tor_switches.yml

If I understand correctly, you want:

1) One file that holds variable data for several related hosts.
2) In a play, you will create one file from a template on each of the
hosts in a group
3) The template will contain variables specific to the host that were
defined in the variable data file mentioned earlier.

I think a solution would look something like this:

(1) If the group you're working with is named "cisco_tor", create a
group_var file for cisco_tor. Do this by creating a group_vars/
directory next to your host_vars/ directory.
Then adding a "cisco_tor" file in there.

Put your data structure into the file. For instance, you can just" mv
host_vars/tor_switches.yml group_vars/cisco_tor"

(2) Your playbook will look something like this:

- hosts: cisco_tor
  gather_facts: false
  tasks:
    - name: Create config file
      template:
        src: router.j2
        dest: /etc/router.cfg

(3) The template looks something like this:

host={{ inventory_hostname }}
ip={{ hostname[inventory_hostname].ip }}

-Toshio

Hey Toshio,
Thanks very much that is exactly what I need see below. I’m able to access the dict within group_vars/cisco_tor.yml and extract variable {{ tor_switch[inventory_hostname].ip }} as per instructions you provided.
End result is 3 switch device configs. Will port this back to my main Ansible tempting engine but looks like this is a working solution to my problems

Amanda

interface GigabitEthernet0/0
ip address {{ tor_switch[inventory_hostname].ip }}
ip access-group INTERNET in
no ip redirects
no ip proxy-arp
ip nat outside
ip virtual-reassembly
duplex auto
speed auto
no cdp enable

[vagrant@dev4 RTR-TEMPLATE]$ more group_vars/cisco_tor.yml