Saturday, April 26, 2025

An Ansible Journey 15: Templates

My final post will walk through the process of using a template to deliver customized files that may vary across hosts, operating systems, applications and so on. The principle is as in the prior posts, not overly difficult. It consists of:

  1. Creating the template file(s)
  2. Creating the variables with changing values to insert in those template files
  3. Adding the play to do the work
  4. Restarting any services once the change is made.

Creating the Template Files

For this exercise, we will be customizing two sshd_config files, one on Rocky Linux and one on Ubuntu. The main difference is in the content of each file. The default Rocky Linux file will not work with Ubuntu, and vice versa. 

We start by creating a templates directory under playbooks/roles/base. In that directory, we need to drop a copy of both versions of the files and give them a name that indicates to which OS they belong:

[ansadm@rocky-1 ansible]$ ls -l playbooks/roles/base/templates/
total 12
-rw-rw-r--. 1 ansadm ansadm 4297 Apr 26 16:11 sshd_config_rocky.j2
-rw-rw-r--. 1 ansadm ansadm 3282 Apr 26 16:11 sshd_config_ubuntu.j2

Ansible uses the Jinja2 templating system to manage templates. Jinja2 files use a .j2 extension.

Next, we will add the same directive to both. The portion of the sshd_config file that we are editing is identical in both versions, so I'll show that just once here:

[...]
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

AllowUsers {{ ssh_users }}
[...]

We're adding the AllowUsers directive which expects a list of usernames, separated by spaces. Since this list could change from one host to another, we'll use a variable to store the individual user names.

Variables

In each of the host variable files, we'll add some additional variables to include a list of users, the name of the template files we created above, and the sshd service name:

Rocky Linux Files:

ssh_users: "ansadm rlohman"
ssh_template_file: sshd_config_rocky.j2
ssh_service_name: sshd

Ubuntu File:

ssh_users: "ansadm rlohman"
ssh_template_file: sshd_config_ubuntu.j2
ssh_service_name: ssh


Now, just prior to copying the files out, the placeholder variable in the templates will be swapped with the ssh_users string. The ssh_template_file variable will be used to select the appropriate file to use as a template.

Adding the Play

in the playbooks/roles/base/tasks/main.yml file, we'll add the following play to execute the task:

- name: Generate sshd_config File from Template
  tags: ssh
  template:
    src: "{{ ssh_template_file }}"
    dest: /etc/ssh/sshd_config
    owner: root
    group: root
    mode: 0644
  notify: restart_sshd

There's nothing here we have not already done. The src parameter accepts a variable in place of the actual template file to use. The ownership and permissions are set according to what the configuration file has in the /etc/ssh directory.

Service Restarts

There is one additional item that we'll need to account for. the service name between the two is also different. Ubuntu uses ssh.service, whereas Rocky uses sshd.service. That is handled by our last variable, ssh_service_name, in the restart_sshd handler. We again use the notify directive to call the handler once the change is registered.

And with that, our configuration for sshd is now templatized (read, quickly and easily customized) for our servers.

<PREV - CONTENTS

No comments:

Post a Comment