Introduction

Writing efficient conditional logic in Ansible often means leveraging Jinja2 templating. One particularly powerful feature is the ternary operator, which helps you choose between two values based on a condition. However, many users encounter the dreaded error:

template error while templating string: unexpected character

This article walks through the correct way to use ternary expressions in Ansible using Jinja2 filters and shows how to avoid common pitfalls.

The Problem: Using JavaScript-style Ternary in Ansible

If you’ve ever written something like this in your Ansible playbook or template:

{{ env == 'dev' ? 'localhost' : 'db.prod.internal' }}

You’ve likely been met with a syntax error. That’s because Jinja2 does not support this JavaScript-style ternary operator. Instead, Ansible uses a different syntax via the ternary filter.

The Correct Way: Use the ternary Filter

To properly use conditional logic in Ansible, wrap your condition in parentheses and apply the ternary() filter:

{{ (env == 'dev') | ternary('localhost', 'db.prod.internal') }}

This line says: if env is 'dev', return 'localhost'; otherwise, return 'db.prod.internal'.

Example Use Case in a Template

Suppose you’re building an .env.j2 file and want to set the database host depending on the environment:

DB_HOST={{ (env | default('prod')) == 'dev' | ternary('localhost', 'db.prod.internal') }}

This ensures the condition works even if env isn’t defined.

Common Mistakes and Fixes

MistakeWhy it’s wrongCorrect Syntax
env == 'dev' ? 'a' : 'b'Not valid Jinja2`(env == ‘dev’)
Missing parenthesesJinja2 parses it incorrectlyAlways use parentheses around the condition
Forgetting `beforeternary`ternary is a filter, not a function

Debugging Tips

  • Use debug tasks to check expressions:
    - debug:
        msg: "{{ (my_var is defined) | ternary(my_var, 'default') }}"
    
  • Pipe | type_debug to see what kind of data you’re working with.

Why Use Ternary?

The ternary operator in Jinja2 helps you:

  • Avoid verbose if-else blocks in templates.
  • Keep playbooks and configuration files cleaner.
  • Make conditional assignments more readable.

Conclusion

When used correctly, the ternary operator can drastically improve the clarity and maintainability of your Ansible playbooks and templates. Avoid syntax errors by remembering: wrap the condition in parentheses and use the | ternary(true_value, false_value) filter. Stick to this structure, and you’ll avoid the classic unexpected character template error for good.

Subscribe to the YouTube channel, Medium, and Website, X (formerly Twitter) to not miss the next episode of the Ansible Pilot.

Academy

Learn the Ansible automation technology with some real-life examples in my
Udemy 300+ Lessons Video Course.

BUY the Complete Udemy 300+ Lessons Video Course

My book Ansible By Examples: 200+ Automation Examples For Linux and Windows System Administrator and DevOps

BUY the Complete PDF BOOK to easily Copy and Paste the 250+ Ansible code

Want to keep this project going? Please donate

Patreon Buy me a Pizza