Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding Azure Web App Service Custom Domain during Devops Deployment

An App Service custom domain requires validation at deployment time which in turn requires a DNS CNAME to point to the new app service name. The app service name is, however, created dynamically, so we do not know the name it will have at deployment time. This https://learn.microsoft.com/en-us/azure/app-service/manage-custom-dns-migrate-domain almost solves the problem but it also requires you to know the app service name prior to deployment.

I have tried an App Gateway instead to sit in front of the App Service and editing the URLs in in a rewrite rule. This partially works but unfortunately, it has a documented bug where if there are many Set-Cookie to rewrite, it rewrites the first and deletes the rest. Therefore, we cannot rewrite headers on the App Gateway (until such time as MS fix the bug) and have instead to send the public URL all the way to the back end App Service, hence why we need the custom domain defined on the App Service itself.

The question is: how do I create a Custom Domain on an App Service the the time of deployment using Azure Devops if I do not know the name of the App Service until it is created?

like image 473
Mark Avatar asked Nov 07 '22 07:11

Mark


1 Answers

I ran into the same issue as you, OP - and like you, I felt it was utterly pointless to attempt applying custom DNS config through a pipeline at all if it was necessary to create the DNS record by hand. What's the point of CI/CD then?!

My company's DNS runs through Cloudflare, so my solution to this problem is...

  • Create an API Token in Cloudflare with permission to manage DNS for the domain in question - stored in Azure Key Vault, and injected into the pipeline with a variable group (via a service connection)
  • Deploy an initial ARM template that contains just the resources, including the App Service(s), without any DNS config applied
  • The initial ARM template declares output variables for the website name, app service plan name, custom domain verification ID, and anything else needed further down in the pipeline
  • I wrote a PowerShell script that takes the output variables from the previous step, and makes REST calls to Cloudflare to check if the CNAME and TXT records exist - if they don't, create them. If they do, update them. (Because maybe something changed!)
  • Deploy a second ARM template that simply applies the custom domain config to any app services it needs to

I have currently got my pipeline to the point where its updating DNS in Cloudflare - I have an error in the second template deployment, because I forgot to pass its parameters, heh.

It's not 100% ideal, but it's a solid workaround, IMO, and requires no manual steps. I'll report back when I'm completely finished with it, and I'm happy to share code snippets at that time if you need them.

EDIT: This solution appears to have worked! I've deployed the app I was working with to two brand new environments that had no resources provisioned at all, and no pre-existing DNS entries. Everything worked perfectly!

EDIT2: I should mention, I went through this process a second time for a different project - but I used Terraform instead, and it was a far smoother experience! No need to mess with PowerShell or nested deployments at all! Everything just worked! :)

like image 146
CaptainStealthy Avatar answered Nov 11 '22 09:11

CaptainStealthy