Search code examples
ansibleansible-inventory

How do i use pre task module in ansible to validate input parameters?


I want to validate few things before i run my main play in Ansible. For example below command is taking 2 input arguments from the user so I want to validate them before executing the main tasks.

ansible-playbook -i my-inventory my-main.yml --tags=repodownload -e release_version=5.0.0-07 -e target_env=dev/prod/preprod

In the above case, release_version should not be empty and target_env must be these type of values - 5.0.0.34

I want to display a message to user about what is wrong. How do i achieve it?

Any help is appreciated.


Solution

  • If you absolutely need the user to provide the variables, I would first of all use vars_prompt so that the variable value is asked interactively if user forgot to provide them as extra vars. This also makes a good inline documentation.

    Then you can use pre_tasks to validate the input that was provided, either interactively or as an extra var. For validation, I usually use the fail module. The point here is to use run_once: true to force the test to run only once even if there are several hosts in your play.

    Here is an example based on your input. Adapt to your exact needs

    ---
    - name: Prompt and validation demo
      hosts: all
      gather_facts: false
    
      vars:
        _allowed_envs:
          - dev
          - preprod
          - prod
    
      vars_prompt:
    
        - name: release_version
          prompt: "What is the release version ? [w.x.y-z]"
          private: no
    
        - name: target_env
          prompt: "What is the target environment ? [{{ _allowed_envs | join(', ') }}]"
          private: no
    
      pre_tasks:
    
        - name: Make sure version is ok
          fail:
            msg: >-
              Release version is not formatted correctly. Please make sure
              it is of the form w.x.y-zz
          when: not release_version is regex('\d*(\.\d*){2}-\d\d')
          run_once: true
    
        - name: Make sure target_env is allowed
          fail:
            msg: >-
              Environment "{{ target_env }}" is not allowed.
              Please choose a target environment in {{ _allowed_envs | join(', ') }}
          when: not target_env in _allowed_envs
          run_once: true
    
      tasks:
    
        - name: "Dummy task just to have a complete playbook for the example"
          debug:
            msg: "Deploying version {{ release_version }} for environment {{ target_env }} on {{ inventory_hostname }}"
    

    And here are some examples launching the playbook:

    ##########################
    # Fully interactive runs #
    ##########################
    
    $ ansible-playbook -i localhost, playbook.yml 
    What is the release version ? [w.x.y-z]: wrong
    What is the target environment ? [dev, preprod, prod]: prod
    
    PLAY [Prompt and validation demo] ************************************
    
    TASK [Make sure version is ok] ***************************************
    fatal: [localhost]: FAILED! => {"changed": false, "msg": "Release version is not formatted correctly. Please make sure it is of the form w.x.y-zz"}
    
    NO MORE HOSTS LEFT ***************************************************
    
    PLAY RECAP **********************************************************
    localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
    
    
    $ ansible-playbook -i localhost, playbook.yml 
    What is the release version ? [w.x.y-z]: 1.2.3-44
    What is the target environment ? [dev, preprod, prod]: dev
    
    PLAY [Prompt and validation demo] ************************************
    
    TASK [Make sure version is ok] ***************************************
    skipping: [localhost]
    
    TASK [Make sure target_env is allowed] *******************************
    skipping: [localhost]
    
    TASK [Dummy task just to have a complete playbook for the example] ***
    ok: [localhost] => {
        "msg": "Deploying version 1.2.3-44 for environment dev on localhost"
    }
    
    PLAY RECAP ***********************************************************
    localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0
    
    
    ###############
    # Hybrid run #
    ###############
    
    $ ansible-playbook -i localhost, playbook.yml -e target_env=prod
    What is the release version ? [w.x.y-z]: 1.2.3-44
    
    PLAY [Prompt and validation demo] ************************************
    
    TASK [Make sure version is ok] ***************************************
    skipping: [localhost]
    
    TASK [Make sure target_env is allowed] *******************************
    skipping: [localhost]
    
    TASK [Dummy task just to have a complete playbook for the example] ***
    ok: [localhost] => {
        "msg": "Deploying version 1.2.3-44 for environment prod on localhost"
    }
    
    PLAY RECAP ***********************************************************
    localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0
    
    
    ###################
    # Fully automated #
    ###################
    
    $ ansible-playbook -i localhost, playbook.yml -e target_env=prod -e release_version=1.2.3-44
    
    PLAY [Prompt and validation demo] ************************************
    
    TASK [Make sure version is ok] ***************************************
    skipping: [localhost]
    
    TASK [Make sure target_env is allowed] *******************************
    skipping: [localhost]
    
    TASK [Dummy task just to have a complete playbook for the example] ***
    ok: [localhost] => {
        "msg": "Deploying version 1.2.3-44 for environment prod on localhost"
    }
    
    PLAY RECAP ***********************************************************
    localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0