Ansible variables acess in host_vars/file

1,088 views
Skip to first unread message

mandy galligan

unread,
Dec 3, 2014, 4:08:09 AM12/3/14
to ansible...@googlegroups.com
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

Brian Coca

unread,
Dec 4, 2014, 5:31:21 PM12/4/14
to ansible...@googlegroups.com

You can use inventory groups as lists to iterate over

- debug:
   with_items: groups ['cisco_switches'

mandy galligan

unread,
Dec 8, 2014, 2:31:38 PM12/8/14
to ansible...@googlegroups.com
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
---
- name: Generate router configuration files
  hosts: router
  connection: local
  gather_facts: no
  roles:
   - router
[vagrant@dev4 RTR-TEMPLATE]$ more test
[router]
tor01.a01
tor01.a02
[vagrant@dev4 RTR-TEMPLATE]$

my structure currently looks like this 

[vagrant@dev4 ANSIBLE]$ tree RTR-TEMPLATE/
RTR-TEMPLATE/
├── host_vars
│   ├── tor01.a01.yml
│   ├── tor01.a02.yml
│   └── tor_switches.yml
├── roles
│   └── router
│       ├── tasks
│       │   └── main.yml
│       ├── templates
│       │   ├── base.j2
│       │   ├── router-1921.j2
│       │   └── router-881.j2
│       └── vars
├── site.yml
└── test

6 directories, 9 files

Brian Coca

unread,
Dec 8, 2014, 2:39:58 PM12/8/14
to ansible...@googlegroups.com
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 Coca

mandy galligan

unread,
Dec 9, 2014, 1:01:52 PM12/9/14
to ansible...@googlegroups.com
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
---
hostname:
   tor01.a01:
  ip : 10.1.1.1
   tor01.a02:
  ip : 10.1.1.2
[vagrant@dev4 RTR-TEMPLATE]$

Toshio Kuratomi

unread,
Dec 9, 2014, 6:06:49 PM12/9/14
to ansible...@googlegroups.com
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
> --
> You received this message because you are subscribed to the Google Groups
> "Ansible Project" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to ansible-proje...@googlegroups.com.
> To post to this group, send email to ansible...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/ansible-project/302e6fa1-e57e-430d-a591-a09f785382a6%40googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.

Amanda Galligan

unread,
Dec 15, 2014, 6:18:51 AM12/15/14
to ansible...@googlegroups.com
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
---
tor_switch:
  tor01.a01:
     ip: 10.1.1.4
  tor01.a02:
     ip: 10.1.1.5
  tor01.a03:
     ip: 10.1.1.6
[vagrant@dev4 RTR-TEMPLATE]$ more test
[cisco_tor]
tor01.a01
tor01.a02
tor01.a03
[vagrant@dev4 RTR-TEMPLATE]$ ansible-playbook -i test site.yml
 [WARNING]: The version of gmp you have installed has a known issue regarding
timing vulnerabilities when used with pycrypto. If possible, you should update
it (ie. yum update gmp).


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

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

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

[vagrant@dev4 RTR-TEMPLATE]$
[vagrant@dev4 RTR-TEMPLATE]$ ansible-playbook -i test site.yml
You received this message because you are subscribed to a topic in the Google Groups "Ansible Project" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ansible-project/6cedSRpt7kA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ansible-proje...@googlegroups.com.

To post to this group, send email to ansible...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages