Automating Windows migrations to Aws with Double Take Move and Ansible

Posted in AWS Blog
14/04/2016 Pauwel Rummens


When you’re a cloud reseller/architect you often get contacted by customers who want to migrate their infra to Aws.

Although I’m not really for the lift and shift way of working, sometimes there is no way around it.


Instead of spending hours of work on installing and configuring, exporting, importing, etc… we can now really get things going by using Double Take Move and Ansible.

For this article you need some basic knowledge of Ansible.

A good place to start is ( )


Double take move is really well made and very user friendly!

And the license cost to use this product is forgotten easily when you don’t have to spend hours in exporting-importing – troubleshooting these kind of moves.




Prep work

Ah yes, there is always some prep work to do. (more if your not already using Ansible now)


Lets first configure the Aws environment, create the needed vpc, subnets,vpn’s, seurity groups, roles,etc…


Make sure that the vpc cidr block and subnets match your current setup exactly.

(And also create the target servers in the correct subnets)

DHCP option set

Make sure that you create a dhcp option set if the servers you are migrating are on dhcp.



DHCP options set ID: dopt-xxxxxx | NameHere


domain-name = fqdninlowercase
domain-name-servers = adserveriphere
ntp-servers = ntpserveriphere
netbios-name-servers = netbiosserveriphere

Public ip’s

Maybe for connectivity to work you will need to attach some public ip’s to your source and target servers.

We used this mostly in Azure to Aws migrations.


Ansible Setup

We have been using Ansible for quite some time now and we find that installing it on Centos or Ubuntu is the best way to go.

Below are the basic steps for Centos

  • We mostly use at least Ansible version 2, therefore we need to enable the the epel-testing repository to install Ansible. Edit the file under /etc/yum.repos.d/epel-testing.repo to enable it. Then run the below commands


rpm -Uvh

yum install ansible

useradd ansible

chown ansible.ansible /etc/ansible/ -R

sudo su - ansible


Accept defaults for the keygen. Or change to your way of working (you can then push this key out to linux server, which are not in scope of this blog)

  • Install pywinrm
pip install "pywinrm>=0.1.1"
  • If your windows systems are in a domain (most of them normally are) install the Kerberos dependencies
yum -y install python-devel krb5-devel krb5-libs krb5-workstation
  • You will also need the python part to this
pip install kerberos


Please read the kerberos documentation carefully, as your really need this to be correct and working.



Edit the /etc/krb5.conf file and change it to reflect your domain



 default = FILE:/var/log/krb5libs.log

 kdc = FILE:/var/log/krb5kdc.log

 admin_server = FILE:/var/log/kadmind.log


 dns_lookup_realm = false

 ticket_lifetime = 24h

 renew_lifetime = 7d

 forwardable = true

 rdns = false

 default_realm = FQDN.IN.CAPITALS

 default_ccache_name = KEYRING:persistent:%{uid}



  kdc = ip or fqdn.of.your.first.domain.controller

  kdc = ip or fqdn.of.your.second.domain.controller

  default_domain =

  kpasswd_server = ip or fqdn.of.your.first.domain.controller

  kpasswd_server = ip or fqdn.of.your.second.domain.controller



        .fqdninlowercase = FQDN.IN.CAPITALS


When that is done you can test the connection is working by running the below command


kinit user@MY.DOMAIN.COM


If nothing is returned -> don’t panic!!! Then it worked !

You can then check your Kerberos ticket with the command





Under your /etc/ansible directory there is a hosts file.

It contains some examples in how to use an Ansible Inventory file.

Create yours any way you like.

But for the these migration you can do something like this











For each group you create here you can/must create a credential file with the same name.

So in this case a sourceservers.yml and targetservers.yml

Store these under the /etc/ansible/group_vars.

Content of these files for local users


# it is suggested that these be encrypted with ansible-vault:

# ansible-vault encrypt sourceservers.yml 

ansible_user: Administrator

ansible_password: SecretPasswordGoesHere

ansible_port: 5986

ansible_connection: winrm

# The following is necessary for Python 2.7.9+ when using default WinRM self-signed certificates:

ansible_winrm_server_cert_validation: ignore


Content of the file for domain users


# it is suggested that these be encrypted with ansible-vault:# ansible-vault encrypt sourceservers.yml

ansible_user: ansible@FQDNINCAPITALS

ansible_password: SecretPasswordGoesHere

ansible_connection: winrm

ansible_port: 5986

ansible_winrm_server_cert_validation: ignore


You can also add it in the hosts file like so






ansible_ssh_user = ansible@FQDNINCAPITALS

nsible_password = secretpasswordhere

ansible_connection = winrm

ansible_ssh_port = 5986

ansible_winrm_server_cert_validation = ignore



Windows Configuration

Make sure your target servers are as identical as possible to your source servers.

So same os ,service pack,IP and disk layout and your good to go. (ooh and don’t rename your target server to the source server just yet, double take will complain and will not continue. But a usefull name is a good way to identify the target server)

You will need to do the below on all source and target servers, for the target servers you can maybe create an ami from which to deploy, depending in how many servers you need to migrate.

  • Configure winrm on all windows machines that you need to migrate (script for this can be found here :
  • Also make sure you have at least version 3 of powershell installed, so basically check all your servers that are below server 2012.
  • Preferably create an “ansible” user on those systems and allow it to connect through winrm (there is a local group called WinRMRemoteWMIUsers__, add it to this group. Also the local admin, else you will not be able to do everything that is needed here)
  • Because of Ansible’s way of spawning allot of connections I found that increasing the MaxShellsPerUser parameter for winrm to give less problems.

Command :

winrm set winrm/config/winrs '@{MaxShellsPerUser="50"}'

Hint: You can combine the above in the ConfigureRemotingForAnsible.ps1 that you download from the ansible site, by added the following on the bottom of the script

winrm set winrm/config/winrs '@{MaxShellsPerUser="50"}'
NET USER ansible "secretpasswordhere" /ADD
NET LOCALGROUP "administrators" "ansible" /add
NET LOCALGROUP "WinRMRemoteWMIUsers__" "ansible" /add
shutdown /r

I found that in most cases you will need to reboot the server in order for it all to work correctly.



Ofcourse we need to modify some firewall rules here and there.

Make sure that ansible can reach your servers on 5986 tcp.

Also make sure that source and target servers can speak with each other directly over port 6320 and 6325 tcp and udp.

The double take console will also need to speak with all servers on these ports.


Note: ofcourse make sure that all other needed rules,routes,vpn’s,etc are in place for your servers.


Test test test

We can now test the connection to the windows servers.

(If you are using the domain credentials make sure you have a valid Kerberos ticket first.)

Run the following

Ansible sourceservers –m setup

to verify the source server connections

Ansible targetservers –m setup

to verify the target server connections


Double take console

I’m not going to go into details here but on the machine you have installed the double take console you add all the servers (source and target), attach the licenses to them and setup full server replication jobs with the parameters of your choice.

Wait before failing over, we will need some more playbooks depending on your server licensing.



On to the interesting stuff, unless you want to manually install double take software on all servers then go do that now 🙂


I downloaded the doubletake software, and unzipped the following directory /setup/dt/x64 folder and placed it in a S3 bucket. If you have 32-bit servers extract also the 32bit folder. The below examples only use the 64bit installer… if the need arises we can create also the 32bit playbook.

Make sure the files are public else you will not be able to download it on the source servers, use a the readonly S3 policy attached to a role for the targetservers.

Before uploading also modifie the DTsetup.ini file to allow a quiet installation. (modify it anyway you want, make sure that the diskqueue folder has around 20gb of free space)





DOUBLETAKEFOLDER="C:\Program Files\Vision Solutions\Double-Take\"


DISKQUEUEFOLDER="C:\Program Files\Vision Solutions\Double-Take\"








When the above is done, we can continue to write our playbooks.

Write the following playbook, place it in the /etc/ansible directory.



# doubletake.yml

# This playbook will silently install doubletake move.

-   name: Install doubletake move

    hosts: sourceservers:targetservers

    gather_facts: false


        - doubletake


Then create the following directory structure


The create the following “role”, save it as main.yml


# Create a temp directory, if it does not exist then the below won’t work

-  name: create temp dir

   win_file: path=C:\temp state=directory

# To download from s3 using the aws command line, we need the aws cli installed

-  name: download aws cli


     url: ''

     dest: 'c:\temp\AWSCLI64.msi'

     force: no

-  name: install aws cli

   win_msi: path=C:\\temp\\AWSCLI64.msi wait=true

-  name: download from S3

   raw: aws s3 cp s3://double-take c:\temp\dt --recursive

-  name: Install doubletake

   raw: CMD /C "c:\temp\dt\setup.exe /s /v"DTSETUPINI=\"c:\temp\dt\DTSetup.ini\" /qn""

-  name: cleanup doubletake

   win_file: path=C:\temp\dt state=absent

Now we can test the doubletake installation like this

Ansible-playbook doubletake.yml

Or if you encrypted the files with vault then

Ansible-playbook doubletake.yml --ask-vault-pass


If everything is working as it should then doubletake should be installed everywhere, nice and fast no?



Windows Licensing


It all depends what you want to do, but this example will change the windows activation to the Aws kms servers, thus using the aws licencing instead of your own or…

Source : “Unable to activate Windows”

Ok that will be a lot of manual work, so let’s not do that.


Since ansible is still a work in progress I found that the module win_unzip does not work all the time.

Therefore I chose to put the ec2install.exe also in an S3 bucket.

(wanted to do download the latest ec2config service from amazon and unzip it , then install it…if it works better in the future I’ll make an update)


Write the following playbook



# windowsactivation.yml

# This will configure the components needed for windows activation on aws

-   name: Windows Activation

    hosts: targetservers

    gather_facts: true


        - windowsactivation


The create the following directory structure


Then write the following main.yml and place it in the dir above


# This role configures the windows activation with aws kms servers

#download the ec2install from our s3 bucket, change the destination if needed

-  name: Download Ec2Install.exe


     url: ''

     dest: 'C:\Users\ansible\Downloads\Ec2Install.exe'

     force: no

# install the ec2config service

-  name: Install the ec2config service

   raw: C:\\Users\\ansible\\Downloads\\Ec2Install.exe /quiet

# set the kms license key silently - below example for 2012R2

-  name: set license key 2012R2

   raw: cscript //B C:\\Windows\\System32\\slmgr.vbs /ipk W3GGN-FT8W3-Y4M27-J84CP-Q3VJ9

#needed kms routes on windows

-  name: kmsroute1

   raw: route add mask -p

-  name: kmsroute2

   raw: route add mask -p

-  name: kmsroute3

   raw: route add mask -p

# reboot to activate the server (ec2config service activates machines at boot time)

-  name: Restart machine

   raw: shutdown /r /f /c "Ansible Activate Windows"

   async: 0

   poll: 0

   ignore_errors: true

#wait for the server to boot

-  name: Waiting for server to come back

   local_action: wait_for

                    host={{ inventory_hostname }}



   sudo: false


DNS forwarder

If you have a domain running you probably also have windows dns, because you now going to move to aws, we need to change to forwarder to aws.

!The below script will replace all your forwarders! If you don’t want this then there is also ‘add-dnsserverforwarder’ and ‘Remove-DnsServerForwarder’.


So maybe create a group in the ansible host file [activedirectory]


To find the ip for the forwarder take your VPC cidr block and change the last digit to 2.

Example: the dns forwarder is at

source : (VPC Subnets –> subnet sizing)


Create the below playbook under /etc/ansible


# name : setdnsforwarder.yml

# playbook to reset the dns forwarders on a microsoft dns server

- name: Reset DNS forwarder

  hosts: activedirectory


    - name: Reset dns forwarders to aws forwarders

      raw: Set-DnsServerForwarder -IPAddress "awsforwarder" –PassThru




Right we have the necessary components now, let do the failover to aws

In the double take console start failing over your servers, best to start with the core servers, like AD, then maybe SQL, exchange.

Then applications servers and webservers… it’s really up to you


When everything is failed over, check to see if ansible is able to reach your servers.

(With Kerberos or local user)

Also it can get confusing now because your target servers are also your source servers now! 🙂


Anyway, run the setdnsforwarder.yml first to make sure you have internet access.

Then run the windowsactivation.yml


Everything should now reboot and come back online, activated with the aws kms server.

Since this is a repeatable process you can first do a testfailover, test this out, tune where needed, then do the actual failover.


If you have questions or just don’t want do to this yourself, contact us by email or phone (+32 3 450 80 30).


Go Automate Something!



Leave a Reply

Your email address will not be published. Required fields are marked *


Need a hand? Or a high five?
Feel free to visit our offices and come say hi
… or just drop us a message

We are ready when you are

Cloudar NV – Operations

De Villermontstraat 9
2550 Kontich (Antwerp)

info @

+32 3 450 67 18

Cloudar NV – HQ

Veldkant 33A
2550 Kontich (Antwerp)

VAT BE0564 763 890

This contact form is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

© 2020 – CLOUDAR NV