Q: In an Ansible playbook, a custom CLI command returns exit code 1 for non-fatal status warnings, causing the task to fail. How do you tune failed_when and changed_when conditions?
Custom scripts frequently violate standard exit code conventions. Capture stdout and return codes using register, override failure logic using failed_when, and accurately enforce changed_when conditions to eliminate false positives.
Want to master this scenario in a live sandbox? KodeKloud's CKA & CKAD Hands-On Certification Track covers this exact problem with hands-on terminal drills.
🛠️ Production Runbook & Step-by-Step Resolution
Capture Script Telemetry with register
Capture the command's stdout, stderr, and return code into a variable:
- name: Run legacy database migration scriptcommand: /opt/scripts/migrate.shregister: migration_out
Override Failure Logic with failed_when
Define custom boolean conditions that mark the task as failed even when the exit code is 0:
failed_when:
- migration_out.rc != 0 or 'ERROR' in migration_out.stdout or 'FAILED' in migration_out.stderr- This halts execution immediately when error patterns appear in stdout, preventing silent failures.
Refine Mutation Status with changed_when
By default, command/shell tasks always report changed: true. Override this so changes only register when work was actually performed:
changed_when: "'MIGRATION_APPLIED' in migration_out.stdout"- If stdout contains 'NO_CHANGES_NEEDED', the task cleanly reports green (
ok), preventing downstream restart handlers from firing.
- By default, Ansible determines success purely by exit code 0 and marks all command/shell tasks as 'changed'.
- Use 'register: output_var' to capture stdout, stderr, and return code in task memory.
- Use 'failed_when: "'FATAL' in output_var.stdout"' to fail tasks when legacy scripts return exit code 0 on errors.
- Use 'changed_when: "'UPDATED' in output_var.stdout"' to prevent false positive 'changed' status on no-op runs.
- Set 'changed_when: false' on read-only status and audit commands to maintain pristine idempotency metrics.
- Combine conditions with YAML lists to evaluate multiple logical expressions cleanly without complex bash regex.
Senior hiring managers and bar raisers evaluate how you prioritize during outages. Avoid these common anti-patterns:
- Using ignore_errors: yes instead of failed_when ignore_errors blindly continues execution on real catastrophic errors; failed_when allows fine-grained error evaluation.
- Leaving changed_when undefined on diagnostic shell scripts Causes monitoring tools and CI reports to show false configuration drifts on every single run.
- Checking for substring matching without accounting for case sensitivity A script outputting 'error' will not match 'ERROR' unless explicitly lowercased via Jinja2 filters.