Courseiva

EX294 Transform data with filters and plugins Practice Question

An Ansible playbook is used to generate configuration files for network devices. The variables are defined in a vars file like: ---

interfaces:

- name: GigabitEthernet1 ip: 192.168.1.1/24 - name: GigabitEthernet2 ip: 10.0.0.1/24

The playbook uses a Jinja2 template to render the config. The template iterates over interfaces and writes "ip address" lines. However, the designer wants to support an additional field "secondary_ips" which is a list of IP addresses (e.g., ["192.168.2.1/24", "192.168.3.1/24"]). In the template, they want to generate multiple "ip address" lines for each interface, one for the primary IP and one for each secondary IP. The following template fragment is used:

{% for iface in interfaces %}
interface {{ iface.name }}
 ip address {{ iface.ip }}
{% for sec in iface.secondary_ips|default([]) %}
 ip address {{ sec }}
{% endfor %}
{% endfor %}

This works when secondary_ips is defined. However, some interfaces have secondary_ips defined as a string (e.g., "192.168.2.1/24") instead of a list. The playbook fails because the inner loop tries to iterate over a string. The engineer wants to normalize the data in the playbook before passing to the template, so that secondary_ips is always a list. Which of the following set_fact tasks will correctly transform the interfaces list to ensure secondary_ips is always a list (even if missing or a string)?

⚠ Common exam trap

The trap here is that candidates often try to use `default([])` or `split` without handling the case where the variable is already a list, leading to nested lists or string conversion errors, while the correct approach uses `ternary` to conditionally apply transformations based on the data type.

Answer choices

Why each option matters

Answer the question above first, then reveal the full breakdown to understand why each option is right or wrong.

Correct answer & explanation

✓

- set_fact: interfaces: "{{ interfaces | map('combine', {'secondary_ips': (item.secondary_ips is undefined or item.secondary_ips is none) | ternary([], (item.secondary_ips is string) | ternary(item.secondary_ips | split(','), item.secondary_ips))}) }}" loop: "{{ interfaces }}"

Ly uses the `ternary` filter to handle three cases: when `secondary_ips` is undefined or None (returns an empty list), when it is a string (splits it into a list), and when it is already a list (returns it unchanged). This ensures the template always receives a list for iteration, preventing the 'iteration over string' error.

Answer analysis

Option-by-option breakdown

For each option: why learners choose it and why it is or isn't the right answer here.

  • ✗

    - set_fact: interfaces: "{{ interfaces | map('combine', {'secondary_ips': item.secondary_ips | default([]) | split(',') if item.secondary_ips is defined and item.secondary_ips is string else item.secondary_ips | default([])}) }}" loop: "{{ interfaces }}"

    Why it's wrong here

    Syntax error due to incorrect Jinja2 conditional placement within map.

  • ✗

    - set_fact: interfaces: "{{ interfaces | map('combine', {'secondary_ips': [item.secondary_ips | default('')] | flatten }) }}" loop: "{{ interfaces }}"

    Why it's wrong here

    Wraps a string in a list, but does not split it; flatten only removes one level of nesting.

  • ✗

    - set_fact: interfaces: "{{ interfaces | map('combine', {'secondary_ips': item.secondary_ips | default([]) | string | split(',') | list}) }}" loop: "{{ interfaces }}"

    Why it's wrong here

    String conversion of a list produces a representation like "['a','b']", which split by comma yields incorrect elements.

  • ✓

    - set_fact: interfaces: "{{ interfaces | map('combine', {'secondary_ips': (item.secondary_ips is undefined or item.secondary_ips is none) | ternary([], (item.secondary_ips is string) | ternary(item.secondary_ips | split(','), item.secondary_ips))}) }}" loop: "{{ interfaces }}"

    Why this is correct

    Correctly handles undefined, string, and list cases.

About these practice questions

This EX294 question is part of Courseiva's 392-question bank — original exam-style content with full explanations and wrong-answer analysis, never real exam questions or exam dumps. Learn why practice questions differ from exam dumps →

How Courseiva writes practice questions · Editorial policy

JA

Written by Johnson Ajibi, MSc IT Security

Senior Network & Security Engineer · founder of Courseiva

This EX294 practice question is part of Courseiva's free Red Hat certification practice question bank. Courseiva provides original exam-style practice questions with explanations, topic-based practice, mock exams, readiness tracking, and study analytics to help learners prepare for the EX294 exam.