Megakoresh
Megakoresh

Reputation: 824

Ansible - check variable type

Apparently, according to several hours of searching nobody has encountered this use-case:

Its simple - I would like to execute some ansible logic depending on variable type. Basically equivalent of e.g. instanceof(dict, var_name) but in Ansible:

- name: test
  debug:
    msg: "{{ instanceof(var_name, dict) | ternary('is a dictionary', 'is something else') }}"

Is there any way this can be done?

Upvotes: 18

Views: 42530

Answers (3)

Vladimir Botka
Vladimir Botka

Reputation: 68144

Q: "Execute some ansible logic depending on the variable type."

A: The tests including mapping work as expected. For example, the tasks below

    - set_fact:
        myvar:
          key1: value1
    - debug:
        msg: "{{ (myvar is mapping)|
                 ternary('is a dictionary', 'is something else') }}"

give

    msg: is a dictionary

Q: "Ansible - check variable type"

A: An option would be to discover the data type and dynamically include_tasks. For example, the tasks below

shell> cat tasks-int
- debug:
    msg: Processing integer {{ item }}

shell> cat tasks-str
- debug:
    msg: Processing string {{ item }}

shell> cat tasks-list
- debug:
    msg: Processing list {{ item }}

shell> cat tasks-dict
- debug:
    msg: Processing dictionary {{ item }}

with this playbook

- hosts: localhost
  vars:
    test:
    - 123
    - '123'
    - [a,b,c]
    - {key1: value1}
  tasks:
    - include_tasks: "tasks-{{ item|type_debug }}"
      loop: "{{ test }}"

give (abridged)

  msg: Processing integer 123

  msg: Processing string 123

  msg: Processing list ['a', 'b', 'c']

  msg: 'Processing dictionary {''key1'': ''value1''}'

If you want to simulate the switch statement create a dictionary

  case:
    int: tasks-int
    str: tasks-str
    list: tasks-list
    dict: tasks-dict
    default: tasks-default

and use it in the include

    - include_tasks: "{{ case[item|type_debug]|d(case.default) }}"
      loop: "{{ test }}"

Upvotes: 15

musicformellons
musicformellons

Reputation: 13413

Since Ansible version 2.3 there is type_debug:

- name: test
  debug:
        msg: "{{ (( var_name | type_debug) == 'dict') | ternary('is a dictionary', 'is something else') }}"

Note that the docs state a preference for 'type tests'.

Upvotes: 12

crock
crock

Reputation: 461

Older question, but you can do this easily with a Python custom filter plugin. Granted it would give you Python specific types, but that may be fine for your use case.

This could work. It just needs to be placed in a folder named filter_plugins alongside your playbook or role.

import sys

if sys.version_info[0] < 3:
    raise Exception("Must be using Python 3")

def get_type(var, **kwargs):
    return type(var)

class FilterModule(object):
    def filters(self):
        return {
            "get_type": get_type
        }

Then in your playbook:

- name: test
  debug:
    msg: "{{ var_name | get_type }}"

Upvotes: 1

Related Questions