Skip to content

🐛 Ansible 12.0.0 breaks deployments: String to boolean conversion error in conditionals #14833

@dguido

Description

@dguido

Bug Description

Algo deployments are failing after the recent Ansible 12.0.0 update (PR #14832, commit 1a2795b) due to strict type checking that no longer allows string values in boolean conditionals.

Error Message

TASK [common : Iptables configured]
[ERROR]: Task failed: Conditional result (True) was derived from value of type 'str' at 
'/Users/incertia/algo/roles/common/tasks/facts.yml:16:19'. Conditionals must have a boolean result.

failed: [142.93.230.102] (item={'src': 'rules.v6.j2', 'dest': '/etc/iptables/rules.v6'}) => {
    "msg": "Task failed: Conditional result (True) was derived from value of type 'str' at 
    '/Users/incertia/algo/roles/common/tasks/facts.yml:16:19'. Conditionals must have a boolean result."
}

Affected Versions

  • Ansible version: 12.0.0 (updated from 11.9.0 yesterday)
  • Deployment target: All providers (confirmed on DigitalOcean)
  • Host OS: macOS, likely affects all platforms

Root Cause Analysis

Ansible 12.0.0 introduced a breaking change that enforces strict boolean type checking in conditionals. String values like "true" and "false" are no longer automatically converted to booleans.

Affected Code

Primary Issue

File: roles/common/tasks/facts.yml:16

# Current (produces string "true" or "false")
ipv6_support: "{% if ansible_default_ipv6['gateway'] is defined %}true{% else %}false{% endif %}"

Used in: roles/common/tasks/iptables.yml:21

when: ipv6_support  # Expects boolean, receives string

Secondary Issues

File: input.yml (lines 120, 124, 133, 137, 141)

# These all produce string "false" in their fallback cases:
algo_ondemand_cellular: >-
  {% if ondemand_cellular is defined %}{{ ondemand_cellular | bool }}
  {%- elif _ondemand_cellular.user_input is defined %}{{ booleans_map[_ondemand_cellular.user_input] | default(defaults['ondemand_cellular']) }}
  {%- else %}false{% endif %}  # ← String "false", not boolean

Impact Scope

  • 6 variables producing string booleans instead of native booleans
  • 30+ usage locations across the codebase
  • All new deployments fail at the iptables configuration stage
  • Affects core functionality: IPv6 support, DNS ad blocking, SSH tunneling

Proposed Fix

Phase 1: Immediate Hotfix (for v2.0.1)

Fix the source of string boolean values:

# roles/common/tasks/facts.yml:16
# FIXED: Produces actual boolean
ipv6_support: "{{ ansible_default_ipv6['gateway'] is defined }}"
# input.yml lines 120, 124, 133, 137, 141
# FIXED: Use boolean false instead of string "false"
{%- else %}{{ false }}{% endif %}

Phase 2: Defensive Hardening (for v2.1.0)

Add | bool filter to all conditionals for safety:

# roles/common/tasks/iptables.yml:21
when: ipv6_support | bool

# server.yml:56
when: algo_dns_adblocking | bool or dns_encryption | bool

# server.yml:83
when: algo_ssh_tunneling | bool

Phase 3: Prevention (ongoing)

  1. Add CI test with strict type checking:

    ANSIBLE_STRICT_BOOLEAN=True ansible-playbook main.yml --syntax-check
  2. Add ansible-lint custom rule to detect string boolean patterns

  3. Test against multiple Ansible versions in CI matrix

Temporary Workaround

Users experiencing this issue can work around it by setting:

# Option 1: Environment variable
export ANSIBLE_CONDITIONAL_BARE_VARS=True

# Option 2: In ansible.cfg
[defaults]
conditional_bare_vars = True

# Option 3: Allow broken conditionals (not recommended)
export ANSIBLE_ALLOW_BROKEN_CONDITIONALS=1

⚠️ Note: These workarounds are temporary. The proper fix should be implemented ASAP.

Testing Plan

  1. Unit tests for boolean type verification
  2. Integration test on DigitalOcean (multi-IP environment)
  3. Compatibility test with Ansible 11.x and 12.x
  4. Regression test for all deployment providers

References

Checklist

  • Fix ipv6_support to produce boolean
  • Fix algo_* variables in input.yml
  • Add unit tests for boolean types
  • Test with Ansible 12.0.0
  • Test with Ansible 11.x for compatibility
  • Update CI to catch future type issues
  • Document in CLAUDE.md lessons learned

Priority

🔴 Critical - All new deployments are broken. This needs an immediate hotfix release.


cc: @dguido @incertia

Thanks to @incertia for the detailed bug report and initial investigation!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions