How to setup dynamic customer domains with SSL, CloudFlare and AWS ALB
Every one of us has seen or even used a SaaS product that has an ability to use your company’s domain name to point to this application. For example, imagine that there is a mail service called "mailito.com", but the company mkdev doesn't want to have an email in the domain mkdev.mailito.com, they prefer to use mail.mkdev.me. To achieve this, mailito.com needs to somehow configure SSL and DNS so that customer’s domain resolves to mailito.com application domain.
Now, imagine that mailito.com has 1000 customers, and they need to do the same exercise for every one of the customers. This exercise comes with a number of problems, but the biggest one is always the combination between DNS and SSL.
When a customer goes to mail.mkdev.me, they would prefer to have a valid certificate pointing to mail.mkdev.me instead of having any other certificate that would break the connection. The problem here is that mailito.com can't tell their customers that they need to be DNS experts. The work to setup a correct SSL certificate for mkdev.me domain needs to be done on mailito.com’s side.
The way it’s usually implemented is by asking the customer to create a CNAME entry in their DNS provider that will point to mailito.com. The CNAME will point to the customer-specific hostname on mailito.com domain, and from there to a load balancer and to the application.
So, most people with infra on AWS will say, let's do that with AWS, as AWS allows this functionality. However, AWS comes with a problem: the limit. There is a maximum of 25 SSL Certificates per Application Load Balancer (excluding default certificates). And even though you could request more, we're not talking here about just 25 more or even 100. We want to have thousands of customers, and possibly even more.
There are some amusing solutions to this problem on the internet, like adding a new ALB for every 25 certificates or every 50. But, for sure, this is not a solution - we want something that can be also easily automated from inside our application code, we want to provision all of this with a simple API call.
So, we have two options: automate this crazy idea or find a new solution. And one of the best solutions is called Cloudflare for SaaS. With Cloudflare, we will be able to solve all our problems in a simple console and with just a few clicks.
Naturally, you only do that in a console to learn, and later on you automate this with Terraform and integration over CloudFlare API!
mail.mkdev.me → CNAME → mailito.com
That’s how to set it up:
1) First, in Cloudflare (where we control mailito.com), we have to set up two entries in the DNS:
CNAME proxy-fallback mailito.com CNAME *.cname proxy-fallback.mailito.com
proxy-fallback is a possible name to be used as a proxy-fallback direction in the next step, and
*.cname is the CNAME target for your customers.
As we are talking about AWS in this case, proxy-fallback would point to your ALB Hostname. Of course, you will also need to update your application source code to properly parse incoming hostname and show the correct information to visitors depending on the hostname that was requested.
CNAME mail.mkdev.com mailito.cname.mailito.com
And TXT records that CloudFlare will give to you when you add a custom hostname at the step 2.
Cloud Native consulting: regardless if you are just getting started, or looking for a big shift from the old ways to the future, we are here to help. About consulting
And that's all. We only need to wait a few minutes until everything turns green, and now when we go to mail.mkdev.me, we end up on mailito.com, but with the certificate pointing to mkdev. CloudFlare will automatically create proper SSL certificates for every custom domain. The best part is that the first 100 custom hostnames are included for free, and you pay 0.10$ for extra domains, with a default maximum of 5 000 hostnames. You can keep a single ALB behind CloudFlare and avoid provisioning new ones for every 25 certificates, because all certificates and DNS will be handled by CloudFlare. In a future article, I will explain how to do the same, but for Google Cloud Platform Cloud Run.