Reputation: 824
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
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
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
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