Range function in Ansible?

Can anyone tell me there is a solution I can use to do the same thing a Python range function in Ansible?

Scenario:
Variables I am using

`

access_hostname:

  • name: dariusz_access1
    nodeid_access: 1001
    from_port: ‘04’
    vlanid:

  • 201-204,500-510
    podid: 1
    int_mode: regular
    depl_immediacy: lazy

  • name: dariusz_access2
    nodeid_access: 1001
    from_port: ‘05’
    vlanid:

  • 10,1200
    podid: 1
    int_mode: regular
    depl_immediacy: lazy

`

What I want to achieve is to expand my ‘vlanid’ variable into a list of individual items:
So from this

`

vlanid:

  • 201-204,500-510

`

to something like this, hopefully to the use that info in loops, etc.

`

dariusz_access1:
vlanid:

  • ‘0201’
  • ‘0202’
  • ‘0203’
  • ‘0204’
  • ‘0500’
  • ‘0501’
  • ‘0502’
  • ‘0503’
  • ‘0504’
  • ‘0505’
  • ‘0506’
  • ‘0507’
  • ‘0508’
  • ‘0509’
  • ‘0510’
  • |-
    dariusz_access2:
    vlanid:
  • ‘0010’
  • ‘1200’

`

I also need to get a leading zero ‘0’ added to each vlanid that is not 4 characters in length.

The idea is to avoid having to ask the end user to input each vlanid individually, which could take some time.

I have a python code that can split the ranges for me, with no problem, but if there was an option in Ansible, i would prefer that.

Any guidance would be great.

This works for me:

Scenario:
Variables I am using
    access_hostname:
    - name: dariusz_access1
      nodeid_access: 1001
      from_port: '04'
      vlanid:
        - 201-204,500-510
      podid: 1
      int_mode: regular
      depl_immediacy: lazy

    - name: dariusz_access2
      nodeid_access: 1001
      from_port: '05'
      vlanid:
        - 10,1200
      podid: 1
      int_mode: regular
      depl_immediacy: lazy

What I want to achieve is to expand my 'vlanid' variable into a list of
individual items:

It's possible to create "filter_plugins"
https://docs.ansible.com/ansible/latest/dev_guide/developing_plugins.html#filter-plugins

For example

  > cat filter_plugins/my_filters.py
  def my_range(s):
      interval = str(s).split("-")
      start = int(interval[0])
      if len(interval) > 1:
          stop = int(interval[1]) + 1
      else:
          stop = start + 1
      return [i for i in range(start,stop)]

  def my_split(s):
      return str(s).split(",")

  class FilterModule(object):
      def filters(self):
          return {
              'my_range': my_range,
              'my_split': my_split
              }

Then this task does the job

    - debug:
        msg: "{{ item.vlanid|
                 map('my_split')|flatten|
                 map('my_range')|flatten }}"
      loop: "{{ access_hostname }}"

HTH,

  -vlado

Dick,

thanks for that, other than the strange behavior for anything with the 8 or 9 in it not formatting correctly.

My next issue I can’t resolve is to make this loop through a ‘multi-layer’ dictionary

`

top:
device1:
name: test_name1
vlanid: 2-10,800-810
device2:

name: test_name2
vlanid: 100-120

`

My brain is a bit frazzled right now but I may be looking at this from the wrong angle.

My idea, if possible is to be able to:

  1. User to input ‘name:’ for each device/endpoint (‘device1:’ , ‘device2:’)
  2. User input of ‘vlanid:’ for each specific device/endpoint (‘device1:’ , ‘device2:’)
  3. Ansible to loop through ‘top:’
  4. Use ‘name:’ input
  5. Expand ‘vlanid:’
  6. Build required objects in ACI, on per device/endpoint deployment
    If I can get this work once, I hope to be able to use it on other ACI object creations that are endpoint specific.

I have tried using sub_elements in my past playbook, which works fine, but I have to input each ‘vlanid’ individually into a list

`

top:
device1:
name: test_name1
vlanid:

  • ‘0002’
  • ‘0003’
  • ‘0004’
  • ‘0919’
    device2:
    name: test_name2
    vlanid:
  • ‘0100’
  • ‘0101’
  • ‘0102’
  • ‘0103’
  • ‘0120’

`

Again, any assistance would be great.

Regards