Hello and welcome to the first in our series of Bitesize Ansible blog posts!
With these Bitesize Ansible posts, we hope to give people an easy access route to practicing with and gaining an understanding of, important Ansible concepts and best practices. So to kick things off, we're going to show you a really simple example of how the Template Module ( http://docs.ansible.com/ansible/latest/template_module.html) works and how to run it via a very simple playbook.
Before we begin, all of these examples will be hosted in our github library here; https://github.com/evolvere-tech and if you need any help or have any questions, either comment on the post in question or email us at info@evolvere-tech.co.uk
Getting Started
In order to run through this example, you'll need python installed in your environment and then to install ansible using whichever package manager you're using for your distribution. For simplicity, we're using default python and pip as our package manager on a linux system.
* If you'd like some more structure info on using python to write code, we offer an in person training course to get you started here
Once you've got your Ansible install up and running, lets create a directory to hold our files;
All of the files apart from the jinja2 (.j2)template file and the inventory file (inventory) are written in YAML. This is the language of Ansible files and the key point to remember is that whitespace matters! Always ensure that your indents match up and you have the same amount of spaces for each of them.
Now, we're ready to Automate with Ansible!
Creating The Template
In this example, we're just going to create a little hello world html page to show you how jinja2 variable substitution works through the Ansible template module. So to start with, lets create the html page template we want to use. The below code snippet is an example of a template, so you can use this, or create one of your own. We're going to call our file html_template.j2;
For those of you that have written HTML before, you'll probably notice that there are some odd tags that have {{ }} in them. Good work! You've spotted the jinja2 template tags.
In Jinja2, all variables have double curly braces around them. Thus, our variable called website_username would be written as {{ website_username }}
Curly braces are special characters in Jinja2 and are reserved, along with some others, such as % (you can get more info on them and other syntax details here: http://jinja.pocoo.org/docs/2.10/). Anything within the curly braces will be interpreted by the template module in Ansible as a variable and must be declared for the template module to succeed. This leads us on to where we define these variables...
I do declare! (Variables)
Variables are a massive and key, concept in the world of Ansible. They allow us to substitute in values to templates (like we're about to do here), perform simple and complex execution logic in single tasks or even whole plays or roles within a playbook. They have the ability to be overriden during execution and have a clearly defined precedence level. We won't go into detail about those features in this blog post, but we cover all the need to know aspects of variables in our Beginners Training Course
Our next objective is to create our website_vars.yml - the file will contain declarations for all of the variables we've put in the HTML template you can see above. You can set these to whatever you want to, and even change the variable names, however, remember to update them in the template as well if you do;
You'll see that we've quoted some of the strings, particularly with non-alphanumeric characters in them, this is just to ensure they get interpreted as text, rather than any formula etc, now on to the playbook!
The Playbook
The following playbook is a simple example of how to execute the template module on the localhost using a template in the current directory to create a fully generated HTML file in the /tmp directory. For the purposes of simplicity, we're not going to collect facts (system information) about the host, so we have set gather_facts: false
Additionally, we have declared the variables file we created in the last step statically within the playbook, again for simplicity. We'll use an inventory file to set the connection type to local - Ansible by default attempts to use SSH, however, on localhost, we usually set it to default to the local connection_type for simplicity. As mentioned previously, we cover details like this more comprehensively in our Beginners Course
Finally, if you look at the task declaration for the template module, you'll see that we have only used the bare minimum src and dest parameters for the module. There are a great variety more options that can be declared, but for simplicity we've not included them here. This is the template_test.yml file;
For completeness, the inventory file contains the following to set the connection to local type;
Running with the (Ansible) pack
Now that we've got all our files in order, lets run the playbook!
All being well, you should now see Ansible go off and run the playbook and when it completes successfully, you should see the fully generated file in /tmp/hello_world.html or whichever path you set as the destination for the file. To open the file, startup your browser and enter file:///tmp/hello_world.html and you should see the webpage in all its glory! (tested on google chrome!)
D'oh!
What happens if our playbook doesn't work? Well, thankfully there are a few things we can try:
Re-run your playbook with -vvvv before the -i inventory. This will output a verbose trace of the playbook run and should indicate any errors in the playbook run.
Check the whitespace and indents on your playbook, remember whitespace matters!
Check that your files are in the right place, with the right names and do the same for your variables
If you're stuck, comment on this post or email us at info@evolvere-tech.co.uk
We hope that this has been useful and encouraging and we'd love to hear your feedback if you thought it was great and especially so if you thought it wasn't so great ( learning is a 2 way street!).
Follow us on LinkedInand on this blog for more updates about Ansible, Network Automation, Infrastructure as Code and all things DevOps!