Conditionals Usage in Ansible Playbook

Last updated: June 29, 2025

My Journey with Conditionals in Ansible

When I first started with Ansible, my playbooks were pretty straightforward—install a package, copy some files, restart a service. But as my infrastructure grew more complex, I realized that I needed my automation to be smarter and more adaptable. That's when I discovered the power of conditionals in Ansible playbooks.

Learning to use conditionals effectively was a game-changer in my automation journey. Instead of writing separate playbooks for different environments or scenarios, I could create a single, intelligent playbook that could make decisions based on facts, variables, and previous task results. This approach dramatically reduced duplication in my code and made my automation much more maintainable.

In this blog post, I'll share my experience with using conditionals in Ansible playbooks, with practical examples for both Linux and Windows environments. Whether you're managing a handful of servers or a complex multi-platform infrastructure, mastering conditionals will take your Ansible automation to the next level.

Understanding Conditionals in Ansible

Conditionals in Ansible let you control the execution flow of your playbooks by making tasks run only when certain conditions are met. This is similar to if/elif/else statements in traditional programming languages, but with Ansible's declarative approach.

The most common way to implement conditionals in Ansible is through the when statement, which uses Jinja2 expressions to evaluate conditions. Unlike other places where you'd use Jinja2 syntax in Ansible, you typically don't need to surround expressions with {{ }} in a when statement.

Basic Conditionals with When

The when statement is the foundation of conditional execution in Ansible. Here's a simple example from my early days of using conditionals:

---
- name: Install appropriate web server based on OS
  hosts: all
  tasks:
    - name: Install Apache on Debian/Ubuntu systems
      apt:
        name: apache2
        state: present
      when: ansible_facts['os_family'] == "Debian"

    - name: Install Apache on RHEL/CentOS systems
      yum:
        name: httpd
        state: present
      when: ansible_facts['os_family'] == "RedHat"
      
    - name: Install IIS on Windows systems
      win_feature:
        name: Web-Server
        state: present
      when: ansible_facts['os_family'] == "Windows"

In this example, the appropriate web server installation task runs only on systems that match the specified OS family. Tasks with conditions that evaluate to false are skipped completely.

Comparison Operators

Conditions in Ansible use standard comparison operators that you might recognize from other programming languages:

  • == - Equal to

  • != - Not equal to

  • > - Greater than

  • < - Less than

  • >= - Greater than or equal to

  • <= - Less than or equal to

Here's an example checking disk space before performing a large file operation:

Conditionals Based on Ansible Facts

One of the most powerful uses of conditionals is with Ansible facts. Facts are pieces of information about your managed hosts that Ansible gathers automatically when running playbooks.

Here's an example from a cross-platform automation project I worked on:

Multiple Conditions

You can use logical operators to combine multiple conditions:

  • and - Both conditions must be true

  • or - Either condition can be true

  • not - Inverts the condition

For complex conditions, you can use parentheses to group expressions or use a list format for improved readability:

Conditionals Based on Registered Variables

Another powerful way to use conditionals is with the register directive, which lets you capture the output from one task and use it to make decisions in subsequent tasks.

Here's a real-world example I use to check if a service is running before attempting to restart it:

In Windows environments, I often use PowerShell to gather information that influences subsequent tasks:

Testing for Success, Failure, or Change

Ansible provides special tests for registered variables:

  • when: result is success - Task ran successfully (return code 0)

  • when: result is failed - Task failed (return code not 0)

  • when: result is changed - Task made changes

  • when: result is skipped - Task was skipped

Here's how I use these in my playbooks:

Conditionals Based on Variables

You can also use variables defined in your inventory, playbooks, or vars files as the basis for conditionals.

Boolean Variables

Boolean variables make for clean, readable conditionals:

Testing for Variable Definition

Sometimes you need to check if a variable is defined before using it:

This pattern is particularly useful when you have optional configurations or when you're building playbooks that can be customized via extra vars.

Advanced Conditional Techniques

Over time, I've developed some more sophisticated conditional techniques that have proven invaluable in complex automation scenarios.

Using Blocks with Conditionals

The block directive lets you apply a condition to multiple tasks at once, which can make your playbooks more readable and maintainable:

Error Handling with Rescue and When

You can combine conditionals with Ansible's error handling features for more robust playbooks:

This pattern has saved me many times in production environments where operations might fail and need alternative approaches.

Sequence Diagram: Conditional Execution Flow

To visualize how conditionals affect the execution flow in Ansible playbooks, I've created this sequence diagram:

spinner

This diagram illustrates how Ansible evaluates conditions before executing each task, and how the results of previous tasks can influence subsequent conditional evaluations.

Best Practices for Using Conditionals

Through my experience with Ansible, I've developed these best practices for working with conditionals:

1. Keep Conditions Simple and Readable

Break complex conditions into smaller, more manageable pieces:

Group related tasks under a single condition using blocks:

3. Consider Variable Types

Be mindful of variable types, especially when comparing numbers:

4. Test Conditions Before Deployment

Use ansible-playbook --check with liberal debug statements to verify your conditions are evaluating as expected:

Real-World Examples

Here are some examples from my actual automation projects that demonstrate the power of conditionals in Ansible:

Cross-Platform Package Installation

Environment-Specific Configuration

Self-Healing Infrastructure

One of my favorite uses of conditionals is creating self-healing infrastructure:

Conclusion

Mastering conditionals has transformed how I approach Ansible automation. Instead of creating separate playbooks for different scenarios, I now build intelligent, adaptive playbooks that respond to the actual state of my infrastructure.

Conditionals make Ansible playbooks more powerful, flexible, and maintainable. They allow you to handle edge cases gracefully, adapt to different environments, and implement sophisticated automation logic without leaving the comfort of Ansible's declarative approach.

As you build your own automation, I encourage you to experiment with conditionals. Start simple, and as you gain confidence, you'll find yourself handling increasingly complex scenarios with elegant, readable code. The path to truly powerful automation is through smart, conditional execution.

Last updated