Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot delegate to a host defined by a variable whose value is determined using ansible_facts, for package module #82598

Open
1 task done
jrosser opened this issue Jan 24, 2024 · 3 comments
Labels
affects_2.15 bug This issue/PR relates to a bug. data_tagging has_pr This issue has an associated PR. module This issue/PR relates to a module. P3 Priority 3 - Approved, No Time Limitation verified This issue has been verified/reproduced by maintainer

Comments

@jrosser
Copy link

jrosser commented Jan 24, 2024

Summary

When delegating to a host, you might have some logic that decides which host to delegate to.

An example of that might be using the CPU architecture from ansible_facts to delegate a task to another host which must be the same architecture. This is a contrived example for the purpose of this bug report.

If the logic that determines the delegate_to target uses a regular host variable the resulting type will be AnsibleUnicode and whatever is passed to delegate_to is templated correctly. If ansible_facts[] is used to determine the delegate_to target then the type will be AnsibleUnsafeText and templating of the variable will not happen.

git-bisect indicates that this change behaviour was introduced in fea1304

This https://github.com/ansible/ansible/blob/v2.15.8/lib/ansible/plugins/action/package.py#L49
leads to https://github.com/ansible/ansible/blob/v2.15.8/lib/ansible/template/__init__.py#L744-L746
and returns the original untemplated text as the module name

There are other action plugins (service for example) which use the same templating pattern for delegation and I expect these fail in the same way.

Issue Type

Bug Report

Component Name

package, service

Ansible Version

$ ansible --version

ansible [core 2.15.8]
  config file = None
  configured module search path = ['/Users/jrosser/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/jrosser/cloud/venv2/lib/python3.11/site-packages/ansible
  ansible collection location = /Users/jrosser/.ansible/collections:/usr/share/ansible/collections
  executable location = /Users/jrosser/cloud/venv2/bin/ansible
  python version = 3.11.6 (main, Oct  2 2023, 20:14:46) [Clang 14.0.0 (clang-1400.0.29.202)] (/Users/jrosser/cloud/venv2/bin/python)
  jinja version = 3.1.2
  libyaml = True

Configuration

# if using a version older than ansible-core 2.12 you should omit the '-t all'
$ ansible-config dump --only-changed -t all

CONFIG_FILE() = None

OS / Environment

Darwin RD012343 21.6.0 Darwin Kernel Version 21.6.0: Wed Oct 4 23:55:28 PDT 2023; root:xnu-8020.240.18.704.15~1/RELEASE_X86_64 x86_64

Also reproducible on ubuntu 22.04

Steps to Reproduce

- hosts: a
  vars:
    my_other_hosts:
      x86_64: mist100.test.mist.rd.bbc.co.uk

    architecture: x86_64
    delegate_host1: "{{ my_other_hosts[architecture] }}"
    delegate_host2: "{{ my_other_hosts[ansible_facts['architecture']] }}"
  tasks:
    - debug:
        msg: "{{ delegate_host1 | type_debug }}"

    - debug:
        msg: "{{ delegate_host2 | type_debug }}"

    - package:
        name: vim
        state: present
      delegate_to: "{{ delegate_host1 }}"

    - package:
        name: vim
        state: present
      delegate_to: "{{ delegate_host2 }}"

Expected Results

I expected the task to be delegated to the host computed by the variable delegate_host2 as has happened in ansible versions prior to 2.15.7.

Actual Results

ansible-playbook -i inventory.yml test.yml

PLAY [a] *****************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************************************************************
ok: [mist0.test.mist.rd.bbc.co.uk]

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [mist0.test.mist.rd.bbc.co.uk] => {
    "msg": "AnsibleUnicode"
}

TASK [debug] *************************************************************************************************************************************************************************************************
ok: [mist0.test.mist.rd.bbc.co.uk] => {
    "msg": "AnsibleUnsafeText"
}

TASK [package] ***********************************************************************************************************************************************************************************************
ok: [mist0.test.mist.rd.bbc.co.uk -> mist100.test.mist.rd.bbc.co.uk]

TASK [package] ***********************************************************************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: NoneType: None
fatal: [mist0.test.mist.rd.bbc.co.uk -> mist100.test.mist.rd.bbc.co.uk]: FAILED! => {"changed": false, "msg": "Could not find a module for {{hostvars['mist100.test.mist.rd.bbc.co.uk']['ansible_facts']['pkg_mgr']}}."}

PLAY RECAP ***************************************************************************************************************************************************************************************************
mist0.test.mist.rd.bbc.co.uk : ok=4    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

Code of Conduct

  • I agree to follow the Ansible Code of Conduct
@ansibot ansibot added bug This issue/PR relates to a bug. needs_triage Needs a first human triage before being processed. affects_2.15 module This issue/PR relates to a module. labels Jan 24, 2024
@ansibot
Copy link
Contributor

ansibot commented Jan 24, 2024

Files identified in the description:

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

@mkrizek mkrizek added verified This issue has been verified/reproduced by maintainer P3 Priority 3 - Approved, No Time Limitation and removed needs_triage Needs a first human triage before being processed. labels Jan 30, 2024
@bcoca
Copy link
Member

bcoca commented Jan 30, 2024

note: caused by 'facts' being flagged 'unsafe' and the package action using delegate_to host in a template to figure out the pkg_mgr

@jrosser
Copy link
Author

jrosser commented Feb 28, 2024

There has not been a quick fix for this so I had a look at potential workarounds to allow me to move my Ansible version forward.

It seems that adding the use parameter when calling package causes a sufficiently different code path is taken in the action plugin such that templating of AnsibleUnsafeText can be avoided.

use: "{{ ansible_facts['pkg_mgr'] }}"

openstack-mirroring pushed a commit to openstack/ansible-role-python_venv_build that referenced this issue Mar 4, 2024
See ansible/ansible#82598

Setting the 'use' parameter to something other than 'auto'
should cause a different code path to be use in the package
action plugin which could avoid the templating unsafe text
inside the plugin.

Change-Id: I0c14510eb625d74a654a6398387ab74c4355a4e8
openstack-mirroring pushed a commit to openstack/openstack that referenced this issue Mar 4, 2024
* Update ansible-role-python_venv_build from branch 'master'
  to d80a61f81089338e5dc9a2cfd98ee3d322014c3a
  - Workaround ansible unsafe text templating bug
    
    See ansible/ansible#82598
    
    Setting the 'use' parameter to something other than 'auto'
    should cause a different code path to be use in the package
    action plugin which could avoid the templating unsafe text
    inside the plugin.
    
    Change-Id: I0c14510eb625d74a654a6398387ab74c4355a4e8
@ansibot ansibot added the has_pr This issue has an associated PR. label Mar 21, 2024
openstack-mirroring pushed a commit to openstack/ansible-role-python_venv_build that referenced this issue Mar 30, 2024
See ansible/ansible#82598

Setting the 'use' parameter to something other than 'auto'
should cause a different code path to be use in the package
action plugin which could avoid the templating unsafe text
inside the plugin.

Change-Id: I0c14510eb625d74a654a6398387ab74c4355a4e8
(cherry picked from commit d80a61f)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects_2.15 bug This issue/PR relates to a bug. data_tagging has_pr This issue has an associated PR. module This issue/PR relates to a module. P3 Priority 3 - Approved, No Time Limitation verified This issue has been verified/reproduced by maintainer
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants