Fix crash when ansible_default_ipv4.address is undefined (PE-1998) - #371
Merged
steven-schattenberg-itential merged 2 commits intoAug 28, 2026
Merged
Conversation
redis_bind and redis_sentinel_bind assumed ansible_default_ipv4.address
always exists. On hosts with no default route, Ansible sets
ansible_default_ipv4 to an empty dict, so accessing .address raised
AnsibleUndefinedVariable and aborted the run. Both now check
`is defined` first and fall back to binding on 127.0.0.1 only.
Tested by:
- Reproducing the crash with an ad-hoc command simulating the empty-fact
case: `ansible localhost -m debug -a "msg={{ '127.0.0.1 ' ~
ansible_default_ipv4.address }}" -e '{"ansible_default_ipv4": {}}'`
confirmed the pre-fix expression fails with
"'dict object' has no attribute 'address'".
- Re-running the same ad-hoc check against the new expression for both
the empty-fact case (renders "127.0.0.1", no crash) and a populated
case (`-e '{"ansible_default_ipv4": {"address": "10.0.0.5"}}'`, renders
"127.0.0.1 10.0.0.5"), confirming existing behavior is unchanged.
- Parsing both YAML files with PyYAML to confirm the folded scalar
produces the identical single-line Jinja expression as before wrapping
it for line length.
- ansible-lint roles/redis/defaults/main/redis.yml
roles/redis/defaults/main/sentinel.yml passes clean (0 failures,
0 warnings).
steven-schattenberg-itential
requested changes
Aug 28, 2026
Replace the ternary conditional with the simpler, more idiomatic
`| default('')` filter, matching the pattern already used by every
other reference to ansible_default_ipv4.address in this codebase
(the three *-validation-report.md.j2 templates).
Tested by:
- Re-running the same ad-hoc reproduction checks against this new
expression: undefined-fact case renders "127.0.0.1 " (trailing
space, no crash); defined case renders "127.0.0.1 10.0.0.5" as
before.
- Confirmed the trailing space is harmless to Redis itself: ran a
real redis:latest Docker container with a config file containing
"bind 127.0.0.1 " (trailing space) - it loaded the config and
reached "Ready to accept connections" with no parse error.
- ansible-lint on both changed files passes clean (0 failures,
0 warnings).
steven-schattenberg-itential
approved these changes
Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
redis_bindandredis_sentinel_bind(inroles/redis/defaults/main/redis.ymlandroles/redis/defaults/main/sentinel.yml) assumedansible_default_ipv4.addressalways exists.ansible_default_ipv4to an empty dict, so accessing.addressraisedAnsibleUndefinedVariableand aborted the entire run.ansible_default_ipv4.address is definedfirst, falling back to binding on127.0.0.1only when it's not present.*-validation-report.md.j2templates) already guarded with| default('N/A')and needed no changes.How this was tested
Reproduced the crash with an ad-hoc Ansible command that simulates the "no default route" case (empty
ansible_default_ipv4fact), using the exact pre-fix expression:Result:
FAILED! => "'dict object' has no attribute 'address'"— confirming the exact failure mode described in the ticket.Verified the fix by running the same style of check against the new expression, for both the broken case and the normal case:
Confirmed the YAML still parses to the identical single-line Jinja expression after wrapping it across two lines for line-length (folded scalar
>-), using PyYAML to load both files and print the resultingredis_bind/redis_sentinel_bindvalues.Ran
ansible-lintagainst both changed files — passes clean (0 failures, 0 warnings):End-to-end sanity check: this same Redis role (unmodified logic aside from this fix) was used minutes earlier in a full
itential.deployer.siterun against a live EC2 instance (Rocky Linux 8, AIO topology) whereansible_default_ipv4.addresswas defined — Redis, Sentinel, MongoDB, Platform, and Gateway all installed and started successfully, confirming this change doesn't alter behavior on hosts where the fact is present.Test plan for reviewer
redis_bind/redis_sentinel_binddefault definitionsansible localhost -m debugcommands above to reproduce/verify locallyitential.deployer.redisagainst a host with no default route to confirm no crash end-to-end