Skip to content

Intermediate · Configuration management with Ansible, and YAML · topic 37 of 53 · 30 min

Roles, templates, Galaxy and Vault

Explanation

A role packs tasks, handlers, templates, files and variables into a standard folder layout, so you can reuse them across playbooks and projects. Templates use Jinja2: {{ variable }}, plus for loops and if blocks. Ansible Galaxy shares roles and collections. Ansible Vault encrypts secrets so they can live in Git safely. Terraform creates the servers; Ansible configures them.

Why roles

A playbook for one web server is fine. When you have nginx, PostgreSQL, monitoring agents and user accounts, across many projects, one long file becomes hard to read and impossible to reuse. A role is a folder with a fixed layout that bundles everything for one job, such as "nginx" or "postgres". A playbook then just lists the roles a group of hosts needs.

Think of it like this: Roles are like the departments of a hospital. Cardiology, radiology and pharmacy each have their own staff, rules and equipment in a known place. A patient's treatment plan just says which departments to visit; it does not repeat how each department works.

The role layout

output
roles/nginx/
  tasks/main.yml        # the tasks (entry point)
  handlers/main.yml     # handlers, e.g. Reload nginx
  templates/            # Jinja2 templates, e.g. site.conf.j2
  files/                # plain files copied as they are
  vars/main.yml         # role variables (high priority, rarely overridden)
  defaults/main.yml     # default variables (lowest priority, meant to be overridden)
  meta/main.yml         # author, supported platforms, dependencies on other roles
Create this skeleton with: ansible-galaxy role init roles/nginx
yaml
---
- name: Web servers
  hosts: web
  become: true
  roles:
    - common
    - nginx
    - role: node_exporter
      vars:
        node_exporter_port: 9100
site.yml using roles. Inside a role, template and copy find their files in templates/ and files/ automatically.
Tip: Put every value a user might want to change in defaults/main.yml. Because defaults have the lowest priority, group_vars or host_vars can override them without editing the role.

Jinja2 templates

Ansible templates use Jinja2, a template language. {{ name }} inserts a variable. {% for %} and {% if %} add loops and conditions. Filters change a value with a pipe, for example {{ port | default(80) }} or {{ name | upper }}. Template files usually end in .j2.

output
# templates/site.conf.j2
server {
    listen {{ http_port | default(80) }};
    server_name {{ site_name }};
    root /var/www/{{ site_name }};

{% for path in blocked_paths %}
    location {{ path }} { deny all; }
{% endfor %}
{% if enable_gzip %}
    gzip on;
{% endif %}
}
Jinja2 template for nginx. With site_name: college.edu and blocked_paths: [/admin], the output has a deny rule for /admin.

Ansible Galaxy and collections

Ansible Galaxy (galaxy.ansible.com) is a public hub where people share roles and collections. A collection is a package that bundles modules, roles and plugins under a namespace, for example community.general, amazon.aws or community.postgresql. That is why module names look like amazon.aws.ec2_instance.

bash
ansible-galaxy collection install community.general
ansible-galaxy install -r requirements.yml     # install everything listed in a file
ansible-galaxy role init roles/nginx            # create a new role skeleton
Pin versions in requirements.yml, just as you pin Terraform modules.

Ansible Vault for secrets

Playbooks need secrets: database passwords, API keys, TLS private keys. Never commit them in plain text. Ansible Vault encrypts a whole file, or a single string, with a password (AES-256). The encrypted file can live in Git; Ansible decrypts it in memory when the playbook runs.

bash
ansible-vault create group_vars/db/vault.yml    # create a new encrypted file
ansible-vault encrypt secrets.yml               # encrypt an existing file
ansible-vault edit group_vars/db/vault.yml      # edit it (decrypts in a temporary editor)
ansible-vault view group_vars/db/vault.yml
ansible-vault encrypt_string 'S3cret!' --name 'db_password'   # encrypt one value to paste into YAML
ansible-playbook site.yml --ask-vault-pass                     # or --vault-password-file ~/.vault_pass
Keep the vault password itself out of Git: in a password manager or a CI secret.

A common pattern: group_vars/db/vars.yml holds db_password: "{{ vault_db_password }}" in plain text, and group_vars/db/vault.yml (encrypted) holds vault_db_password. Anyone reading the code can see which variables exist, but not their values.

Testing roles with Molecule

Molecule is a testing tool for roles. It creates a test machine (often a container), applies the role, runs it a second time to check idempotency (no changes expected), runs checks, and then destroys the machine. molecule test runs the whole sequence. It catches broken roles before they reach real servers.

Ansible and Terraform together

TerraformAnsible
Main jobProvisioning: create networks, VMs, databases, DNSConfiguration: packages, files, users, services inside servers
StyleDeclarative, with a state fileMostly declarative modules run in order, no state file
Typical useCreate 3 VMs and a load balancerInstall nginx and deploy the site on those VMs

They work together: Terraform creates the servers and outputs their IP addresses, and Ansible (using a dynamic inventory plugin that asks the cloud for hosts, or an inventory generated from Terraform outputs) configures them. Each tool can do a little of the other's job, but each is best at its own.

AWX and Ansible Automation Platform

Running playbooks from laptops does not scale for a big team. AWX (open source) and Red Hat Ansible Automation Platform (the commercial product built from it) add a web UI and API, role-based access, stored credentials, schedules and a log of every run. Teams use them so that, for example, the support team can run an approved "restart app" job without having SSH access.

Common mistakes

Careful: Committing the vault password file, or a decrypted copy of a vault file, to Git. Add them to .gitignore and keep the password in a password manager or a CI secret.
Careful: Putting changeable settings in vars/main.yml instead of defaults/main.yml. vars has high priority, so users cannot easily override them, and they end up editing the role.
Careful: Using a variable in a template that is not defined. Ansible fails with "undefined variable". Give it a value in defaults/main.yml, or use the default filter.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Roles, templates, Galaxy and Vault · 1/7

Roles, templates and Vault

In this lesson you will organise Ansible code into roles, write templates, and keep secrets safe with Vault.

Prefer a video by a teacher? Find free videos on “ansible roles jinja2 templates ansible vault tutorial” on YouTube ↗

In real life: One nginx role for many hospital apps

A hospital IT team in Kochi runs six internal web apps: appointments, lab reports, pharmacy stock and others. Instead of six copies of the same nginx setup, they have one nginx role with defaults for the port and site name. Each app's group_vars sets its own site_name and upstream port. The TLS private keys live in vault-encrypted files in Git, and the vault password is stored only in AWX, which runs the playbooks on a schedule and keeps a log of every run for audits.

yaml
# group_vars/lab_reports/vars.yml
site_name: labreports.hospital.local
upstream_port: 8081
tls_key: "{{ vault_tls_key }}"     # the real key is in vault.yml, encrypted
Plain vars point to encrypted vault vars.

Practice (0/3 done)

Task 1 · Question

In a role, where do default values that users are expected to override go?

Task 2 · Code · Python

Render a tiny Jinja-like template. Write render(template, variables) that replaces every {{ name }} (spaces inside the braces are optional) with str(variables[name]). If a name is not in variables, raise KeyError. Nothing else needs to be supported.

Task 3 · Practice

Turn the web-server playbook from the previous lesson into a role called nginx. Write roles/nginx/defaults/main.yml, tasks/main.yml, handlers/main.yml and templates/site.conf.j2, and a site.yml that applies the role to the web group. Put a fake database password in an encrypted file with ansible-vault create and explain how you would pass the vault password in CI.

Quick quiz

Question 1

1.Which command creates the standard folder skeleton for a new role?

Question 2

2.What is a collection in Ansible?

Question 3

3.Which is the safest way to keep a database password used by a playbook?

Question 4

4.Which pairing of tools and jobs is most typical?

Question 5

5.What does Molecule mainly do?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

Which command creates the standard folder skeleton for a new role?

Answer: ansible-galaxy role init

ansible-galaxy role init NAME creates tasks, handlers, templates, defaults and the other folders.

What is a collection in Ansible?

Answer: A package of modules, roles and plugins under a namespace, like community.general

Collections are how modules are packaged and shared, for example through Galaxy.

Which is the safest way to keep a database password used by a playbook?

Answer: In an ansible-vault encrypted file, with the vault password kept outside Git

Vault-encrypted files can be committed; the vault password must stay out of Git.

Which pairing of tools and jobs is most typical?

Answer: Terraform creates the servers, Ansible configures the software on them

Terraform is strongest at provisioning, Ansible at configuration.

What does Molecule mainly do?

Answer: Tests a role on a throwaway machine, including an idempotency run

Molecule creates, converges, re-runs for idempotency, verifies and destroys a test instance.

In a role, where does the template module look for src files by default?Related

Answer: templates/

templates/ for template, files/ for copy.

From Roles, collections and ansible-galaxy

What does the first line of a vault-encrypted file start with?Related

Answer: $ANSIBLE_VAULT;

$ANSIBLE_VAULT;1.1;AES256.

From RHEL System Roles and Ansible Vault

What does ansible-playbook site.yml --check --diff do?Related

Answer: Shows what would change, with file differences, without changing anything

Check mode is a dry run; diff shows the before and after of files.

From Ansible playbooks

Which module writes a file from a Jinja2 .j2 file with variables filled in?Related

Answer: template

template renders Jinja2.

From Everyday modules and handlers

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. This is the last topic of “Configuration management with Ansible, and YAML”. The module exam comes next.
  2. Module 8 exam: Configuration management with Ansible, and YAML · 13 questions · 20 min, without help. 4 topics of this module still to finish first.
  3. Then the next module, Monitoring and logging. 53 topics left in the course before the final exam.

← Previous: Ansible playbooks