ansible / ansible

Ansible is a radically simple IT automation platform that makes your applications and systems easier to deploy and maintain. Automate everything from code deployment to network configuration to cloud management, in a language that approaches plain English, using SSH, with no agents to install on remote systems. https://docs.ansible.com.
https://www.ansible.com/
GNU General Public License v3.0
61.81k stars 23.76k forks source link

`vars` doesn't accept a dictionary if it's dynamically generated #83537

Open andrewvaughan opened 5 days ago

andrewvaughan commented 5 days ago

Summary

When trying to include a Role with dynamic variables:

    # Use the `create-zfs-pool` role to create the root pool.
    - name: "Creating `rpool` ZFS pool for operating system."
      ansible.builtin.include_role:
        name: "create-zfs-pool"
      vars: "{{ { 'name': 'rpool' } | ansible.builtin.combine(hostvars[inventory_hostname].storage.root) }}"

The following error occurs:

ERROR! Vars in a IncludeRole must be specified as a dictionary

...

The offending line appears to be:

        name: "create-zfs-pool"
      vars: "{{ { 'name': 'rpool' } | ansible.builtin.combine(hostvars[inventory_hostname].storage.root) }}"
            ^ here

...

I have confirmed that the output of this jijna2 template is a dict:

      - debug:
        msg: "{{ { 'name': 'rpool' } | ansible.builtin.combine(hostvars[inventory_hostname].storage.root) | type_debug }}"

With the following output:

TASK [provision-ubuntu : debug] ******************************************************************************************************************************
ok: [new-host.opc.lab.andrewvaughan.io] => 
  msg: dict

Issue Type

Bug Report

Component Name

ansible-core

Ansible Version

$ .venv/bin/ansible --version

ansible [core 2.17.1]
  config file = /Users/andrew/Repositories/Personal/homelab/ansible.cfg
  configured module search path = ['/Users/andrew/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/andrew/Repositories/Personal/homelab/.venv/lib/python3.12/site-packages/ansible
  ansible collection location = /Users/andrew/Repositories/Personal/homelab
  executable location = .venv/bin/ansible
  python version = 3.12.4 (main, Jun  6 2024, 18:26:44) [Clang 15.0.0 (clang-1500.3.9.4)] (/Users/andrew/Repositories/Personal/homelab/.venv/bin/python)
  jinja version = 3.1.4
  libyaml = True

Configuration

# if using a version older than ansible-core 2.12 you should omit the '-t all'
$ .venv/bin/ansible-config dump --only-changed -t all
ANSIBLE_NOCOWS(/Users/andrew/Repositories/Personal/homelab/ansible.cfg) = True
COLLECTIONS_PATHS(/Users/andrew/Repositories/Personal/homelab/ansible.cfg) = ['/Users/andrew/Repositories/Personal/homelab']
CONFIG_FILE() = /Users/andrew/Repositories/Personal/homelab/ansible.cfg
DEFAULT_HOST_LIST(/Users/andrew/Repositories/Personal/homelab/ansible.cfg) = ['/Users/andrew/Repositories/Personal/homelab/hosts.yml']
DEFAULT_LOAD_CALLBACK_PLUGINS(/Users/andrew/Repositories/Personal/homelab/ansible.cfg) = True
DEFAULT_ROLES_PATH(/Users/andrew/Repositories/Personal/homelab/ansible.cfg) = ['/Users/andrew/Repositories/Personal/homelab/roles']
DEFAULT_STDOUT_CALLBACK(/Users/andrew/Repositories/Personal/homelab/ansible.cfg) = yaml
DISPLAY_SKIPPED_HOSTS(/Users/andrew/Repositories/Personal/homelab/ansible.cfg) = False
INTERPRETER_PYTHON(/Users/andrew/Repositories/Personal/homelab/ansible.cfg) = /usr/bin/python3

CALLBACK:
========

default:
_______
display_failed_stderr(/Users/andrew/Repositories/Personal/homelab/ansible.cfg) = True
display_ok_hosts(/Users/andrew/Repositories/Personal/homelab/ansible.cfg) = True
display_skipped_hosts(/Users/andrew/Repositories/Personal/homelab/ansible.cfg) = False
show_task_path_on_failure(/Users/andrew/Repositories/Personal/homelab/ansible.cfg) = True

CONNECTION:
==========

ssh:
___
control_path(/Users/andrew/Repositories/Personal/homelab/ansible.cfg) = /tmp/%%h-%%r

OS / Environment

macOS 14.1.2 (23B92)

Steps to Reproduce

  1. Create a task with a jinja2 template as the vars output, with a dict type.

Expected Results

I expected the vars argument to accept the dict created from the formula.

Actual Results

ERROR! Vars in a IncludeRole must be specified as a dictionary.

As described in the summary.



### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct
ansibot commented 5 days ago

Files identified in the description:

None

If these files are incorrect, please update the component name section of the description or use the component bot command.

nitzmahone commented 1 day ago

This might be easier with an upcoming feature- no promises, but I'm going to play with it...