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?
Through the register keyword you assign a variable. You want to know what variable type it is (e.g., a string, a dictionary or a JSON). You know the data type is not a Boolean.
As per latest Ansible Version 2.5, to check if a variable is defined and depending upon this if you want to run any task, use undefined keyword. tasks: - shell: echo "I've got '{{ foo }}' and am not afraid to use it!" when: foo is defined - fail: msg="Bailing out. this play requires 'bar'" when: bar is undefined.
Creating valid variable names Not all strings are valid Ansible variable names. A variable name can only include letters, numbers, and underscores. Python keywords or playbook keywords are not valid variable names. A variable name cannot begin with a number.
This module allows setting new variables. Variables are set on a host-by-host basis just like facts discovered by the setup module. These variables will be available to subsequent plays during an ansible-playbook run.
In Ansible playbooks, it is often a good practice to test if a variable exists and what is its value. Particularity this helps to avoid different “ VARIABLE IS NOT DEFINED ” errors in Ansible playbooks. In this context there are several useful tests that you can apply using Jinja2 filters in Ansible.
Ansible facts are data related to your remote systems, including operating systems, IP addresses, attached filesystems, and more. You can access this data in the ansible_facts variable.
That’s a bit arbitrary, but you can see how the same role was invoked multiple times. In that example it’s quite likely there was no default for ‘name’ supplied at all. Ansible can yell at you when variables aren’t defined – it’s the default behavior in fact.
vars can be used only when we are statically defining a variable inside the playbook but for dynamic values which are collected runtime we can use set_fact Ansible also allows you to set a fact (effectively the same as defining a new variable) in a task by using the set_fact module.
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 }}"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With