$ cd /home/Lu/

Keep-learning Lu

18 Dec 2020

Ansible to Conditionally Prompt for Variables

As a part of the installation of SlapOS node, the Ansible playbook is written in yml file. Since it is the first time I worked with ansible playbook, I surely don't much about it while I do try to realise a function: conditionallise the prompt for variables.

To begin with the story, I would like to fill in some previously on prompting variables in ansible. During the installation of SlapOS node, it always asks 4 questions:

  1. “What is the url to the SlapOS Master API? (ignore if you already have a configured re6st and slapos):”
  2. “What is the url to the SlapOS Master Website? (ignore if you already have a configured re6st and slapos):”
  3. “What is this computer name? (ignore if you already have a configured re6st and slapos):”
  4. “If you have slapos token if you have (ignore if you already have a configured slapos):”

These questions, however, are not separate. For instance, if I don't input a computer name for Q3, then the 4th question of slapos token can be nonsense. Therefore, if the questions can be conditional, it will ease some misunderstandings for users. And as you know, in ansible, the “questions” are written in vars_prompt, BUT…

Unfortunately it seems there is no way of allowing the vars_prompt statement at task level.

… according to [Ansible to Conditionally Prompt for a Variable?], which did offer a feasibility solution though, thanking for pause module as tehmoon mentioned.

Original slapos.yml:

  vars:
    - interface_name: lo

  vars_prompt:
    - name: "slapos_master_url"
      prompt: "What is the url to the SlapOS Master API?  (ignore if you already have a configured re6st and slapos):"
      private: no
      default: "https://slap.vifib.com/"

    - name: "slapos_web_master_url"
      prompt: "What is the url to the SlapOS Master Website?  (ignore if you already have a configured re6st and slapos):"
      private: no
      default: "https://slapos.vifib.com/"

    - name: "computer_name"
      prompt: "What is this computer name?  (ignore if you already have a configured re6st and slapos):"
      private: no
      default: "noname"

    - name: "slapostoken"
      prompt: "If you have slapos token if you have (ignore if you already have a configured slapos):"
      private: no
      default: "notoken"

My idea is to add a question for interface_name but according to the logic of the tasks.

graph TB
A(start) --> B(slapos_master_url)
B --> C(slapos_web_master_url)
C --> D{register to SlapOS master?}
D --> |no| E(keep default computer_name)
E --> I(End)
D --> |yes| F(input computer_name)
F --> G(input slapostoken)
G --> H(input interface_name)
H --> I

(First time to use mermaid syntax, feels pretty good.)

(but it doesn't work on my blog… so I put a screenshot.)

2020-12-26-00-23-17.png

Volià the final slapos.yml:

  # var for interface_name is removed
  vars_prompt:
    - name: "slapos_master_url"
      prompt: "What is the url to the SlapOS Master API?  (ignore if you already have a configured re6st and slapos):"
      private: no
      default: "https://slap.vifib.com/"

    - name: "slapos_web_master_url"
      prompt: "What is the url to the SlapOS Master Website?  (ignore if you already have a configured re6st and slapos):"
      private: no
      default: "https://slapos.vifib.com/"

    - name: "computer_name"
      prompt: "Name your computer (ignore if you already have a configured re6st and slapos or if you don't want to register your computer to SlapOS Master):"
      private: no
      default: "noname"

  pre_tasks:
    - pause:
        prompt: "Input your slapos token (ignore if you already have a configured slapos) [notoken]"
      when: computer_name != "noname"
      register: prompt
    - set_fact:
        slapostoken: "{{ prompt.user_input | default('notoken', true) }}" 

    - pause:
        prompt: "Which network interface are you using? (ignore if you already have a configured re6st) [lo]"
      when: slapostoken != "notoken"
      register: prompt
    - set_fact:
        interface_name: "{{ prompt.user_input | default('lo', true) }}" 
comments powered by Disqus