Windows Task in a role for Linux hosts? How?

Hi,

I’ve put together a role that configures a number of defined proxy_hosts in nginx. The playbook that calls this role is assigned to [nginx_proxy] in my inventory file that currently contains 3 x linux hosts.
The role currently installs & configures nginx and also generates a .key/.csr on the target host.
As part of the config, I’d like to automate the generation of certificates using our internal PKI server based on these generated files. Unfortunately we use Windows Certificate Services so at the moment I have to manually copy the generated .csr to the server and authorise before copying the .cer back to the nginx hosts.

I’ve successfully put together a playbook that can run a few PS scripts on the PKI server to authorise and retrieve a certificate. However I’m unable to figure out how to marry these two roles so that they can interoperate with each other.

Essentially I want the role to:

[on linux host]

  • generate the .key/.csr
  • fetch the .csr

[on windows pki]
-win_copy .csr to windows pki
-script auth_and_save_cer.ps1

[on linux host]

  • fetch the .cer
  • copy to nginx hosts
  • finish other config steps

I’ve tried the following for the tasks relating specifically to the windows host in the role

  • name: Copy .csr to PKI
    win_copy:
    src: /var/tmp/certificate.csr #sample .csr for debugging
    dest: c:/TEMP/
    delegate_to: fugro-root-ca

But this returns the error:
FAILED! => {“failed”: true, “msg”: “Internal Error: this connection module does not support running commands via sudo”}

In desperation I’ve also tried to run the windows playbook from within the role:

  • name: Run getcert.ps1
    command: “/home/devel/ansible/ansible-playbook -i myhosts win_ca.yml”
    delegate_to: 127.0.0.1

But this also returns an error:
UNREACHABLE! => {“changed”: false, “msg”: “Failed to connect to the host via ssh.”, “unreachable”: true}

So I guess my question is, what’s the proper way of running a task on a windows target machine from inside a role where ‘- hosts’ is targeting linux?

Thanks in advance for anyone that can assist me with this

Niels

Looks like you need to target your linux hosts and your windows ca machine like this:

hosts: linux:windows-ca

Then either delegate_to: linux or delegate_to: windows-ca

From the above you might also need to set

become: false

on the tasks you are delegating to windows

It might make sense to break stuff up in to separate plays (within a single playbook) targeting the windows and linux hosts.

Also you can use pre_tasks and post_tasks in your playbooks which might make sense for you, although I prefer to have playbooks only consist of lists of roles where possible.

Hope this helps,

Jon

I’d second splitting it up a bit into separate roles/tasks/plays for the Win/non-Win for now parts. While it’s possible to target Windows/non-Windows hosts in the same role, all the role tasks would have to be conditionally executed (eg, when: ansible_os_family == ‘Windows’ / != ‘Windows’ or something) to get them behaving properly. Delegate_to would be difficult to use in this scenario due to the way the winrm psuedo connection vars (eg, ansible_winrm_X) work today. The delegator doesn’t have a full list of those, and doesn’t currently know how to work by convention, so it can’t overwrite them all properly. This makes delegation involving Windows hosts hacky at best, and for some combinations of vars, impossible. We’ve got some ideas for how to correct this going forward, but not sure when it’s going to happen.

-Matt