Nov 23, 2018 2 min read

Use an Azure Function to redirect url's

Use an Azure Function v2 with a proxy to redirect legacy domains to a new domain.

Use an Azure Function to redirect url's

Before I started this blog, I had a website on https://yannick.reekmans.be and this url is still floating around on the internet. So when the blog was live, I wanted everyone with old url's to be redirected here.
First I did it with the redirect service provided by my domain name registrar, but it intermittently failed on my site but not on theirs (according to them).

So I thought: an Azure Function would be perfect for this! I created an additional function in the same Function App as before (see this post and this post). This time it's an HttpTrigger, named UrlRedirect and made it Anonymous. The code is very simple:

using Microsoft.AspNetCore.Mvc;

public static IActionResult Run(HttpRequest req, ILogger log)
{
    return new RedirectResult("https://blog.yannickreekmans.be", true);
}

Every request that hits my function gets redirected to the new url.

I registered my legacy domains on the Function App and adjusted the Azure Function to generate SSL certificates for them. When testing it out, I got greeted by a nice blue page:

One more thing to do: add an additional Proxy! I named it BlogUrlRedirect (functions and proxies cannot share the same name and must be unique within the Function App). As a route template, I put just the / and as a Backend URL I put https://localhost/api/UrlRedirect

All requests for any of my legacy root domains now get redirected to my blog. You can try it with https://yannick.reekmans.be or https://www.reekmans.be

Caveat

If you want to match the route url and everything that comes after it, to redirect an old post to a new post on your blog you might try /{*all} as a route template. This will work in the browser, but break the Azure Function experience in the Azure Portal. In the portal they try to access some endpoints that exist on https://yourapp/admin/*, but due to the wildcard route these requests fail. It will show the error: The function runtime is unable to start.

I tried working around it with a regex /{*all:regex(^(?admin).*$)} as a route template, to catch all except for paths starting with admin. Apparently Azure Function Proxies don't support regex expressions in the route template (which is supported by .NET and Azure API Management), the feature request for this was declined.

Second workaround I tried creating an additional Proxy that listens to /admin/{*all} (all request methods) and as a Backend Url I used https://localhost/admin/{all}. Supposedly, using localhost in here should bypass the Proxy but when I tried it, I got Infinite loop detected when trying to call a local function or proxy from a proxy.. This means to me that the backend request still lands on the proxy and then gets forwarded to itself until the safeguards kick in.

Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Yannick Reekmans.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.