-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Feature: allow Ansible provisioner to specify usage of WinRM instead of SSH #3911
Comments
@bhcleek do you know if this is already supported, maybe on master? |
Hi @rickard-von-essen , thanks for your comment. As I linked the code, I think it's quite clear that this is not implemented, however maybe I'm overlooking something, so let's wait for the comment. Thanks for such a quick respose :) |
This is a bit complicated since ansible communicates with a ssh proxy that in turn forwards the connection to the VM. But it should now work on master for docker which also uses a special communicator, if I understand correctly. |
Yes, this should work on master now. |
👍 |
Thanks for you responses @bhcleek . In that case, could you please provided any documentation/example, how to use this feature? Since it doesn't work for me even when I try to build fresh master, but I haven't configured anything. My Packer JSON file looks like this: http://pastebin.com/qh9R00Qr Output of my image build: http://pastebin.com/sC8wRSrs So question - if this feature is already implement, how to use it? |
@Holmistr Packer communicates with the node, because the builder's Your packer template looks fine to me; I'm working on some tests to verify that the provisioner works correctly in this configuration. In the meantime, have you tried using Ansible's raw module? Adding |
@bhcleek Yes, I tried the raw module. openstack: <127.0.0.1> ESTABLISH WINRM CONNECTION FOR USER: jholusa on PORT 44902 TO 127.0.0.1 I'm not very familiar with the process, but it looks like it's trying to establish WinRM connection to the local proxy, is that correct? I'm sorry, I'm still a bit confused here, hence I cannot diagnose it properly. |
I've setup a simple test repo https://github.com/chris-smith-zocdoc/packer-windows-example for this issue. If I'm doing something wrong/dumb please let me know, the rest of this is based on the assumption that what I'm doing in the example repo is correct. AFAIK its unlikely that the current implementation will work unless there is a way to have Ansible send windows commands over the ssh connection. Here is my packer log
Notice that its trying to issue a command to the windows host using If you take a look at the Ansible winrm connector, it does a bunch of things when executing winrm commands which doesn't happen over the ssh connection. It looks like it might be possible to force the ssh connector to use the powershell shell type but I'm not familiar enough with the Ansible codebase to make that determination. I also wouldn't be surprised if that just brought on a new slew of bugs in Ansible because I imaging anyone who is doing windows management with Ansible is using winrm. Running Ansible from outside of packer on the same host, you'll notice that the commands change to be more powershelly I'm not familiar with either of these codebases, but from what I can tell we have the following options:
|
@chris-smith-zocdoc My testing shows the same results that you're seeing, but I think there may be a way forward. ansible/ansible#14274, ansible/ansible#13490, and http://docs.ansible.com/ansible/intro_configuration.html#executable hint that it may be possible to force ansible to use the shell of our choice; I'll keep looking into it. Regarding the other two alternatives that you provided, implementing a WinRM proxy may be possible. The last alternative, exposing the IP address from the communicator interface is unlikely to happen, because not all the builders communicate over TCP/IP. |
https://github.com/ansible/ansible/blob/stable-2.1/lib/ansible/plugins/connection/__init__.py#L173-L221 and https://github.com/ansible/ansible/blob/600915aa97cd70dc3b6c5e5a3d1944f48c14597e/docsite/rst/intro_inventory.rst#list-of-behavioral-inventory-parameters give us details about the values that may need to be configured using |
I was able to force the executable to be powershell and Ansible made it a little further. This time it failed to run scp (I assume Ansible is copying files to the target machine) See the updated log I'm currently running an older version of Ansible
For my own knowledge, what packer builders don't support TCP/IP? |
That's great news! The Can you try setting the
The docker builder, for instance, doesn't use SSH to communicate with Docker. Currently it runs docker commands, but there's a pending change (maybe already merged?) that will use the Docker API instead. Also, any number of custom builders may use their own communicator. |
I tried setting the shell type to powershell but this caused an exception inside ansible
Ansible also built a docker connector so I don't think that's an issue. I see a lot of duplicate work between the two projects which seems unfortunate. |
I took a look at the WinRM protocol, turns out its all done over HTTP which is really convenient for us. We should be able to get this to work by setting up a HTTP proxy between Ansible and the target machine. Example of someone doing this in nginx There are plenty of http proxy packages available, including the one in the std lib https://golang.org/pkg/net/http/httputil/#ReverseProxy and this one built on top of it https://github.com/elazarl/goproxy |
It would be awesome to implement a WinRM proxy that can forward WinRM, it should be fairly easy. We could extract the ssh proxy and the WinRM proxy into a utility and allow things like |
Keep in mind that the ansible-remote provisioner is an adapter, not a proxy. @rickard-von-essen are you suggesting that a communicator bypass be put in place? I'd like to take a little more time to see if we can find the right set of variables that would allow Ansible to be configured so that Ansible could connect to the provisioner using SSH, but using Powershell on the remote node. |
@bhcleek Sure if you ask a Software Engineer it's an adapter, but ask a Network Engineer and he'll call it a proxy ;-)
No I was just thinking aloud that your adapter/proxy could be use with {
"type": "shell-local",
"inline": [ "git push ssh://git@localhost:$SSH_PORT" ]
} Where But this is not the solution for this issue right now. |
Thanks for the clarification. Is there another forum where we could talk about it? |
@chris-smith-zocdoc your latest attempt made some good progress, and gives me some confidence that we're getting close to a solution. I think we still don't have the I'll spend some time trying to provision a Windows machine with Ansible this weekend. |
@bhcleek I'll try that and report back. We can probably also reach out to the Ansible team to see if they can point is in the right direction |
I'm happy to report that I've had success provisioning a Windows machine using the
|
@bhcleek that is great news. The we can just check if |
@rickard-von-essen the |
@bhcleek sorry have been programming to much on the builders where you have On Oct 10, 2016 19:56, "Billie Cleek" notifications@github.com wrote: @rickard-von-essen https://github.com/rickard-von-essen the Communicator — Reply to this email directly, view it on GitHub |
@bhcleek Do you have an example I can look at? Setting those arguments still gives me the error I was seeing previously. chris-smith-zocdoc/packer-windows-example@5746322 Which version of Ansible do you have installed?
The stack I'm seeing with those arguments
|
I'm using the same version of ansible, 2.1.2.0. Your playbook looks like it should work. However, I am seeing the same error as you under some conditions. I'm writing some tests to verify the WinRM functionality and will let you know when I know more. |
After troubleshooting some more, I've realized that so far I am only able to get the |
For everyone following this, I think the problem here may actually lie in Ansible. I'm working to resolve it, and will post an update or submit a PR when I have a solution. |
Hi @bhcleek , I see that you've made some progress, nice! Do you have any update on this? I'm getting the same errors as mentioned above. |
I have made progress. I'm dealing with one remaining issue, and then I need to refine the solution to be less hacky. So far I've had to make a very small change to the provisioner code and supply an Ansible connection type that's forked from the Unfortunately, Ansible's I'm going to keep at it, though, and will try to publish some code this weekend to show my progress. |
Awesome news @bhcleek , I really appreciate this! :) |
Assume the scp target is a file instead of a directory. Assuming the scp target is a file instead of a directory allows uploading files to a node being provisioned with the ssh communciator using sftp and with the winrm communicator. It is fully compatible with ansible; ansible communicators only allow for files to be uploaded (when the copy module is used to upload a directory, ansible walks the directory and uploads files one at a time). Update docuemntation to explain how to provision a Windows image. Extend tests that use ssh to communicate with the node to include single files, recursive copies, and content-only recursive copies. Add test to verify support for the winrm communicator. Remove the err argument from adapter.scpExec, because it was unused. Fixes hashicorp#3911
I've submitted a PR, #4209, that should resolve the incompatibility of using the ansible provisioner with nodes being provisioned using the winrm communicator. You can see how to hook this up in three files:
It's also documented in https://github.com/mitchellh/packer/blob/9201b2db606854c8c5fac3915ee855b4f7c5e3b5/website/source/docs/provisioners/ansible.html.md Note that code changes were required, so you'll need to use a build that incorporates the code changes in #4209. |
Assume the scp target is a file instead of a directory. Assuming the scp target is a file instead of a directory allows uploading files to a node being provisioned with the ssh communciator using sftp and with the winrm communicator. It is fully compatible with ansible; ansible communicators only allow for files (never directories) to be uploaded (when the copy module is used to upload a directory, ansible walks the directory and uploads files one at a time). Update documentation to explain how to provision a Windows image. Extend tests that use ssh to communicate with the node to include single files, recursive copies, and content-only recursive copies. Add test to verify support for the winrm communicator. Remove the err argument from adapter.scpExec, because it was unused. Fixes hashicorp#3911
@bhcleek This worked wonderfully. Thank you so much! |
@bhcleek Thanks for contributing a fix for using winrm within ansible and packer. I've been using a build based off your PR for a project and everything is working very well, except when using the win_reboot module. I receive the following error:
When running with
|
Update, I added the _winrm_host and _winrm_port attributes to the custom connection plugin for packer. However, the values will need to be set based on the VM, not the proxy/adapter. I hard coded the values as a test. Is that information available to the connection plugin, so they can be set dynamically? Everything works, except the ansible logging while it waits during reboot. |
From the perspective of Ansible, the adapter is the thing being provisioned, so the However, rebooting using the win_reboot module will cause packer to lose the connection; if you need to reboot in the middle of provisioning, then use packer's windows restart provisioner instead of Ansible's win_reboot module. |
Thanks @bhcleek. I was hoping not to break up my playbook just for reboots when I'm using Ansible to do the provisioning. I do not know the history, but what was the use case that led to the proxy/adapter? |
@dragan it's due to the (necessary) architecture of packer. RE: #3846 (comment) |
My usecase is to create Windows image using Ansible. The problem is that I need to connect to Windows image via WinRM. Ansible already has this capability, you only specify "ansible_connection: winrm" and other parameters in the inventory file.
However, Packer's Ansible provisioner doesn't allow to add this information to the inventory file. Packer create temporary inventory file which it uses further. As stated in the documentation: "It dynamically creates an Ansible inventory file configured to use SSH ... ". Also, when looking at the code of Ansible provisioner (https://github.com/mitchellh/packer/blob/master/provisioner/ansible/provisioner.go#L252), I see that there is no option to either specify ansible_connection properties, or provide custom inventory file.
This feature could be quite useful and I would say not very hard to implement. If you can confirm that this makes sense to implement and we agree on the way how to do it (either provide capability to specify custom inventory file or just add new properties like "ansible_connection", etc.), I would be happy to implement it (or at least try).
The text was updated successfully, but these errors were encountered: