I was running my hosting on 1and1 hosting (now Ionos) since the early days of the web. In the years I’ve been on that service, I’ve moved it a few times from one of their servers to another (mostly to save a few bucks), so it was time to do a Plesk migration to AWS.

I was trying to turn my web building skills into something that would earn me some passive income, so I had a couple of small clients that I built web sites for in there.

I started getting notices telling me they’d be shutting down the service I was currently on. Since I knew that meant migrating my server, I figured I’d see if I could move it to AWS and maybe make it a bit more reliable. Also to test the theory I’ve heard that you can run your own servers more cheaply on AWS.

Because I had used 1and1, their servers provided different versions of Plesk on them over the years. Plesk is a sort of control panel that makes setting up multiple servers on one virtual machine easier. In my case I host a few servers on the one machine, so it made sense to see if I could do a Plesk migration to AWS on my own.

That turned out to be the first hurdle, as my preference on AWS is to use AWS Linux 2 with spot instances behind a load balancer. Because Plesk assumes it is a standalone server, all of the magic it does to route the right content to the right DNS name doesn’t really work properly behind a load balancer (I spent way too much time trying to figure that out).

I’m getting ahead of myself. So the first thing I did was to create some simple CloudFormation templates:

  1. buildPleskInstance.yaml – this template was to build the instance with Plesk on it.
  2. buildAMI.yaml – to create the AMI from the above instance.
  3. server.yaml – to put Plesk behind an ALB

The hurdle with not using AWS Linux 2 (which is AWS version of CentOS, aka open source Redhat), was that I had to use the Marketplace template from Plesk. The “free” version of their software runs on Ubuntu, so I spent a bunch of time reworking things to fit the difference (apt vs yum, etc)

The first template went really well, I got a vanilla Plesk server set up, and went about figuring out all the Plesk specific commands to make it be up to date. I was able to build it, manually run the Plesk import (process to copy the data from the old Plesk server), and see my content just fine.

I ran the second stack to build the AMI (see: CloudFormation Custom Resources), so was starting to think this was going to go pretty smoothly. The problem was that as soon as the new stack built, hitting any of the URLs that should have given me host specific content (e.g. – www.accuweaver.com) would instead give me the page I’d expect to see for an invalid domain.

Plesk Default Page for Plesk migration to AWS

Lots of Googling and experimenting later, I found a LOT of questions without answers about this exact problem. As an educated guess, it has to do with how the servers are configured under Plesk to use certain HTTP headers. When you put that behind a load balancer, some of those headers get stripped off, so Apache (or NGinX or both) don’t have the right information about the URL being requested so it thinks you’ve set up a DNS entry that points to the server but is not known by it (hence the default page)

That meant I needed to step back to using the first template, and modify that to use my new AMI in order to preserve the migrated content. So my first step was to add the DNS entries I needed to the instance template, which led me to my next problem.

In the setup at Ionos, my main server was using the “free” SSL certificate managed by them. I had thought I would be using the AWS ACM certificate, but those don’t work for non AWS resources (like Apache on an instance), so I had to update my server to exclusively use the LetsEncrypt plugin. Not a big deal as I was already using it for the secondary sites I was hosting, but it did take a minute for me to discover and fix.

After a bit of hacking (lather, rinse repeat), I got it working again, and with the new image got my server working. I marked the AMI as shared to my production account, repeated the process only to realize I had forgotten to subscribe to the Plesk image on the second account (took a bunch of retries to realize that was the failure since that failure doesn’t bubble up to CloudFormation the way you’d like).

With the exception of some updates and times when I’ve had to fix something unexpected, the migration is complete and I’m actually saving a few bucks (even though I’m running a dev and prod server now). I still have a couple of manual steps I’d like to eliminate during the Plesk migration to AWS, but this is getting close.

I still need to figure out how to create a new AMI on a regular basis, and update the CloudFormation stack to use it, since the one risk I face with this design is losing my content (which WordPress stores in both the database and filesystem). I’ve tried to mitigate this a bit by turning on an SSM solution to create an AMI on a regular basis, which should enable me to recreate everything from scratch should something happen.

So I have now completed my Plesk migration to AWS.

Hi, I’m Rob Weaver