Our good old Red Hat Ansible Tower was recently upgraded to the Ansible Automation Platform. Although the AAP adoption was fast, Ansible compatibility tack derailed half an O&M templates in our organization. The error message says, "Invalid data passed to 'loop', it requires a list, got this instead: dict_keys([])."

The issue comes from the  AAP Execution Engine. The Ansible 2.9 container runs on Python 3. That breaks a lot of code that loops through data structures. The meta code below is a generic representation of the original code.

- name: "Loop through Managment Servers"
  include_role: 
      name: do_stuff
  vars:
     env: development
     target: "{{ item.name }}"
  loop: "{{ servers.keys() }}"
    
Ansible Task with Loop

Function d.keys()  returns a list for Python 2 and a class for Python3 interpreter. The JDoodle allows you to run the code against different Python engines, as in the screenshot below.

Execution results side-by-side

Luckily, the simple explicit typecast fixes the issue.

- name: "Loop through Managment Servers"
  include_role: 
      name: do_stuff
  vars:
     env: development
     target: "{{ item.name }}"
  loop: "{{ servers.keys()|list }}"
Python 3 compatible code