Answers: <p>If an extra variable is truly required, you can add <a href="https://docs.ansible.com/ansible/latest/assert_module.html" rel="nofollow noreferrer"><code>assert</code></a> statements at the top of the role to stop it from executing if they're not defined:</p>
  
  <pre><code>┌─[jamesph@geror] - [~/temp] - [Sat Jan 13, 09:40]
  └─[$]&gt; cat assert.yml
  - hosts: localhost
    vars:
      foo: False
    tasks:
      - assert:
          that:
            - "foo is defined"
            - "bar is defined"
  ┌─[jamesph@geror] - [~/temp] - [Sat Jan 13, 09:40]
  └─[$]&gt; ansible-playbook assert.yml
   [WARNING]: Unable to parse /etc/ansible/hosts as an inventory source
  
   [WARNING]: No inventory was parsed, only implicit localhost is available
  
   [WARNING]: Could not match supplied host pattern, ignoring: all
  
   [WARNING]: provided hosts list is empty, only localhost is available
  
  
  PLAY [localhost] *************************************************************************************
  
  TASK [Gathering Facts] *******************************************************************************
  ok: [localhost]
  
  TASK [assert] ****************************************************************************************
  fatal: [localhost]: FAILED! =&gt; {
      "assertion": "bar is defined",
      "changed": false,
      "evaluated_to": false
  }
      to retry, use: --limit @/Users/jamesph/temp/assert.retry
  
  PLAY RECAP *******************************************************************************************
  localhost                  : ok=1    changed=0    unreachable=0    failed=1
  </code></pre>
  
Answers: CC BY-SA 3.0
Answers: 2018-01-13T17:41:12.197Z
Answers: 2018-01-13T17:41:12.197Z
Answers: Xiong Chiamiov
Answers: <blockquote>
    <p>some have required and optional arguments that I forget about from
    time to time</p>
  </blockquote>
  
  <p><a href="http://docs.ansible.com/ansible/latest/playbooks_variables.html#variables-defined-in-inventory" rel="nofollow noreferrer">http://docs.ansible.com/ansible/latest/playbooks_variables.html#variables-defined-in-inventory</a></p>
  
  <blockquote>
    <p>Ok, so if you are writing a redistributable role with reasonable
    defaults, put those in the roles/x/defaults/main.yml file. This means
    the role will bring along a default value but ANYTHING in Ansible will
    override it. It’s just a default. That’s why it says “defaults” :) See
    Roles for more info about this:</p>
  
  <pre><code>---
  # file: roles/x/defaults/main.yml
  # if not overridden in inventory or as a parameter, this is the value that will be used
  http_port: 80
  </code></pre>
    
    <p>If you are writing a role and want to ensure the value in the role is
    absolutely used in that role, and is not going to be overridden by
    inventory, you should put it in roles/x/vars/main.yml like so, and
    inventory values cannot override it. -e however, still will:</p>
  </blockquote>
  
  <p>In summary, always set reasonable defaults, e.g. a software version that exists instead of using a non-existing one or empty variable and if there is a constant, put it in the vars directory.</p>
  
  <p>There is a number of <a href="https://galaxy.ansible.com/" rel="nofollow noreferrer">galaxy playbooks</a> that could be checked:</p>
  
  <ul>
  <li><a href="https://github.com/geerlingguy/ansible-role-nginx" rel="nofollow noreferrer">https://github.com/geerlingguy/ansible-role-nginx</a></li>
  <li><a href="https://github.com/shelleg/ansible-role-gradle" rel="nofollow noreferrer">https://github.com/shelleg/ansible-role-gradle</a></li>
  <li><a href="https://galaxy.ansible.com/030/firefox/" rel="nofollow noreferrer">https://galaxy.ansible.com/030/firefox/</a></li>
  </ul>
  
Answers: CC BY-SA 3.0
Answers: 2017-12-27T22:14:59.197Z
Answers: Ok, then it's probably an ansible-smell to use "When" with extra_args.  There's some things that I only want to do when I _do_ specify those extra args and I don't want to do them by default. I guess either way it helps to have defaults and just don't do those things when the value is the default, that way all I need to do is cat out my default yamls
Answers: Peter Turner
Answers: CC BY-SA 3.0
Answers: 2017-12-27T22:19:32.970Z
Answers: Could you add the code code snippet, e.g. the exact when statement? Could you explain it more functionally, e.g. if system ubuntu and this version then this and otherwise this.
Answers: 030
Answers: CC BY-SA 3.0
Answers: 2017-12-27T23:11:27.023Z
Answers: I added code, but I think you hit the nail on he head with specifying default software versions, that'd saved my butt.
Answers: Peter Turner
Answers: CC BY-SA 3.0
Answers: 2017-12-27T23:46:46.843Z
Answers: [It is possible to overwrite the default variables using `group_vars` and `host_vars`](http://docs.ansible.com/ansible/latest/playbooks_variables.html#variable-examples).
Answers: 030
Answers: CC BY-SA 3.0
Answers: 2017-12-27T22:10:18.227Z
Answers: 2017-12-27T22:18:38.110Z
Answers: 2017-12-27T22:18:38.110Z
Answers: 030
Body: <p>I've got a number of ansible playbooks that I come back to from time to time, some have required and optional arguments that I forget about from time to time.</p>
  
  <p>I know there's a list-tags, list-hosts and list-tasks option baked into the ansible-playbook command, there's no list-args, which would be super useful, but maybe it means I'm using ansible wrong?</p>
  
  <p>So what strategies do devops engineers use to manage "api's" for ansible playbooks? Maybe just a recursive grep command to list non-standard args that aren't registered variables like this</p>
  
  <pre><code>grep -or "{{[a-zA-Z_ ]\+}}" roles/.  | grep -v "ansible" | grep -v "item"
  </code></pre>
  
  <p>only better.</p>
  
  <hr>
  
  <p>For instance, I've got a program I want to put on a device called "showstopper", but I specify the version with extra_args and if I don't specify the version, it doesn't get installed.</p>
  
  <pre><code> - name: download showstopper from artifactory
     local_action: get_url url=https://example.net/artifactory/generic-release-local/com/cdw/mans/silo/showstopper/showstopper-{{ showstopper_version }}.noarch.rpm dest=/tmp validate_certs=no
     run_once: true
     when: showstopper_version is defined
  
   - name: copy showstopper to silo
     copy: src=/tmp/showstopper-{{ showstopper_version }}.noarch.rpm dest=/tmp
     when: showstopper_version is defined
  
   - name: Install showstopper
     yum: name=/tmp/showstopper-{{ showstopper_version }}.noarch.rpm state=present
     notify:
      - start cron
     when: showstopper_version is defined
  </code></pre>
  
  <p>This works good when I run it the way I intended to run it, but in 2 months when I want to run it on another machine, I forgot to specify showstopper_version and the last few machines I've built went out without that configured on it.</p>
  
Tags: <ansible>
Title: Discovering extra args needed for running ansible playbooks
UserDisplayName: Peter Turner
ThreadText: # Discovering extra args needed for running ansible playbooks
  
  (Asked by: username_0 on 2017-12-27)
  
  I've got a number of ansible playbooks that I come back to from time to time, some have required and optional arguments that I forget about from time to time.
  
  I know there's a list-tags, list-hosts and list-tasks option baked into the ansible-playbook command, there's no list-args, which would be super useful, but maybe it means I'm using ansible wrong?
  
  So what strategies do devops engineers use to manage "api's" for ansible playbooks? Maybe just a recursive grep command to list non-standard args that aren't registered variables like this
  
  ```
  grep -or "{{[a-zA-Z_ ]\+}}" roles/.  | grep -v "ansible" | grep -v "item"
  
  ```
  
  only better.
  
  ---
  
  For instance, I've got a program I want to put on a device called "showstopper", but I specify the version with extra\_args and if I don't specify the version, it doesn't get installed.
  
  ```
   - name: download showstopper from artifactory
     local_action: get_url url=https://example.net/artifactory/generic-release-local/com/cdw/mans/silo/showstopper/showstopper-{{ showstopper_version }}.noarch.rpm dest=/tmp validate_certs=no
     run_once: true
     when: showstopper_version is defined
  
   - name: copy showstopper to silo
     copy: src=/tmp/showstopper-{{ showstopper_version }}.noarch.rpm dest=/tmp
     when: showstopper_version is defined
  
   - name: Install showstopper
     yum: name=/tmp/showstopper-{{ showstopper_version }}.noarch.rpm state=present
     notify:
      - start cron
     when: showstopper_version is defined
  
  ```
  
  This works good when I run it the way I intended to run it, but in 2 months when I want to run it on another machine, I forgot to specify showstopper\_version and the last few machines I've built went out without that configured on it.
  
  **Tags:** ansible
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2018-01-13. Score: 4
  
  If an extra variable is truly required, you can add [`assert`](https://docs.ansible.com/ansible/latest/assert_module.html) statements at the top of the role to stop it from executing if they're not defined:
  
  ```
  ┌─[jamesph@geror] - [~/temp] - [Sat Jan 13, 09:40]
  └─[$]> cat assert.yml
  - hosts: localhost
    vars:
      foo: False
    tasks:
      - assert:
          that:
            - "foo is defined"
            - "bar is defined"
  ┌─[jamesph@geror] - [~/temp] - [Sat Jan 13, 09:40]
  └─[$]> ansible-playbook assert.yml
   [WARNING]: Unable to parse /etc/ansible/hosts as an inventory source
  
   [WARNING]: No inventory was parsed, only implicit localhost is available
  
   [WARNING]: Could not match supplied host pattern, ignoring: all
  
   [WARNING]: provided hosts list is empty, only localhost is available
  
  PLAY [localhost] *************************************************************************************
  
  TASK [Gathering Facts] *******************************************************************************
  ok: [localhost]
  
  TASK [assert] ****************************************************************************************
  fatal: [localhost]: FAILED! => {
      "assertion": "bar is defined",
      "changed": false,
      "evaluated_to": false
  }
      to retry, use: --limit @/Users/jamesph/temp/assert.retry
  
  PLAY RECAP *******************************************************************************************
  localhost                  : ok=1    changed=0    unreachable=0    failed=1
  
  ```
  
  
  ---
  
  ### Answer by username_2 on 2017-12-27. Score: 2
  
  > some have required and optional arguments that I forget about from
  > time to time
  
  <http://docs.ansible.com/ansible/latest/playbooks_variables.html#variables-defined-in-inventory>
  
  > Ok, so if you are writing a redistributable role with reasonable
  > defaults, put those in the roles/x/defaults/main.yml file. This means
  > the role will bring along a default value but ANYTHING in Ansible will
  > override it. It’s just a default. That’s why it says “defaults” :) See
  > Roles for more info about this:
  >
  > ```
  > ---
  > # file: roles/x/defaults/main.yml
  > # if not overridden in inventory or as a parameter, this is the value that will be used
  > http_port: 80
  >
  > ```
  >
  > If you are writing a role and want to ensure the value in the role is
  > absolutely used in that role, and is not going to be overridden by
  > inventory, you should put it in roles/x/vars/main.yml like so, and
  > inventory values cannot override it. -e however, still will:
  
  In summary, always set reasonable defaults, e.g. a software version that exists instead of using a non-existing one or empty variable and if there is a constant, put it in the vars directory.
  
  There is a number of [galaxy playbooks](https://galaxy.ansible.com/) that could be checked:
  
  * <https://github.com/geerlingguy/ansible-role-nginx>
  * <https://github.com/shelleg/ansible-role-gradle>
  * <https://galaxy.ansible.com/030/firefox/>
  
  > **Comments:**
  > **username_0**: Ok, then it's probably an ansible-smell to use "When" with extra_args.  There's some things that I only want to do when I _do_ specify those extra args and I don't want to do them by default. I guess either way it helps to have defaults and just don't do those things when the value is the default, that way all I need to do is cat out my default yamls  
  > **username_2**: Could you add the code code snippet, e.g. the exact when statement? Could you explain it more functionally, e.g. if system ubuntu and this version then this and otherwise this.  
  > **username_0**: I added code, but I think you hit the nail on he head with specifying default software versions, that'd saved my butt.  
  > **username_2**: [It is possible to overwrite the default variables using `group_vars` and `host_vars`](http://docs.ansible.com/ansible/latest/playbooks_variables.html#variable-examples).  
  
  ---
  
  