Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible - check variable type

Tags:

ansible

jinja2

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?

like image 691
Megakoresh Avatar asked Apr 16 '20 16:04

Megakoresh


People also ask

How do you find the data type of a variable in Ansible?

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.

When Ansible variable is defined?

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.

Which variables are valid in Ansible?

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.

What does Set_fact do in Ansible?

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.

How to test if a variable exists in Ansible?

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.

What are Ansible facts?

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.

Is there a default for ‘name’ in Ansible?

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.

What is the difference between set_fact and VARs in Ansible?

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.


1 Answers

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 }}"
like image 116
Vladimir Botka Avatar answered Sep 17 '22 21:09

Vladimir Botka