Answers: <p>Note that <code>SOME_CONSTANT = "helloworld"</code> is just following a <a href="https://www.python.org/dev/peps/pep-0008/#constants" rel="nofollow noreferrer">PEP8 convention</a>, one can always follow that statement with <code>SOME_CONSTANT = "something_else"</code>. Python doesn't really have constants, see <a href="https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python">How do I create a constant in Python?</a></p>
  
  <p>I'd use lowercase (i.e. following the Python variable naming convention), to prevent confusion:</p>
  
  <ul>
  <li>inline with the ansible documentation</li>
  <li>no surprises when (some of them) are internally changed to lowercase, for example in <a href="http://docs.ansible.com/ansible/latest/playbooks_variables.html#local-facts-facts-d" rel="nofollow noreferrer">Local Facts (Facts.d)</a>:</li>
  </ul>
  
  <blockquote>
    <p><strong>Note</strong></p>
    
    <p>The key part in the key=value pairs will be converted into lowercase
    inside the ansible_local variable. Using the example above, if the ini
    file contained <code>XYZ=3</code> in the <code>[general]</code> section, then you should
    expect to access it as: <code>{{ ansible_local.preferences.general.xyz }}</code>
    and not <code>{{ ansible_local.preferences.general.XYZ }}</code>. This is because
    Ansible uses Python’s <a href="https://docs.python.org/2/library/configparser.html" rel="nofollow noreferrer">ConfigParser</a> which passes all option names
    through the <a href="https://docs.python.org/2/library/configparser.html#ConfigParser.RawConfigParser.optionxform" rel="nofollow noreferrer">optionxform</a> method and this method’s default
    implementation converts option names to lower case.</p>
  </blockquote>
  
Answers: CC BY-SA 3.0
Answers: 2018-02-28T00:00:32.097Z
Answers: 2018-02-28T00:00:32.097Z
Answers: Dan Cornilescu
Answers: <p>As pointed out in the other comment, there are no constants in python. It's just a convention, but defining a variable in capitals, doesn't mean you can't reassign the value.</p>
  
  <p>There are many ways to pass/define variables in ansible (command line, <code>vars</code> in playbook, include a <code>yaml</code>, <code>vars</code> dir in a role, <code>defaults</code> dir, etc) however, there isn't a way to define a <strong>constant</strong>.</p>
  
  <p>The closest to setting a constant in the way you ask for it is setting your variables as defaults(that is <code>defaults/main.yml</code> inside the role structure). The defaults of a role are the type of variables that have the lowest precedence and are being overwritten by any other way you can define a var but are a great place to put a variable that is unlikely to change and won't clutter your "important" role vars.</p>
  
  <p>Regarding the way you define them - I'd say it's up to you. Just stick to it. I haven't seen anybody using capitals and I would probably make the variable lower case, however, since ansible provides tremendeous amount of flexibility and freedom to do what you like the way you like it, it really is up to you.</p>
  
Answers: CC BY-SA 3.0
Answers: 2018-02-28T00:33:07.557Z
Answers: but a CONSTANT is immutable right? A variable that reside in `defaults/main.yml` could be overridden and is mutable.
Answers: 030
Answers: CC BY-SA 3.0
Answers: 2018-02-28T00:34:10.560Z
Answers: Well this is my point and sorry if I haven't made it clear(I'll update) - there are no constants in ansible. No matter what you, you can always override a variable. Same goes for python.
Answers: man0v
Answers: CC BY-SA 3.0
Answers: 2018-02-28T00:40:30.983Z
Answers: +1: `since ansible provides tremendeous amoount of flexibility and freedom to do what you like the way you like it, it really is up to you.`. I have experienced that Python is extremely flexible as well. It is possible to combine functions, classes and scripts in a project and also the structure could deviate, e.g. some contain a main file, others contain a tests directory, while the latter is omitted in other github projects for example
Answers: 030
Answers: CC BY-SA 3.0
Answers: 2018-02-28T00:22:57.603Z
Answers: 2018-02-28T00:41:36.180Z
Answers: 2018-02-28T00:41:36.180Z
Answers: man0v
Body: <p>If one writes a constant in Python, then <a href="https://stackoverflow.com/a/2682752/2777965">one uses uppercase</a>:</p>
  
  <pre><code>SOME_CONSTANT = "helloworld"
  </code></pre>
  
  <p>Now I wonder how to define constants in Ansible. My first impression was to use the same convention as in Python as Ansible is written in python, but when one checks <a href="http://docs.ansible.com/ansible/latest/playbooks_variables.html" rel="nofollow noreferrer">the variables information page</a> then this does not seem to be a best practice.</p>
  
  <p><strong>Current approach</strong></p>
  
  <p><a href="https://github.com/030/ansible-firefox/blob/master/vars/main.yml" rel="nofollow noreferrer">https://github.com/030/ansible-firefox/blob/master/vars/main.yml</a></p>
  
  <pre><code>---
  firefox_download: /tmp/firefox-{{ firefox_version }}.tar.bz2
  firefox_bin: "{{ firefox_home }}/firefox/firefox"
  </code></pre>
  
  <p><a href="https://github.com/030/ansible-firefox/blob/master/tasks/main.yml" rel="nofollow noreferrer">https://github.com/030/ansible-firefox/blob/master/tasks/main.yml</a></p>
  
  <pre><code>- name: Download.
    get_url:
      url: https://ftp.mozilla.org/pub/firefox/releases/{{ firefox_version }}/linux-x86_64/en-US/firefox-{{ firefox_version }}.tar.bz2
      dest: /tmp/firefox-{{ firefox_version }}.tar.bz2
  checksum: "{{ firefox_checksum }}"
  </code></pre>
  
  <p><strong>Discussion</strong></p>
  
  <p>I am considering to define <code>https://ftp.mozilla.org/pub/firefox/releases/{{ firefox_version }}/linux-x86_64/en-US/firefox-{{ firefox_version }}.tar.bz2</code> as a constant in the <code>vars/main.yml</code>, but I did not see any other ansible roles that define constants as: </p>
  
  <pre><code>FIREFOX_DOWNLOAD_URL: https://ftp.mozilla.org/pub/firefox/releases/{{ firefox_version }}/linux-x86_64/en-US/firefox-{{ firefox_version }}.tar.bz2
  </code></pre>
  
  <p>while this is valid python and the convention to write constants.</p>
  
  <p>One could argue that an Ansible constant could be defined in the <code>default/main.yml</code>, but on the other hand, as a CONSTANT is immutable it should not be possible to overwrite it and should reside in <code>vars/main.yml</code>. </p>
  
Tags: <ansible>
Title: How to define constants in Ansible?
UserDisplayName: 030
ThreadText: # How to define constants in Ansible?
  
  (Asked by: username_0 on 2018-02-27)
  
  If one writes a constant in Python, then [one uses uppercase](https://stackoverflow.com/a/2682752/2777965):
  
  ```
  SOME_CONSTANT = "helloworld"
  
  ```
  
  Now I wonder how to define constants in Ansible. My first impression was to use the same convention as in Python as Ansible is written in python, but when one checks [the variables information page](http://docs.ansible.com/ansible/latest/playbooks_variables.html) then this does not seem to be a best practice.
  
  **Current approach**
  
  <https://github.com/030/ansible-firefox/blob/master/vars/main.yml>
  
  ```
  ---
  firefox_download: /tmp/firefox-{{ firefox_version }}.tar.bz2
  firefox_bin: "{{ firefox_home }}/firefox/firefox"
  
  ```
  
  <https://github.com/030/ansible-firefox/blob/master/tasks/main.yml>
  
  ```
  - name: Download.
    get_url:
      url: https://ftp.mozilla.org/pub/firefox/releases/{{ firefox_version }}/linux-x86_64/en-US/firefox-{{ firefox_version }}.tar.bz2
      dest: /tmp/firefox-{{ firefox_version }}.tar.bz2
  checksum: "{{ firefox_checksum }}"
  
  ```
  
  **Discussion**
  
  I am considering to define `https://ftp.mozilla.org/pub/firefox/releases/{{ firefox_version }}/linux-x86_64/en-US/firefox-{{ firefox_version }}.tar.bz2` as a constant in the `vars/main.yml`, but I did not see any other ansible roles that define constants as:
  
  ```
  FIREFOX_DOWNLOAD_URL: https://ftp.mozilla.org/pub/firefox/releases/{{ firefox_version }}/linux-x86_64/en-US/firefox-{{ firefox_version }}.tar.bz2
  
  ```
  
  while this is valid python and the convention to write constants.
  
  One could argue that an Ansible constant could be defined in the `default/main.yml`, but on the other hand, as a CONSTANT is immutable it should not be possible to overwrite it and should reside in `vars/main.yml`.
  
  **Tags:** ansible
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2018-02-28. Score: 3 | Accepted answer
  
  As pointed out in the other comment, there are no constants in python. It's just a convention, but defining a variable in capitals, doesn't mean you can't reassign the value.
  
  There are many ways to pass/define variables in ansible (command line, `vars` in playbook, include a `yaml`, `vars` dir in a role, `defaults` dir, etc) however, there isn't a way to define a **constant**.
  
  The closest to setting a constant in the way you ask for it is setting your variables as defaults(that is `defaults/main.yml` inside the role structure). The defaults of a role are the type of variables that have the lowest precedence and are being overwritten by any other way you can define a var but are a great place to put a variable that is unlikely to change and won't clutter your "important" role vars.
  
  Regarding the way you define them - I'd say it's up to you. Just stick to it. I haven't seen anybody using capitals and I would probably make the variable lower case, however, since ansible provides tremendeous amount of flexibility and freedom to do what you like the way you like it, it really is up to you.
  
  > **Comments:**
  > **username_0**: but a CONSTANT is immutable right? A variable that reside in `defaults/main.yml` could be overridden and is mutable.  
  > **username_2**: Well this is my point and sorry if I haven't made it clear(I'll update) - there are no constants in ansible. No matter what you, you can always override a variable. Same goes for python.  
  > **username_0**: +1: `since ansible provides tremendeous amoount of flexibility and freedom to do what you like the way you like it, it really is up to you.`. I have experienced that Python is extremely flexible as well. It is possible to combine functions, classes and scripts in a project and also the structure could deviate, e.g. some contain a main file, others contain a tests directory, while the latter is omitted in other github projects for example  
  
  ---
  
  ### Answer by username_1 on 2018-02-28. Score: 1
  
  Note that `SOME_CONSTANT = "helloworld"` is just following a [PEP8 convention](https://www.python.org/dev/peps/pep-0008/#constants), one can always follow that statement with `SOME_CONSTANT = "something_else"`. Python doesn't really have constants, see [How do I create a constant in Python?](https://stackoverflow.com/questions/2682745/how-do-i-create-a-constant-in-python)
  
  I'd use lowercase (i.e. following the Python variable naming convention), to prevent confusion:
  
  * inline with the ansible documentation
  * no surprises when (some of them) are internally changed to lowercase, for example in [Local Facts (Facts.d)](http://docs.ansible.com/ansible/latest/playbooks_variables.html#local-facts-facts-d):
  
  > **Note**
  >
  > The key part in the key=value pairs will be converted into lowercase
  > inside the ansible\_local variable. Using the example above, if the ini
  > file contained `XYZ=3` in the `[general]` section, then you should
  > expect to access it as: `{{ ansible_local.preferences.general.xyz }}`
  > and not `{{ ansible_local.preferences.general.XYZ }}`. This is because
  > Ansible uses Python’s [ConfigParser](https://docs.python.org/2/library/configparser.html) which passes all option names
  > through the [optionxform](https://docs.python.org/2/library/configparser.html#ConfigParser.RawConfigParser.optionxform) method and this method’s default
  > implementation converts option names to lower case.
  
  
  ---
  
  