Variables and Templates

AnsibleBeginner
Practice Now

Introduction

If you manage 100 servers, you don't want them to be exactly identical. Each server might need its own unique hostname, IP address, or specific configuration settings.

Ansible handles this with variables and templates.

  • Variables: Placeholders for data (like port: 8080 or server_name: "web-01").
  • Templates: Text files with "holes" in them. Ansible fills these holes with variables to create the final file.

This combination is what makes automation reusable instead of repetitive. You can keep one general structure for many hosts while changing the data that gets inserted for each environment or machine.

Ansible uses a templating language called Jinja2. This makes automation more reusable because one template can produce different final configuration files depending on the variables supplied.

And turn it into this: Welcome to web-01

In this lab, you will generate a custom HTML webpage for your server using variables and templates.

Create a Template

First, we need to organize our files. Ansible looks for templates in a specific folder named templates.

That convention is part of Ansible's design philosophy. It prefers predictable directory structures so automation remains easy to read and share across teams.

Create this directory inside your project folder:

mkdir -p ~/project/templates

Now, create the template file. Template files usually end with .j2 (for Jinja2).

Open nano to create index.html.j2:

nano ~/project/templates/index.html.j2

Add the following HTML code. Notice the special {{ }} brackets. This is how we tell Ansible "put a variable here".

<html>
  <head>
    <title>{{ page_title }}</title>
  </head>
  <body>
    <h1>Welcome to {{ inventory_hostname }}</h1>
    <p>This file was generated by Ansible.</p>
  </body>
</html>

Understanding the variables:

  • {{ page_title }}: This is a custom variable. We will define its value in our playbook later.
  • {{ inventory_hostname }}: This is a magic variable. Ansible knows this automatically—it's the name of the server it's currently working on (in our case, localhost).

It is useful to distinguish those two kinds of values. Some variables are defined by you, while others are provided automatically by Ansible from the inventory and execution context.

Save and exit (Ctrl+X, Y, Enter).

Define Variables

Now we need a playbook to use this template. In the playbook, we will define the value for our custom page_title variable.

Create a new file named playbook.yml:

nano ~/project/playbook.yml

Start by defining the play and the variables:

---
- name: Deploy Web Page
  hosts: localhost
  vars:
    page_title: "My LabEx Web Server"
  tasks:

Understanding the code:

  • vars:: This section is where you list your variables.
  • page_title: "...": We are telling Ansible that whenever it sees {{ page_title }} in a template, it should replace it with "My LabEx Web Server".

Keep the file open for the next step.

Use the Template Module

Now we add the task that does the actual work. We use the template module. This module reads our .j2 file, fills in the variables, and saves the result to the server.

In practice, the template module is how many configuration files are deployed in real environments. Instead of copying a static file, you render a host-specific version from a common pattern.

Add the task to your playbook.yml. Be careful with indentation!

---
- name: Deploy Web Page
  hosts: localhost
  become: yes
  vars:
    page_title: "My LabEx Web Server"
  tasks:
    - name: Create index.html from template
      template:
        src: templates/index.html.j2
        dest: /var/www/html/index.html
        mode: "0644"

Understanding the code:

  • template:: The module we are using.
  • src: The source file (our template with the placeholders).
  • dest: The destination (where the final HTML file should go).
  • mode: "0644": Sets file permissions so the web server can read it.
  • become: yes: We added this because writing to /var/www/html requires root permissions.

Save and exit the file.

Deploy and Verify

Let's run the playbook and see the magic happen.

Execute the playbook:

ansible-playbook -i inventory playbook.yml

If it works, you'll see a changed status.

Now, let's look at the final file that Ansible created. We expect the placeholders to be gone, replaced by real text.

Read the generated HTML file:

cat /var/www/html/index.html

Expected Result:

<html>
  <head>
    <title>My LabEx Web Server</title>
  </head>
  <body>
    <h1>Welcome to localhost</h1>
    <p>This file was generated by Ansible.</p>
  </body>
</html>

See? {{ page_title }} became "My LabEx Web Server" and {{ inventory_hostname }} became "localhost".

Summary

In this lab, you learned how to make your configurations dynamic.

  1. Templates: Created a .j2 file with {{ placeholders }}.
  2. Variables: Defined values in the vars section of the playbook.
  3. Magic Variables: Used inventory_hostname which Ansible provides automatically.
  4. Template Module: Used the template module to combine variables and templates into a final configuration file.

This powerful feature allows you to use a single template to configure thousands of servers, each with their own specific details.