HiveBrain v1.2.0
Get Started
← Back to all entries
snippetdockerMinor

How do I provision a Windows Docker container with Ansible?

Submitted by: @import:stackexchange-devops··
0
Viewed 0 times
containerprovisiondockerwithwindowshowansible

Problem

I want to provision a Windows Docker container with Ansible, but I am confused about how exactly it will work.

For instance if I use Packer with Linux, I know I can run ansible (which is ansible remote) and ansible-local. I have to build my Windows Docker containers from a Windows computer and the Windows computer cannot be an Ansible master at this point.

Does any tool, possibly Packer for Windows handle things automatically and spin up a Linux Ansible Master VM to run the playbooks automatically?

How can I easily provision Windows containers with Ansible as part of my image build process?

I am currently using Windows 10 Enterprise and Windows Server 2016 is on the horizon.

Solution

I've always had issues with using ansible to provision Windows machines with Packer due to the winrm connections breaking, example issue.

A workaround which you can do is to use the shell-local on your host machine which calls the Ansible playbook with the new host (although you would need to give it the IP address of your Windows Docker machine).

I've added the example which I did to get a test working. This uploads ip.cmd to the Windows virtual machine, which gets its IP address, and is then downloaded back to the destination. The ansible playbook is then called against that.

"provisioners": [
        {
            "type": "file",
            "source": "ip.cmd",
            "destination": "C:/tmp/ip.cmd"
        },
        {
            "type": "windows-shell",
            "inline": [
                "echo [{{ user `ansible_group` }}] > C:/tmp/hosts",
                "C:/tmp/ip.cmd"
            ]
        },
        {
            "type": "file",
            "direction": "download",
            "source": "C:/tmp/hosts",
            "destination": "./ansible/hosts"
        },
        {
            "type": "shell-local",
            "command": "ANSIBLE_CONFIG=./ansible.cfg ansible-playbook -v -i ./ansible/hosts -l \"{{ user `ansible_group` }}\" -e \"ansible_user={{ user `username` }} ansible_password={{ user `password` }} ansible_become_pass={{ user `password` }} ansible_port=5986 ansible_connection=winrm ansible_winrm_server_cert_validation=ignore \" ./ansible/site.yml"
        }


where ip.cmd gets the IP address of the Windows host:

@echo off
FOR /F "tokens=2,3" %%A IN ('ping %computername% -n 1 -4') DO IF "from"== "%%A" set "IP=%%~B"
echo %IP:~0,-1% >> C:/tmp/hosts


source

Code Snippets

"provisioners": [
        {
            "type": "file",
            "source": "ip.cmd",
            "destination": "C:/tmp/ip.cmd"
        },
        {
            "type": "windows-shell",
            "inline": [
                "echo [{{ user `ansible_group` }}] > C:/tmp/hosts",
                "C:/tmp/ip.cmd"
            ]
        },
        {
            "type": "file",
            "direction": "download",
            "source": "C:/tmp/hosts",
            "destination": "./ansible/hosts"
        },
        {
            "type": "shell-local",
            "command": "ANSIBLE_CONFIG=./ansible.cfg ansible-playbook -v -i ./ansible/hosts -l \"{{ user `ansible_group` }}\" -e \"ansible_user={{ user `username` }} ansible_password={{ user `password` }} ansible_become_pass={{ user `password` }} ansible_port=5986 ansible_connection=winrm ansible_winrm_server_cert_validation=ignore \" ./ansible/site.yml"
        }
@echo off
FOR /F "tokens=2,3" %%A IN ('ping %computername% -n 1 -4') DO IF "from"== "%%A" set "IP=%%~B"
echo %IP:~0,-1% >> C:/tmp/hosts

Context

StackExchange DevOps Q#3488, answer score: 1

Revisions (0)

No revisions yet.