How to create custom type (or validator) in ansible role argument specification?

110 views Asked by At

I want to write role about network configuration, in my role many variable exist that only accept IP value. so I want to check this constraint in role argument specification. but I do not know how to do it?

As I found, this specification accept only few types such as below

str
list
dict
bool
int
float
path
raw
jsonarg
json
bytes
bits

And I do not know, how to add new custom type (IP type) to above list?

Or maybe role argument specification can accept some regex validator, but I do not find anything about that. and after I read specification format, I think ansible does not provide any way to add argument regex validator, but I want to sure does not exist anyway.

What is standard way to role argument validation?

2

There are 2 answers

0
Alexander Pletnev On

Roles parameters specification is a relatively new thing in Ansible, as per the documentation it was introduced in 2.11.

A common way to validate the parameters before that (or if you have more complex validation rules, like in your case) was to define a separate task file with assertions and include it as the first task to the role's entrypoint main.yml:

---
# validate.yml
- name: Validation of role parameters
  assert:
    that:
      - ip_var is defined and ip_var is regex(ip_regex) # ip_regex is defined in role's vars.yml for sanity
      - # other checks
---
# main.yml
- name: Validate the parameters
  include_tasks: validate.yml

# other tasks
2
Vladimir Botka On

Q: "Many variables only accept IP value. Check this constraint."

A: Use the filter ansible.netcommon.ipaddr. For example, to test the validity of three variables ip1, ip2, ip3

    - name: Validation of role parameters
      assert:
        that: "[ip1, ip2, ip3]|map('ansible.netcommon.ipaddr') is all"
        fail_msg: IP address(es) not valid

Either put it into the pre_tasks or into a role.


Example of a complete playbook for testing

- hosts: all

  vars:

    ip1: 10.1.0.1
    ip2: 10.1.0.2
    ip3: 10.1.0.999

  pre_tasks:

    - name: Validation of role parameters
      assert:
        that: "[ip1, ip2, ip3]|map('ansible.netcommon.ipaddr') is all"
        fail_msg: IP address(es) not valid

  # roles:
  #   - net_conf


There are many options for how to test it inside a role. For example, put the declarations into the defaults

shell> cat roles/net_conf/defaults/main.yml
vars_valid: "{{ [vars_ip, vars_str, vars_int] is all }}"
vars_ip: "{{ [ip1, ip2, ip3]|map('ansible.netcommon.ipaddr') is all }}"
vars_str: true  # Test validity of strings
vars_int: true  # Test validity of integers

and test it in main.yml

shell> cat roles/net_conf/tasks/main.yml
- assert:
    that: vars_valid
    fail_msg: Variable(s) not valid.

- debug:
    msg: net_conf is running ...

Example of a complete playbook for testing

- hosts: all

  vars:

    ip1: 10.1.0.1
    ip2: 10.1.0.2
    ip3: 10.1.0.999

  roles:
    - net_conf