Answers: <p>See <a href="https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable" rel="nofollow noreferrer">Variable precedence: Where should I put a variable?</a>. You can see that the role's defaults represent the lowest precedence for variables and the extra variables, declared on the command-line, override everything. There are a plethora of options between these two options.</p>
  <p>For testing, create the roles and the playbook below. For example</p>
  <pre class="lang-sh prettyprint-override"><code>shell&gt; tree roles/
  roles/
  ├── certbot
  │   ├── defaults
  │   │   └── main.yml
  │   └── tasks
  │       └── main.yml
  ├── jenkins
  │   ├── defaults
  │   │   └── main.yml
  │   └── tasks
  │       └── main.yml
  └── nginx
      ├── defaults
      │   └── main.yml
      └── tasks
          └── main.yml
  
  9 directories, 6 files
  </code></pre>
  <p>There are only two files in each role. The files are identical in all roles</p>
  <pre class="lang-yaml prettyprint-override"><code>shell&gt; cat roles/certbot/defaults/main.yml 
  fqdn: &quot;{{ fqdn_default|default('srv.example.com') }}&quot;
  
  shell&gt; cat roles/certbot/tasks/main.yml 
  - debug:
      var: fqdn
  </code></pre>
  <p>Then, the playbook below</p>
  <pre class="lang-yaml prettyprint-override"><code>shell&gt; cat playbook.yml
  - hosts: localhost
    roles:
      - certbot
      - jenkins
      - nginx
  </code></pre>
  <p>gives as expected</p>
  <pre class="lang-yaml prettyprint-override"><code>shell&gt; ansible-playbook playbook.yml 
  
  PLAY [localhost] *********************************************************
  
  TASK [certbot : debug] ***************************************************
  ok: [localhost] =&gt; 
    fqdn: srv.example.com
  
  TASK [jenkins : debug] ***************************************************
  ok: [localhost] =&gt; 
    fqdn: srv.example.com
  
  TASK [nginx : debug] *****************************************************
  ok: [localhost] =&gt; 
    fqdn: srv.example.com
  </code></pre>
  <p>In this example, the default values of <em>fqdn</em> in all roles are the same. Of course, you can declare different default values for each role if you want to.</p>
  <hr>
  <p>You can declare the variable on the command-line</p>
  <pre class="lang-yaml prettyprint-override"><code>shell&gt; ansible-playbook playbook.yml -e fqdn=www.example.com
  
  PLAY [localhost] *********************************************************
  
  TASK [certbot : debug] ***************************************************
  ok: [localhost] =&gt; 
    fqdn: www.example.com
  
  TASK [jenkins : debug] ***************************************************
  ok: [localhost] =&gt; 
    fqdn: www.example.com
  
  TASK [nginx : debug] *****************************************************
  ok: [localhost] =&gt; 
    fqdn: www.example.com
  </code></pre>
  <hr>
  <p>Moreover, in this example, you can also change the default value, e.g. in the <em>group_vars</em></p>
  <pre class="lang-yaml prettyprint-override"><code>shell&gt; cat group_vars/all.yml 
  fqdn_default: default.example.com
  </code></pre>
  <p>Then the playbook will use the value of <em>fqdn_default</em></p>
  <pre class="lang-yaml prettyprint-override"><code>shell&gt; ansible-playbook playbook.yml 
  
  PLAY [localhost] **********************************************************
  
  TASK [certbot : debug] ****************************************************
  ok: [localhost] =&gt; 
    fqdn: default.example.com
  
  TASK [jenkins : debug] ****************************************************
  ok: [localhost] =&gt; 
    fqdn: default.example.com
  
  TASK [nginx : debug] ******************************************************
  ok: [localhost] =&gt; 
    fqdn: default.example.com
  </code></pre>
  <hr>
  <p>Use <a href="https://docs.ansible.com/ansible/latest/user_guide/playbooks_prompts.html#interactive-input-prompts" rel="nofollow noreferrer">vars_prompts</a> if you want to <code>input the fqdn from the command line when the playbook is running</code>. e.g.</p>
  <pre class="lang-yaml prettyprint-override"><code>shell&gt; cat playbook.yml
  - hosts: localhost
    vars_prompt:
      - name: fqdn
        prompt: What is the fqdn?
        private: no
    roles:
      - certbot
      - jenkins
      - nginx
  </code></pre>
  <pre class="lang-yaml prettyprint-override"><code>shell&gt; ansible-playbook playbook.yml
  What is the fqdn?: ww9.example.com
  
  PLAY [localhost] ******************************************************
  
  TASK [certbot : debug] ************************************************
  ok: [localhost] =&gt; 
    fqdn: ww9.example.com
  
  TASK [jenkins : debug] *************************************************
  ok: [localhost] =&gt; 
    fqdn: ww9.example.com
  
  TASK [nginx : debug] ***************************************************
  ok: [localhost] =&gt; 
    fqdn: ww9.example.com
  </code></pre>
  <p>Quoting from the <a href="https://docs.ansible.com/ansible/latest/user_guide/playbooks_prompts.html#interactive-input-prompts" rel="nofollow noreferrer">Note</a>: &quot;<em>Prompts for individual vars_prompt variables will be skipped for any variable that is already defined through the command line --extra-vars option,...</em>&quot;</p>
  
Answers: CC BY-SA 4.0
Answers: 2022-01-23T19:09:35.867Z
Answers: 2022-01-24T01:00:27.223Z
Answers: 2022-01-24T01:00:27.223Z
Answers: Vladimir Botka
Body: <p>There are multiple kind of variables in Ansible. And I find it overwhelming to wrap my head around them. Some of them are:</p>
  <ul>
  <li>The one we can write in roles//vars/main.yml</li>
  <li>The one we can write in the tasks file itself.</li>
  <li>Then there are group_vars.</li>
  <li>Then we have host_vars.</li>
  <li>There are also vars files.</li>
  </ul>
  <p><strong>My use case is</strong>... I have three roles. Namely nginx, jenkins and certbot. Thing common in all of them is the domain name. I decided to use a variable named {{ fqdn }} in all of those for sake of refactoring.</p>
  <p>I am not able to decide on which version to use.</p>
  <p><strong>What I want is</strong>... ability to input the <code>fqdn</code> from command line when playbook is running. There should be default value which I can put somewhere in the repo.</p>
  
Tags: <jenkins><ansible><nginx><certbot>
Title: Where does multi-role variable goes in Ansible?
UserDisplayName: Santosh Kumar
ThreadText: # Where does multi-role variable goes in Ansible?
  
  (Asked by: username_0 on 2022-01-23)
  
  There are multiple kind of variables in Ansible. And I find it overwhelming to wrap my head around them. Some of them are:
  
  * The one we can write in roles//vars/main.yml
  * The one we can write in the tasks file itself.
  * Then there are group\_vars.
  * Then we have host\_vars.
  * There are also vars files.
  
  **My use case is**... I have three roles. Namely nginx, jenkins and certbot. Thing common in all of them is the domain name. I decided to use a variable named {{ fqdn }} in all of those for sake of refactoring.
  
  I am not able to decide on which version to use.
  
  **What I want is**... ability to input the `fqdn` from command line when playbook is running. There should be default value which I can put somewhere in the repo.
  
  **Tags:** jenkins, ansible, nginx, certbot
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2022-01-23. Score: 3
  
  See [Variable precedence: Where should I put a variable?](https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable). You can see that the role's defaults represent the lowest precedence for variables and the extra variables, declared on the command-line, override everything. There are a plethora of options between these two options.
  
  For testing, create the roles and the playbook below. For example
  
  ```sh
  shell> tree roles/
  roles/
  ├── certbot
  │   ├── defaults
  │   │   └── main.yml
  │   └── tasks
  │       └── main.yml
  ├── jenkins
  │   ├── defaults
  │   │   └── main.yml
  │   └── tasks
  │       └── main.yml
  └── nginx
      ├── defaults
      │   └── main.yml
      └── tasks
          └── main.yml
  
  9 directories, 6 files
  
  ```
  
  There are only two files in each role. The files are identical in all roles
  
  ```yaml
  shell> cat roles/certbot/defaults/main.yml 
  fqdn: "{{ fqdn_default|default('srv.example.com') }}"
  
  shell> cat roles/certbot/tasks/main.yml 
  - debug:
      var: fqdn
  
  ```
  
  Then, the playbook below
  
  ```yaml
  shell> cat playbook.yml
  - hosts: localhost
    roles:
      - certbot
      - jenkins
      - nginx
  
  ```
  
  gives as expected
  
  ```yaml
  shell> ansible-playbook playbook.yml 
  
  PLAY [localhost] *********************************************************
  
  TASK [certbot : debug] ***************************************************
  ok: [localhost] => 
    fqdn: srv.example.com
  
  TASK [jenkins : debug] ***************************************************
  ok: [localhost] => 
    fqdn: srv.example.com
  
  TASK [nginx : debug] *****************************************************
  ok: [localhost] => 
    fqdn: srv.example.com
  
  ```
  
  In this example, the default values of *fqdn* in all roles are the same. Of course, you can declare different default values for each role if you want to.
  
  ---
  
  You can declare the variable on the command-line
  
  ```yaml
  shell> ansible-playbook playbook.yml -e fqdn=www.example.com
  
  PLAY [localhost] *********************************************************
  
  TASK [certbot : debug] ***************************************************
  ok: [localhost] => 
    fqdn: www.example.com
  
  TASK [jenkins : debug] ***************************************************
  ok: [localhost] => 
    fqdn: www.example.com
  
  TASK [nginx : debug] *****************************************************
  ok: [localhost] => 
    fqdn: www.example.com
  
  ```
  
  ---
  
  Moreover, in this example, you can also change the default value, e.g. in the *group\_vars*
  
  ```yaml
  shell> cat group_vars/all.yml 
  fqdn_default: default.example.com
  
  ```
  
  Then the playbook will use the value of *fqdn\_default*
  
  ```yaml
  shell> ansible-playbook playbook.yml 
  
  PLAY [localhost] **********************************************************
  
  TASK [certbot : debug] ****************************************************
  ok: [localhost] => 
    fqdn: default.example.com
  
  TASK [jenkins : debug] ****************************************************
  ok: [localhost] => 
    fqdn: default.example.com
  
  TASK [nginx : debug] ******************************************************
  ok: [localhost] => 
    fqdn: default.example.com
  
  ```
  
  ---
  
  Use [vars\_prompts](https://docs.ansible.com/ansible/latest/user_guide/playbooks_prompts.html#interactive-input-prompts) if you want to `input the fqdn from the command line when the playbook is running`. e.g.
  
  ```yaml
  shell> cat playbook.yml
  - hosts: localhost
    vars_prompt:
      - name: fqdn
        prompt: What is the fqdn?
        private: no
    roles:
      - certbot
      - jenkins
      - nginx
  
  ```
  
  ```yaml
  shell> ansible-playbook playbook.yml
  What is the fqdn?: ww9.example.com
  
  PLAY [localhost] ******************************************************
  
  TASK [certbot : debug] ************************************************
  ok: [localhost] => 
    fqdn: ww9.example.com
  
  TASK [jenkins : debug] *************************************************
  ok: [localhost] => 
    fqdn: ww9.example.com
  
  TASK [nginx : debug] ***************************************************
  ok: [localhost] => 
    fqdn: ww9.example.com
  
  ```
  
  Quoting from the [Note](https://docs.ansible.com/ansible/latest/user_guide/playbooks_prompts.html#interactive-input-prompts): "*Prompts for individual vars\_prompt variables will be skipped for any variable that is already defined through the command line --extra-vars option,...*"
  
  
  ---
  
  