Skip to main content
๐ŸŽ“ Claude Code Masterclass Learn AI-assisted development on Udemy โ€” plus the companion book on Leanpub & Amazon. Start Learning
Ansible assert module guide for production validation
Automation

Ansible Assert Module: Validate Variables and

The Ansible assert module catches misconfigurations before they reach production. Learn how to validate variables, facts, network reachability, disk.

LB
Luca Berton
ยท 1 min read

Why Assert Before You Deploy

The ansible.builtin.assert module is your last line of defense before a playbook makes changes to production systems. It evaluates conditions and fails the play immediately if any condition is false โ€” before any damage is done.

Think of it as a pre-flight checklist: verify the target host meets all requirements before applying configuration changes.

Basic Syntax

- name: Ensure minimum Ansible version
  ansible.builtin.assert:
    that:
      - "ansible_version.full is version('2.14', '>=')"
    fail_msg: "Ansible 2.14+ required. Found {{ ansible_version.full }}"
    success_msg: "Ansible version {{ ansible_version.full }} meets requirements"

Key parameters:

  • that โ€” list of conditions (all must be true)
  • fail_msg โ€” custom error message on failure
  • success_msg โ€” optional message on success
  • quiet โ€” suppress success output (boolean, default false)

Validate Required Variables

The most common use case โ€” ensure variables are defined and non-empty before using them:

- name: Validate deployment variables
  ansible.builtin.assert:
    that:
      - app_version is defined
      - app_version | length > 0
      - deploy_env is defined
      - deploy_env in ['staging', 'production']
      - db_host is defined
      - db_port | int > 0
    fail_msg: >
      Missing or invalid deployment variables.
      app_version={{ app_version | default('UNDEFINED') }},
      deploy_env={{ deploy_env | default('UNDEFINED') }},
      db_host={{ db_host | default('UNDEFINED') }}

Validate Host Facts

Check that the target system meets hardware and OS requirements:

- name: Gather facts
  ansible.builtin.setup:

- name: Validate target system
  ansible.builtin.assert:
    that:
      - ansible_os_family == "RedHat"
      - ansible_distribution_major_version | int >= 9
      - ansible_memtotal_mb >= 4096
      - ansible_processor_vcpus >= 2
      - ansible_mounts | selectattr('mount', 'equalto', '/') | map(attribute='size_available') | first | int > 5368709120
    fail_msg: >
      Host does not meet requirements:
      OS={{ ansible_distribution }} {{ ansible_distribution_version }},
      RAM={{ ansible_memtotal_mb }}MB (need 4096MB),
      CPUs={{ ansible_processor_vcpus }} (need 2),
      Root disk free={{ (ansible_mounts | selectattr('mount', 'equalto', '/') | map(attribute='size_available') | first | int / 1073741824) | round(1) }}GB (need 5GB)

Validate Network Connectivity

Check that required services are reachable before configuring clients:

- name: Check database connectivity
  ansible.builtin.wait_for:
    host: "{{ db_host }}"
    port: "{{ db_port }}"
    timeout: 5
  register: db_check
  ignore_errors: true

- name: Assert database is reachable
  ansible.builtin.assert:
    that:
      - db_check is success
    fail_msg: "Cannot reach database at {{ db_host }}:{{ db_port }}"

- name: Check API endpoint
  ansible.builtin.uri:
    url: "https://{{ api_host }}/healthz"
    method: GET
    status_code: 200
    timeout: 10
  register: api_check
  ignore_errors: true

- name: Assert API is healthy
  ansible.builtin.assert:
    that:
      - api_check.status == 200
    fail_msg: "API health check failed: {{ api_check.msg | default('unreachable') }}"

Validate Kubernetes Prerequisites

Before deploying to Kubernetes, verify the cluster is ready:

- name: Get cluster info
  kubernetes.core.k8s_cluster_info:
  register: cluster_info

- name: Assert Kubernetes version
  ansible.builtin.assert:
    that:
      - cluster_info.version.server.kubernetes.major | int >= 1
      - cluster_info.version.server.kubernetes.minor | int >= 28
    fail_msg: "Kubernetes 1.28+ required. Found {{ cluster_info.version.server.kubernetes.gitVersion }}"

- name: Check namespace exists
  kubernetes.core.k8s_info:
    api_version: v1
    kind: Namespace
    name: "{{ deploy_namespace }}"
  register: ns_check

- name: Assert namespace exists
  ansible.builtin.assert:
    that:
      - ns_check.resources | length > 0
    fail_msg: "Namespace {{ deploy_namespace }} does not exist"

Validate File and Directory State

- name: Check SSL certificate exists
  ansible.builtin.stat:
    path: /etc/ssl/certs/app.crt
  register: cert_file

- name: Assert certificate is present and not expired soon
  ansible.builtin.assert:
    that:
      - cert_file.stat.exists
      - cert_file.stat.size > 0
    fail_msg: "SSL certificate missing at /etc/ssl/certs/app.crt"

- name: Get certificate expiry
  ansible.builtin.command: >
    openssl x509 -enddate -noout -in /etc/ssl/certs/app.crt
  register: cert_expiry
  changed_when: false

- name: Assert certificate not expiring within 30 days
  ansible.builtin.assert:
    that:
      - "'notAfter' in cert_expiry.stdout"
    fail_msg: "Certificate expiry check failed: {{ cert_expiry.stdout }}"

Using Assert in Roles

Create a validate.yml task file that runs before the main role tasks:

# roles/webserver/tasks/validate.yml
- name: Validate webserver role variables
  ansible.builtin.assert:
    that:
      - webserver_port | int > 0
      - webserver_port | int < 65536
      - webserver_document_root is defined
      - webserver_ssl_enabled is defined
      - webserver_ssl_enabled | bool or not webserver_force_https | default(false) | bool
    fail_msg: "Invalid webserver configuration. Check role variables."
    quiet: true
# roles/webserver/tasks/main.yml
- name: Run validation
  ansible.builtin.include_tasks: validate.yml

- name: Install web server
  ansible.builtin.dnf:
    name: nginx
    state: present
# ... rest of role

Assert with Loops

Validate multiple items:

- name: Validate all required services are running
  ansible.builtin.assert:
    that:
      - "item in ansible_facts.services"
      - "ansible_facts.services[item].state == 'running'"
    fail_msg: "Service {{ item }} is not running"
    quiet: true
  loop:
    - sshd.service
    - firewalld.service
    - chronyd.service

Assert vs Fail + When

These are equivalent:

# Using assert
- ansible.builtin.assert:
    that:
      - disk_free_gb | int > 10
    fail_msg: "Not enough disk space"

# Using fail + when
- ansible.builtin.fail:
    msg: "Not enough disk space"
  when: disk_free_gb | int <= 10

Use assert when you have multiple conditions to check โ€” it is cleaner than nested when clauses. Use fail + when for simple single-condition checks.

Production Validation Playbook Template

---
- name: Pre-deployment validation
  hosts: "{{ target_hosts }}"
  gather_facts: true
  tasks:
    - name: OS validation
      ansible.builtin.assert:
        that:
          - ansible_os_family in ['RedHat', 'Debian']
          - ansible_distribution_major_version | int >= 9 or ansible_distribution == 'Ubuntu'
        fail_msg: "Unsupported OS: {{ ansible_distribution }} {{ ansible_distribution_version }}"

    - name: Resource validation
      ansible.builtin.assert:
        that:
          - ansible_memtotal_mb >= min_memory_mb | default(2048)
          - ansible_processor_vcpus >= min_cpus | default(2)
        fail_msg: "Insufficient resources: {{ ansible_memtotal_mb }}MB RAM, {{ ansible_processor_vcpus }} CPUs"

    - name: Variable validation
      ansible.builtin.assert:
        that:
          - app_version is defined and app_version | length > 0
          - deploy_env is defined and deploy_env in allowed_environments
        fail_msg: "Invalid deployment variables"

    - name: Connectivity validation
      ansible.builtin.wait_for:
        host: "{{ item.host }}"
        port: "{{ item.port }}"
        timeout: 5
      loop: "{{ required_endpoints }}"
      loop_control:
        label: "{{ item.host }}:{{ item.port }}"

  post_tasks:
    - name: All validations passed
      ansible.builtin.debug:
        msg: "Pre-deployment validation complete. Safe to proceed."

Building reliable automation pipelines? I help teams design Ansible automation with proper validation, testing, and production safeguards.

Book a Consultation โ†’

Free 30-min AI & Cloud consultation

Book Now