Sobes.tech
Middle

What is your experience with handlers and role templates in DevOps?

sobes.tech AI

Answer from AI

I extensively used handlers and templates in configuration management systems such as Ansible.

Handlers

Handlers are tasks that are executed only if notified by other tasks when a change occurs. This ensures that resource-intensive or service-restarting operations are performed only when necessary. For example, restarting a web server after updating its configuration files.

Example in Ansible:

---
- name: Install Nginx
  apt:
    name: nginx
    state: present

- name: Copy Nginx config
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: Restart Nginx

- name: Restart Nginx # Handler definition
  service:
    name: nginx
    state: restarted
  listen: Restart Nginx

In this example, the task "Copy Nginx config" uses notify: Restart Nginx to notify, and the "Restart Nginx" handler will execute only if the configuration file was changed. listen: Restart Nginx links the handler to the notification.

Templates

Templates are used for dynamically creating configuration files on target nodes. They allow the use of variables, conditions, and loops to generate unique files for each node or group of nodes. I actively use Jinja2-based templates in Ansible to generate:

  • Web server configuration files (Nginx, Apache).
  • Application configuration files (e.g., database settings files).
  • Service initialization scripts.
  • Arbitrary text files with dynamic content.

Example of a Jinja2 template (nginx.conf.j2):

worker_processes {{ ansible_processor_vcpus }};
events {
    worker_connections {{ max_connections | default('1024') }};
}
http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    server {
        listen {{ http_port | default('80') }};
        server_name {{ server_name }};
        location / {
            root {{ app_root }};
            index index.html index.htm;
        }
    }
}

Here, variables like {{ ansible_processor_vcpus }}, {{ max_connections }}, {{ http_port }}, {{ server_name }}, {{ app_root }} are used, which can be defined in the Ansible inventory or playbook.

Roles

Roles in Ansible are a way to organize playbooks and related files (variables, templates, task files) into reusable and structured units. This greatly improves readability, manageability, and reusability of code. I use roles to encapsulate the logic for installing and configuring specific system components, such as:

  • A role for installing and configuring a web server.
  • A role for installing and configuring a database.
  • A role for deploying an application.
  • A role for system parameter configuration (firewall, SELinux).

Typical role structure:

my-role/
├── defaults/             # Default variables
│   └── main.yml
├── handlers/             # Handlers
│   └── main.yml
├── meta/               # Role dependency information
│   └── main.yml
├── tasks/              # Main tasks of the role
│   └── main.yml
├── templates/          # Templates
│   └── my.conf.j2
├── files/              # Static files
│   └── my_script.sh
└── vars/               # Role-level variables
    └── main.yml

Using roles significantly simplifies creating complex playbooks and allows easy reuse of existing logic across projects. It is a key element in building scalable and maintainable infrastructure solutions.