Intro
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 (http://docs.ansible.com/ansible/ )
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.
(http://www.visionsolutions.com/products/windows/double-take-move/overview)
Prep work
Ah yes, there is always some prep work to do. (more if your not already using Ansible now)
AWS
Lets first configure the Aws environment, create the needed vpc, subnets,vpn’s, seurity groups, roles,etc…
VPC
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.
Example:
DHCP options set ID: dopt-xxxxxx | NameHere Options: 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 https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm yum install ansible useradd ansible chown ansible.ansible /etc/ansible/ -R sudo su - ansible ssh-keygen
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.
Kerberos
Edit the /etc/krb5.conf file and change it to reflect your domain
[logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] 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} [realms] FQDN.IN.CAPITALS = { kdc = ip or fqdn.of.your.first.domain.controller kdc = ip or fqdn.of.your.second.domain.controller default_domain = fqdn.in.lower.case kpasswd_server = ip or fqdn.of.your.first.domain.controller kpasswd_server = ip or fqdn.of.your.second.domain.controller } [domain_realm] .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
klist
Inventory
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
[sourceservers] Thefirstserver.yourdomain.something Thesecondserver.yourdomain.something Thethirdserver.yourdomain.something [targetservers] Firsttargetip Secondtargetip Thirdtargetip
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
[sourceservers] Thefirstserver.yourdomain.something Thesecondserver.yourdomain.something Thethirdserver.yourdomain.something [sourceservers:vars] 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 : http://docs.ansible.com/ansible/intro_windows.html
- 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.
Firewalls
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.
Playbooks
On to the interesting stuff, unless you want to manually install double take software on all servers then go do that now 🙂
Doubletake
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)
[Config] DTSETUPTYPE=DTSO DTACTIVATIONCODE=1111222233334444 DOUBLETAKEFOLDER="C:\Program Files\Vision Solutions\Double-Take\" QMEMORYBUFFERMAX=1024 DISKQUEUEFOLDER="C:\Program Files\Vision Solutions\Double-Take\" DISKQUEUEMAXSIZE=UNLIMITED DISKFREESPACEMIN=50 DTSERVICESTARTUP=1 PORT=6320 WINFW_CONFIG_OPTION=NOT_INUSE_ONLY LICENSE_ACTIVATION_OPTION=1
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 roles: - doubletake
Then create the following directory structure
/etc/ansible/roles/doubletake/tasks/
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 win_get_url: url: 'https://s3.amazonaws.com/aws-cli/AWSCLI64.msi' 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 roles: - windowsactivation
The create the following directory structure
/etc/ansible/roles/windowsactivation/tasks/
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 win_get_url: url: 'https://s3-eu-west-1.amazonaws.com/double-take/Ec2Install.exe' 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 169.254.169.251 mask 255.255.255.255 10.41.0.1 -p - name: kmsroute2 raw: route add 169.254.169.252 mask 255.255.255.255 10.41.0.1 -p - name: kmsroute3 raw: route add 169.254.169.254 mask 255.255.255.255 10.41.0.1 -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 }} state=started timeout=60 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: 10.41.0.0/16 the dns forwarder is at 10.41.0.2
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 tasks: - name: Reset dns forwarders to aws forwarders raw: Set-DnsServerForwarder -IPAddress "awsforwarder" –PassThru
Failover
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!
Pauwel