Assign variables as in Ansible

Is there a similar way to assign variables in nornir as Ansible does? For example, in Ansible you can do this:

neighbors:
  - ip: "{{ ibgp_peer_ip }}"
    description: "{{ ibgp_peer }}"

and when you run the playbook the “ip” and “description” vars are populated with the value of the other vars.

What problem are you trying to solve?

What I want to solve is that, I can have similar definitions like below for a group of devices in a single yaml file and if only the neighbors portion would be different then I can create only the needed variables for each host that I will run the task.

bgp:
  - name: iBGP
    description: iBGP
    type: internal
    import:
      - REJECT
    export:
      - out-accept-dc-nets-communities
      - REJECT
    neighbors:
      - ip: "{{ ibgp_peer_ip }}"
        description: "{{ ibgp_peer }}"

Maybe, my approach is very ansible dependent, but any recommendations on how to achieve this with nornir is more than welcome.

It is very ansible-ish and I am not sure you will get any benefit by doing this in Nornir. Technically you can use template_file task to achieve this (though you would refer to variables using host, e.g. host.ibgp_peer_ip)
How are you using this data? Are you planning to build a config from those variables? In that case just define a jinja template with your original variables.

Yes, I want to build a configuration out of those variables.

I’ll see if I can achieve something similar with the template_file task. Thanks for your replies.

Hey @ebane, are you already pre-defining these variables? I have something similar, although I am not templating the variable files. For example, I have individual host files that contain data for each device (e.g. bgp neighbors, IP addresses, etc). Then, I have a number of tasks that generate the part of the config.

---
bgp:
  groups:
    ipfabric:
      type: external
      import:
        - "leaf-ipfabric-in"
      export:
        - "leaf-ipfabric-out"
      bfd:
        min_interval: 350
        multiplier: 3
      neighbors:
      - peer_address: 192.168.1.10
        description: "to spine 1"
        peer_as: 65100
      - peer_address: 192.168.1.11
        description: "to spine 2"
        peer_as: 65101

Then call template_file to generate the config snippet.

def configure_bgp(task):
    task.run(name = "Load Data", task = load_data)

    try:
        bgp_config = task.run(name = "Generate Template", task = template_file,
                              path = f"templates/{task.host.platform}/",
                              template = "bgp.j2",
                              data = task.host.data)

        task.run(name = "NAPALM Configure", task = networking.napalm_configure,
                 configuration = bgp_config.result, replace = False)
    except:
        print ("No bgp data to load. Ignoring...")

I think you might be adding an unnecessary step if you are templating files just to populate variables, unless it’s from some sort of dynamic inventory data collection. Like, you have your nornir inventory to connect to devices, but you want gather facts from the devices and populate them as variables. That would make sense then!

hey @z3nbr3w, I’m doing the same actually. I also have individual files for each host, but I wanted to use a single file since most of the variables are going to be the same, with the exception of the peer IPs.
Anyways, I’m still in the exploring phase and trying to learn more about Nornir. So, for the time being I’m going to keep it like this.

Thanks for your comment.

use defaults for the variables shared across different devices and put host specific vars under the host