Alexey Bakulin
Alexey Bakulin

Reputation: 1369

How to Make Ansible variable mandatory

I'm looking for the way how to make Ansible to analyze playbooks for required and mandatory variables before run playbook's execution like:

- name: create remote app directory hierarchy
  file:
    path: "/opt/{{ app_name | required }}/"
    state: directory
    owner: "{{ app_user | required }}"
    group: "{{ app_user_group | required }}"
  ...

and rise error message if variable is undefined, like:

please set "app_name" variable before run (file XXX/main.yml:99)

Upvotes: 37

Views: 28174

Answers (6)

papiro
papiro

Reputation: 2365

If using a role-based architecture, check out the docs on role argument validation.

It allows for you to specify a roles/<role_name>/meta/argument_specs.yml file which allows you to make variables required. Here is an example taken from their sample specification:

# roles/myapp/meta/argument_specs.yml
---
argument_specs:
  # roles/myapp/tasks/main.yml entry point
  main:
    short_description: The main entry point for the myapp role.
    options:
      myapp_int:
        type: "int"
        required: false
        default: 42
        description: "The integer value, defaulting to 42."

      myapp_str:
        type: "str"
        required: true
        description: "The string value"

  # roles/myapp/tasks/alternate.yml entry point
  alternate:
    short_description: The alternate entry point for the myapp role.
    options:
      myapp_int:
        type: "int"
        required: false
        default: 1024
        description: "The integer value, defaulting to 1024."

Upvotes: 9

Lev
Lev

Reputation: 211

Usually inside a role I perform checking input variables like in the example:

- name: "Verify that required string variables are defined"
  ansible.builtin.assert:
    that: 
      - ahs_var is defined
      - ahs_var | length > 0
      - ahs_var != None
    fail_msg: "{{ ahs_var }} needs to be set for the role to work"
    success_msg: "Required variable {{ ahs_var }} is defined"
  loop_control:
    loop_var: ahs_var
  with_items:
    - ahs_item1
    - ahs_item2
    - ahs_item3

by the way there are some tricks:

  1. Don't use global variables inside a role.
  2. If you want use global variables define the role specific variable & set global variable to it i.e. some_role_name__db_port: "{{ db_port | default(5432) }}".
  3. It makes sense to use role name as the prefix for variable. it helps to understand the source inventory easier.
  4. Your role might be looped some how, so it makes sense to override the default item.

Upvotes: 21

Arbab Nazar
Arbab Nazar

Reputation: 23791

You can use this:

{{ variable | mandatory }}

Upvotes: 34

Ren&#233; Pijl
Ren&#233; Pijl

Reputation: 4738

One way to check if mandatory variables are defined is:

- fail:
    msg: "Variable '{{ item }}' is not defined"
  when: item not in vars
  with_items:
    - app_nam
    - var2

Upvotes: 14

Alexey Vazhnov
Alexey Vazhnov

Reputation: 1369

As Arbab Nazar mentioned, you can use {{ variable | mandatory }} (see Forcing variables to be defined) inside Ansible task.

But I think it looks nicer to add this as first task, it checks is app_name, app_user and app_user_group exist:

- name: 'Check mandatory variables are defined'
  assert:
    that:
      - app_name is defined
      - app_user is defined
      - app_user_group is defined

Upvotes: 61

mvk_il
mvk_il

Reputation: 960

There are 2 approaches:

  1. Specify |mandatory filter

    1. Beware dictionaries - if a key with mandatory value fails to eval, you may have a hard time uh understanding which is it.
  2. Use assert module

Upvotes: 3

Related Questions