One of the frequent teachings I have learned whilst learning programming languages is that repeated blocks of code should be, where possible, placed into a function so that the function can be called multiple times instead of writing out the code multiple times. This approach as the benefits of:
- Producing repeatable results
- Reducing the chances of errors due to typos
- Makes code more human readable
Whilst writing Ansible playbooks I found that I was starting to write certain pieces of information into more than one location. For a small playbook this is not too bad, but for a larger playbook it becomes a pain. Especially if the playbook is still being developed, i.e. amended during the testing phase.
The DRY principle is simply “Don’t Repeat Yourself”. If you find that you are writing a file path, URL, IP address, setting etc… multiple times then a method should be used to replace those multiple instances with one instance that is referenced.
Thankfully Ansible has a method to help with DRY, and that is variables. For this blog post I am going to be referencing the work I am currently doing with my ELK (Elastic stack) Ansible playbook, which can be found at: https://github.com/geektechdude/ELK_Ansible_Playbook
Variables Files
I have created a file called “vars.yml” to store all the variables in that I am using. I would recommend thinking about variables during the design phase of the playbook. If however you already have an existing playbook then make a note of anywhere where the same piece of information occurs more than once as these are the type of occurrences that should be replaced with a variable.
I have saved the variable file (e.g. vars.yml) at the root of my playbook so that it is easily accessible for both editing and referencing. If the file sits in the same directory as the playbook then it can be referenced at the top/beginning of the playbook using the lines:
vars_files:
- vars.yml
If it is located in a different directory to the playbook then it can be referenced using its file path. A brief note, if you are using roles with separate task playbook I found that I had to reference the variables file in those task playbooks as well using the play:
– name: Include variables
include_vars:
file: ../../vars.yml
as the first play of the task playbook. The file path in this example takes Ansible back to the root of the playbook directory where vars.yml exists.
Naming And Setting Variables
Make sure to name your variables sensibly, after all you may need to revisit them in several months and trying to remember what an poorly named variable refers to could take up time. Ansible allows for the variable file to contain comments (using #) and I generally place a comment above each variable to confirm what the variable is being used for.
Setting the variable is done in the format of:
variable_name: variable_definition
e.g.
# Download location
download: /tmp
Referencing Variables
The Jinja template engine is used to reference variables in an Ansible playbook. For more information on Jinja check out https://en.wikipedia.org/wiki/Jinja_(template_engine) . The variables are referenced within curly braces such as:
– name: Download Elastic Deb Package
get_url:
url: “{{ elastic_url }}{{ elastic_version }}-amd64.deb”
dest: “{{ download }}”
when: ansible_facts[‘distribution’]==”Ubuntu”

In this example I have referenced variables for the elastic_url (the website for Elastic downloads), elastic_version (the version of Elasticsearch that I want) and download (the location I want to download the .deb file to).
Want to know more?
Ansible have an article on variables at: https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html
Jeff Geerling created an excellent series of YouTube videos about Ansible, including this one on Variables:
https://www.youtube.com/watch?v=HU-dkXBCPdU
You must be logged in to post a comment.