Home
Blog
The Ultimate Guide to Ansible Conditionals for Smarter Automation

The Ultimate Guide to Ansible Conditionals for Smarter Automation

Sam Gabrail
President, TeKanAid
with special guest
Mitchell
Hashimoto
Mitchell Hashimoto headshot

Introduction

Overview of Ansible and its Role in Automation

Ansible is an open-source automation tool designed to simplify IT workflows such as configuration management, application deployment, and orchestration. Its agentless architecture makes it lightweight and easy to use, enabling teams to manage infrastructure at scale without installing additional software on managed nodes. Ansible ensures repeatable, predictable automation outcomes.

Importance of Ansible Conditionals in Playbooks

Conditionals in Ansible provide a dynamic and flexible way to execute tasks based on predefined criteria. They allow users to adapt playbooks to various environments, operating systems, or configurations, making automation more intelligent and versatile. For instance, you can configure tasks to behave differently on Ubuntu versus CentOS, or skip steps based on task outputs.

Purpose of this Guide

This guide deep-dives into Ansible conditionals and explains how to use them effectively in playbooks. From simple “when” statements to advanced scenarios like multiple conditions, registered variables, and OS-specific tasks, this guide equips you with the knowledge to create smarter automation workflows.

Understanding Ansible Conditional Statements with Ansible "when" Statements

What Are Conditional Statements in Ansible?

Conditional statements in Ansible are logical expressions used to control task execution based on specific criteria. They ensure that tasks run only when certain conditions are met, making playbooks more adaptive and efficient. For example, a task might execute only if the target host runs a specific operating system or meets a variable's value.

Ansible’s simplicity lies in its declarative syntax, and conditional statements play a significant role in this by reducing unnecessary complexity. For instance, instead of creating separate playbooks for different environments, you can use conditionals to handle diverse scenarios in a single playbook. Keep in mind that the simplest conditional statement applies to a single task.

Basic Syntax of Conditional Statements Using the "when" Keyword in Ansible

The “when” keyword introduces conditional logic in Ansible tasks. The “when” statement is a conditional statement that runs a particular task if a condition is met. In other words, it evaluates a condition and, if true, allows the task to execute.

Example: Simple "when" Statement

Here’s a basic example of using a "when" condition:


The above example illustrates how to apply conditional statements within Ansible playbooks:

  • The task runs only if the "ansible_os_family" fact equals "Debian"
  • The "when" condition evaluates a fact collected by Ansible during its setup phase

Key Points About the "when" Statement

  1. Dependency on Facts or Variables: "When" conditions often rely on Ansible facts, variables, or outputs from prior tasks. It is crucial to define variables to create flexible and dynamic playbooks, allowing for conditional statements that enhance task execution based on specific conditions. More on that in our blog post: Mastering Ansible Variables: Practical Guide with Examples.
  2. Flexibility: Supports logical operators (and, or, not) to create complex conditions.
  3. Scalability: Simplifies managing large inventories by dynamically adjusting tasks based on host-specific attributes.

Using Ansible Conditionals with Multiple Conditions

Combining Multiple Conditions

In many automation scenarios, tasks must meet more than one condition to execute. Ansible allows combining conditions using logical operators to create complex and precise conditional statements.

Logical Operators in Ansible:

  1. and: Ensures all conditions are true
  2. or: Requires at least one condition to be true
  3. not: Negates a condition

Example: Combining Conditions

Here’s how you can use more than one condition in a task:


In this example:

  • The task executes only if the system is Debian-based (ansible_os_family "Debian") and the version is 10 (ansible_distribution_version "10")

Using "or" for Alternatives


Practical Applications of Multiple Conditions

Environment-Specific Automation

Tasks can be tailored to different environments, such as staging, production, or testing.


Conditional Debugging or Logging

Enable debug tasks based on the environment or a specific flag using the debug module:


Tips for Combining Conditions

  1. Use parentheses to group complex conditions for better readability:
  1. Test conditions with smaller examples before integrating them into larger playbooks.

By leveraging multiple conditions, you can create intelligent workflows that adapt seamlessly to varied environments and requirements. Let’s explore how Ansible facts enhance conditional execution.

Working with Ansible Facts

Conditionals Based on ansible_facts

Ansible facts are automatically gathered data about target nodes, such as the operating system, IP address, architecture, and more. These facts are invaluable for writing condition-based tasks that adapt dynamically to various environments.

Example: Using ansible_facts


In this example:

  • The os_family fact is used to verify the system’s OS type before installing Apache

Examples of Common Facts

  1. ansible_os_family: Identifies the OS family (e.g., Debian, RedHat)
  2. ansible_distribution: Specifies the OS distribution (e.g., Ubuntu, CentOS)
  3. ansible_architecture: Indicates the system architecture (e.g., x86_64, arm64)
  4. ansible_default_ipv4.address: Fetches the default IPv4 address

You can find out more about it in the Ansible documentation.

Practical Use:


Please note that the syntax {{ 'value1' if condition else 'value2' }} is valid Jinja2 templating syntax, which Ansible uses for variable interpolation and conditionals. This is not a native Ansible conditional since Ansible does not have an if-else conditional statement, as we will see later on.

Using Facts to Select Variables, Files, or Templates

Facts can influence variable values, determine file paths, or select templates for deployment. This has less to do with conditionals and more with variables, but we include it here for completeness. To learn more about Ansible Variables, check out the blog post: Mastering Ansible Variables: Practical Guide with Examples.

Example: Using Facts to Load Different Packages


This task installs the Apache2 and nginx packages on systems running Ubuntu. The loop iterates over the package names, and the when condition ensures the task runs only if the operating system is Ubuntu.

Example: File Selection Based on Facts


This ensures that the correct configuration file is deployed based on the operating system.

Loading Custom Facts for Conditional Use

Ansible allows you to define custom facts and use them in conditionals. Custom facts are typically stored in JSON or key-value format and placed under /etc/ansible/facts.d/ on the managed host.

Example: Using a Custom Fact


This example demonstrates how to load and use a custom fact in Ansible:

  1. Load Custom Facts:
    The setup module gathers facts from the target node and is filtered to include only custom_fact. This ensures that Ansible explicitly gathers the specific custom_fact, which might not be automatically included or may have changed during the playbook execution. It ensures accuracy and focuses on relevant data with the filter option.
  2. Conditional Task Execution:
    The debug task runs only if the value of the custom_fact matches "expected_value." The condition is defined using the when keyword.

By leveraging Ansible facts, you can craft highly flexible and efficient playbooks that adjust to the unique characteristics of each managed node. Next, we’ll explore conditionals specifically tailored to operating systems.

Using Ansible Register and Conditionals Based on Previous Tasks

Using Output from Previous Tasks

The register keyword in Ansible captures the result of a task, making it available for conditional use in subsequent tasks. This enables the creation of dynamic playbooks that adapt based on the success, failure, or output of earlier tasks, and apply these results to other tasks.

Example: Capturing Task Output with register


Here:

  1. The first task checks for the existence of /tmp/sample.txt and stores the result in file_status.
  2. The second task creates the file only if it does not already exist (not file_status.stat.exists).

Creating Dependencies with Registered Variables

Registered variables allow tasks to depend on the outcomes of previous tasks. For example, you can execute tasks conditionally based on whether earlier tasks succeeded, failed, or returned specific values.

Example: Using Registered Variables for Dependencies


Here:

  • The connectivity_check.rc field stores the return code of the curl command
  • If the return code is non-zero (indicating failure), a debug message is displayed

Integrating Ansible when Fail

Tasks That Only Run on Failure

Ansible’s “when” condition can be combined with the failed status of tasks to execute specific actions when a preceding task fails. This is particularly useful for implementing fallback mechanisms, error handling, or notifications.

Example: Handling Task Failures


In this example:

  1. The restart_result variable captures the outcome of the web server restart
  2. If the task fails (restart_result.failed), the mail task sends an email notification to the admin
  3. Notice we used an ansible registered variable in the first task

Practical Example: Reusing Registered Outputs

Registered variables can also be reused across multiple tasks to streamline workflows.

Example:


By leveraging the register keyword and subsequent conditionals, you can create interconnected tasks that intelligently respond to system states and task outcomes.

Integrating Conditionals in Loops

Using Conditionals with Loops

Ansible allows you to combine loops with conditional logic to iterate over items dynamically based on specific criteria. This is especially useful when applying tasks to a subset of hosts, packages, or configurations that meet certain conditions.

Example: Applying a Task Conditionally Within a Loop


In this example:

  • The loop iterates through a list of packages
  • The “when” condition ensures the task runs only if the target system uses Ubuntu

Practical Examples

Example 1: Filtering Items in a Loop

You can use conditionals to filter items within a loop dynamically.


Here:

  • Only users with the shell /bin/bash are added to the system

Example 2: Loop with Registered Variables

You can iterate over a list of items, register results for each iteration, and apply conditionals based on the output.


Here:

  1. The stat module checks the existence of files
  2. Results are registered and iterated over with the when condition checking for missing files
  3. with_items:
    • Iterates over the file_check.results, which is the list of registered outputs from the previous task
    • Each item in file_check.results contains:
      • item: The file path used in the stat module (e.g., /etc/passwd)
      • stat: Metadata about the file, including whether it exists
  4. item.item:
    • Refers to the file path being processed in the current iteration
    • The first item refers to the current iteration object, and the second item (e.g., item.item) accesses the original file path stored during the stat task
  5. when:
    • Evaluates not item.stat.exists to check if the file does not exist
    • If the file is missing, the debug message logs the file path

Example Output:
For the given file paths, the output might look like this:


How to Implement Ansible If Else Logic

Ansible’s Approach to if-else Logic

Ansible does not natively support an if-else construct as seen in traditional programming languages. However, similar functionality can be achieved by using multiple tasks with the when condition to handle different scenarios.

Equivalent Logic with Multiple Tasks

You can implement conditional branches by creating separate tasks for each condition, each guarded by a when statement.

Example: if-else Logic Using when


Here:

  • The first task acts as the if block, running only on Ubuntu
  • The second task acts as the else block, running only on CentOS

Nested Conditions for Complex Logic

To handle more intricate scenarios, you can use multiple when conditions with logical operators like "and" or "or".

Example: Simulating else-if


Combining Multiple Conditions with default Fallback

When you want to ensure a fallback condition (similar to an else statement), you can structure your tasks like this:


Practical Example: Conditional File Permissions


Best Practices for If-Else Logic in Ansible

  1. Use Separate Tasks: Clearly separate conditions into individual tasks for better readability
  2. Avoid Over-Nesting: Keep logic simple by avoiding deeply nested conditions
  3. Test for Unsupported Cases: Include a fallback task for scenarios not covered by specific conditions

By using multiple tasks with when conditions, you can replicate the behavior of if-else statements in Ansible, ensuring clear, maintainable, and adaptable playbooks. Next, we’ll explore conditionals in roles and templates for more dynamic automation.

Using Conditionals with Ansible Roles and Templates

Conditionals in Roles

Roles in Ansible are a way to organize and encapsulate all the tasks, variables, and handlers for reusability and maintainability. You can include or skip entire roles based on conditions using the “when” keyword.

Example: Conditional Role Inclusion


In this example:

  • The web server role is included only for Debian-based systems
  • This approach helps maintain clean and modular playbooks by loading roles conditionally

Dynamic Templates with Jinja2

Jinja2 templates in Ansible allow for powerful dynamic configuration generation using conditionals directly within the template files.

Example: Conditional Logic in Jinja2 Templates


When applied, the template dynamically adjusts its content based on the target system’s ansible_os_family.

Template Application


Deploying Conditional Templates

Templates can be used in playbooks to manage OS-specific configurations or adapt to runtime variables.

Example: Deploying Templates with Conditions


Here:

  • Separate templates are deployed based on the operating system
  • This ensures configurations are tailored for each target environment

Why Ansible Shines with env0

Combining Ansible’s automation prowess with env0’s advanced orchestration and governance capabilities transforms infrastructure management into a seamless, efficient process. Together, they empower teams to streamline workflows, enhance collaboration, and maintain robust compliance.

Key Benefits of Integrating Ansible with env0

  1. Simplified automation: env zero eliminates the need to manually run Ansible commands via the CLI. You can define and manage environments directly in env0, streamlining deployments, minimizing errors, and ensuring consistency across the board.
  2. Effortless template management: With env0, managing Ansible templates becomes straightforward. Templates can define essential configurations like Ansible versions, SSH keys, and other environment-specific details, ensuring deployments meet organizational standards effortlessly.
  3. Robust GitHub integration: env0’s integration with GitHub allows you to link environments directly to your repositories. By specifying the folder containing your Ansible playbooks, env zero ensures that configurations are always accessible and up to date.
  4. Dynamic variable handling: Managing environment variables, such as ANSIBLE_CLI_inventory, is made easy with env0. This ensures Ansible can dynamically locate and use the appropriate inventory files, reducing complexity in deployment processes.
  5. End-to-end automation: env zero automates the entire deployment lifecycle. From cloning repositories and setting up working directories to loading variables and running playbooks, env zero handles repetitive tasks, allowing teams to focus on higher-value activities.
  6. Enhanced governance and collaboration: Built-in RBAC and OPA policies in env zero ensure deployments are secure and compliant. Teams can collaborate effectively, with granular access controls and real-time activity tracking providing clarity and accountability.
  7. Comprehensive logs and monitoring: env zero provides detailed deployment logs, making it easier to verify configurations, troubleshoot issues, and monitor playbook execution. This transparency improves reliability and accelerates problem resolution.
  8. Multi-tool flexibility: env zero supports integrating Ansible with other IaC tools like Terraform, OpenTofu, Pulumi, or CloudFormation. This flexibility enables teams to leverage the right tools for specific tasks while maintaining a unified workflow.

By integrating Ansible with env0, teams can simplify complex workflows, improve efficiency, and ensure compliance without compromising flexibility. Whether you’re managing simple configurations or orchestrating intricate deployments, env zero enhances the Ansible experience by taking care of operational overhead, leaving teams free to focus on innovation.

FAQs

What is the “when” condition in Ansible?
The “when” condition in Ansible allows tasks to execute only when specified criteria are met. For example, you can ensure a task runs only if the operating system is Ubuntu:

Is there an if-else statement in Ansible?
No, Ansible does not natively support if-else. However, equivalent functionality can be achieved using multiple tasks with when conditions. For example:

How do I use the register variable in Ansible?
The register keyword captures the output of a task, which can then be referenced in subsequent tasks. For instance:

How do I combine multiple conditions in Ansible?
Use logical operators like "and," "o,r" and "not" to combine multiple conditions. For example:

Can I use custom facts in Ansible?
Yes, you can create and use custom facts for conditional execution. These facts can be stored in JSON or INI files on the target hosts. For example, create a custom fact file /etc/ansible/facts.d/my_facts.fact with the following content:

Then use it in a playbook:

Schedule a technical demo
See env zero in action
Schedule demo

Related Content

All articles