Skip to content
Cloud Kung-Fu

Facts and Templates

3 min read

Overview

In Ansible, variables and facts, along with templates, are foundational tools for creating flexible automation workflows. Variables allow you to manage and change your configurations dynamically. Facts are a special subset of variables that Ansible gathers from the remote systems, providing context-specific information. Templates enable the generation of variable-driven configuration files, making your playbooks adaptable to varied environments and scenarios.

These tools make playbooks reusable and adaptable, allowing you to avoid hard-coding values and enabling customization for different environments.

Variables & Facts

Variables allow for parameters to be modified without altering the playbook's core logic.

How variables, facts & templates work together
  • Types of Variables:

    • Boolean: True or False values.

    • List: An ordered collection of items.

    • Dictionary: Key-value pairs for complex data structures.

    • Registered Variables: Captures the output of tasks to use later in your playbook.

    • Facts: Auto-collected variables that provide details about the remote systems you are managing.

NB: Avoid conflicts in variable names by using bracket notation.

- name: Print the distribution of the target
hosts: all
vars:
curr_time: "{{ now() }}"
tasks:
- name: Distro Check
ansible.builtin.debug:
msg: "The target system is {{ ansible_facts['distribution'] }}. Timestamp: {{ curr_time }}"

Templates & Files

Templates in Ansible use the Jinja2 templating language to dynamically create files using variable interpolation, loops, and conditionals.

- name: Write distro name
hosts: all
tasks:
- name: Write distro name
ansible.builtin.template:
src: distro.j2
dest: /root/distro.txt
mode: '644'
# src: location of jinja2 template file
# dest: location it will be copied to
# permissions that will be granted to the file

Practice

We're going to use the OS Family to determine whether to install NGINX of Lighttpd then we'll deploy a custom homepage to the remote host containing NGINX all without hardcoding hostnames.

  1. Clone the repo
git clone https://github.com/perplexedyawdie/ansible-learn.git

2. Spin up the environment using docker-compose

docker compose up -d --build

3. SSH into the Ansible server

ssh -o StrictHostKeyChecking=no -o NoHostAuthenticationForLocalhost=yes root@localhost -p 2200# password: test123

4. Change directory to ansible_learn

cd ansible_learn

Variables & facts

5. Create a playbook called server_setup.yaml. Here, we'll setup NGINX & Lighttpd then output the name of the distro for each remote host

- name: Install NGINX on Debian & Lighttpd on RedHat
hosts: all
vars:
dev1: "Debian"
dev2: "RedHat"
tasks:
- name: Install NGINX for Debian-based systems
ansible.builtin.apt:
name: nginx
state: present
when: ansible_facts['os_family'] == dev1
- name: Install Lighttpd for RedHat-based systems
ansible.builtin.yum:
name: lighttpd
state: present
when: ansible_facts['os_family'] == dev2
- name: Display the distribution
ansible.builtin.debug:
msg: "The server is running {{ ansible_facts['distribution'] }}"

6. Run ansible-lint

ansible-lint server_setup.yaml

7. Run the playbook

ansible-playbook --key-file /root/.ssh/id_rsa_ansible -u root -i inventory.yaml server_setup.yaml

8. Confirm that setup was successful

ssh -i /root/.ssh/id_rsa_ansible root@server3 nginx -V
ssh -i /root/.ssh/id_rsa_ansible root@server2 lighttpd -v
ssh -i /root/.ssh/id_rsa_ansible root@server1 lighttpd -v

Templates & Files

9. Create a Jinja2 template file called index.html.j2

It will get auto populated with the OS Family & Distribution.

<html>
<head>
<title>Welcome to {{ ansible_facts['os_family'] }}</title>
</head>
<body>
<h1>Server running on {{ ansible_facts['distribution'] }}</h1>
</body>
</html>

10. Create a playbook called custom_homepage.yaml

We're deploying the custom homepage created above to NGINX then restarting the server.

- name: Deploy Custom Homepage and restart
hosts: all
vars:
dev1: "Debian"
dev2: "RedHat"
tasks:
- name: Create Homepage with Jinja2 Template for NGINX
ansible.builtin.template:
src: index.html.j2
dest: /var/www/html/index.html
mode: '644'
when: ansible_facts['os_family'] == dev1
notify: restart nginx
handlers:
- name: Restart NGINX
listen: "restart nginx"
ansible.builtin.service:
name: nginx
state: restarted
when: ansible_facts['os_family'] == dev1

11. Run the linter

ansible-lint custom_homepage.yaml

12. Run the playbook

ansible-playbook --key-file /root/.ssh/id_rsa_ansible -u root -i inventory.yaml custom_homepage.yaml

13. Confirm deployment by visiting http://localhost:2203 in your browser.

Recap

Awesome effort! 🙌 We've learned how to use variables & facts in a playbook along with how to create dynamic files using templates. Next we'll look at modularization and error handling. Til then, take care!

© 2024 by Cloud Kung-Fu. All rights reserved.
Theme by LekoArts