Embedded ansible play treating appliance as inventory instead of inventory item

I’m trying to use embedded ansible to manage provisioning/customization of catalog items, but I’m seeing a very strange behavior in the task.stdout for the tasks for my play.

I’m seeing the following:

  1. manageiq appliance is being treated as the inventory object ( {{ ansible_hostname }} is the appliance name on tasks with delegate_to.
  2. All tasks are acting as though the manageiq appliance is the inventory item, not the IP address and its facts.

One of the tasks I’m performing is creating AD objects for the new VM using a “delegate_to” on the task. This works correctly when I run the playbook from a command line, but when run from the embedded ansible environment, the delegate_to is acting as if the target of the task is the manageiq appliance, not the inventory object. By that I mean, I see that the variables being substituted in the command are showing the appliance information, not the inventory object info.

An earlier role in the play creates the inventory group “ipv4” by processing an extra_var that is all of the ipaddresses reported by VMware tools back to MIQ. (IPv6 is not reliable for us, and the “first” IP is usually IPv6)

e.g.:

- hosts: ipv4
  gather_facts: false

  tasks:
  - include_role: role_that_sets_defaults_and_authentication

` `# test for winrm`
  - wait_for: 
       host: {{ inventory_hostname }}
       port: 5986
       timeout: 120
       sleep: 10
    register: result
    ignore_errors: yes

  - set_fact:
      # ansible_winrm settings
    when: result is succeeded

  - gather_facts:
    setup:

- set_fact:
   target_ou: {{linux_ou if (ansible_system == linux) else windows_ou}}

- name: precreate computer object]
    command: adcli preset-computer --nopassword -D mydomain -S myADserver -C -U ADJoinAcct --onetimepassword --OU={{ target_ou --os-version={{ ansible_distribtuion }} --os-name={{ ansible_distribution }} foo1 {{ ansible_hostname }}
  delegate_to: localhost

The adcli preset-computer output shows:
fatal: [192.168.1.1 -> localhost]: FAILED

And the error output shows:
FAILED! => {"changed": true, "cmd": ["adcli", "preset-computer", "--no-password", "-D", "my.domain.com", "-S", "myAdServer", "-C", "-U", "ADJoinAcct", "--domain-ou=OU=LinuxOUString", "--one-time-password=foo1", "--os-name=CentOS", "--os-version="7.7", "managiqappliance"]

It should be showing the name of the inventory object that corresponds to the 192.168.1.1 inventory object.

Any ideas what would cause this and why I would see this behavior?

Surely this is the ManageIQ appliance though?

I 'm not sure that embedded Ansible can use inventory groups. I’ve had most success when using hosts: all at the top of the playbook, and then controlling which hosts are used for execution by adjusting the hosts values used as input when you define the playbook method (things like this are much easier to do with playbook methods rather than playbook services).

If you wanted to dynamically set the hosts list in a follow-on task I’d probably implement it as 2 successive playbook methods in a simple 2-stage instance. The first method could save the list of IP addresses to something like evm.root['target_host_list'] using the `set_attribute` function from the manageiq-core.manageiq-automate role (see https://www.manageiq.org/blog/2020/02/Embedded-Ansible-Part-3-Ansible-In-An-Automation-Workflow/). The second method could then use the saved value (something like {/#target_host_list}) as its ‘Specify host values’ input list in the method definition.

Hope this helps,
pemcg

Hrm, you got me thinking more about how I’m calling the embedded ansible (using a playbook method). I used to be using the hosts option on the playbook method, but I switched it to be “localhost” when I implemented the custom inventory task. I suspect that when localhost is the specific inventory item, then since that is a part of the inventory (which it normally isn’t, as I understand things), that changes how the delegate_to behaves.

A quick test of that shows that indeed, if I use the Host radio button to pass in some item as a host, but then ignore that item in favor of making my own host_group from the extra_vars, the delegate_to tasks (like the adcli preset-computer), work correctly.

For reference:
I’m creating the inventory group by adding more items to inventory in the course of the play,

 add_host:
   name: "{{ item }}"
   groups: ipv4
 loop: "{{ ip_list | map('regex_replace','\\\"') | ipv4 }}"

ip_list is an extra_var of all of the IPv4 and IPv6 addresses of the VM being created. The default inventory for the play is “localhost”.

Thanks as always for spurring further thought…8)