Adding domain to existing rule with CLI in Azure Front Door

Recently I wrote a simple script for my CI/CD which was responsible for new tenant onboarding. The key thing was to add a domain to Front Door and adjust the existing routing rule. I decided to use Azure CLI for that but there were some difficulties with making routing rules handle the new domains.

Adding domain to existing rule with CLI in Azure Front Door
This solution works with Azure CLI 2.32.0 and Front Door extension 1.0.16.

Official documentation

Let’s have a look at the official docs of az network front-door routing-rule update command (access 2022-02-05). You can notice that there is no direct way to add a new frontend endpoint to the existing routing rule.

According to this what we could do is update the list of frontend endpoints with –frontend-endpoints flag. This operation would require us to input the whole list of existing frontend endpoints plus the domain that we want to add. Thus we would need to fetch the whole existing configuration and then use it in command. As far as I am concerned, that’s not a way to go.

However, there is another interesting flag named --add. What does the documentation say about this?

Add an object to a list of objects by specifying a path and key value pairs. Example: –add property.listProperty <key=value, string or JSON string>.

Actually, that’s exactly what we need 😊!

Adding the domain to the routing rule

This --add flag is quite tricky to use. Besides the front door name and routing rule name we have to provide property.listProperty and <key=value, string or JSON string>. But what is it and how to get it? We need to look at the resource’s template. Go to Front Door resource and click “Export template”.

Multi-tenant app - tenant 2

We are mostly interested in routingRules section. Relevant lines are highlighted.

"routingRules": [{    "id": "[concat(resourceId('Microsoft.Network/frontdoors',        parameters('frontdoors_fd_test_name')), '/RoutingRules/https')]",    "name": "https",    "properties": {        "frontendEndpoints": [            {                "id": "[concat(resourceId('Microsoft.Network/frontdoors',                    parameters('frontdoors_fd_test_name')), '/frontendendpoints/test1')]"            }        ],        ...    }}
JSON

Hence, in our case property.listProperty is just frontendEndpoints and the second part (key-value pairs) is a string like this: Id={frontendEndpoindId}. Frontend endpoint id may depend on how it has been added. If you add it with CLI or another tool that uses Azure API under the hood, you are able to specify the frontend endpoint name. Otherwise, the name is auto-generated. To make sure what is your Id pattern look at the resource template for frontendEndpoints section. In my case it is something like this (code below), so my endpoint has a name test1.

"frontendEndpoints": [    ...,    {        "id": "[concat(resourceId('Microsoft.Network/frontdoors',            parameters('frontdoors_fd_test_name')), '/FrontendEndpoints/test1')]",        "name": "test1",        "properties": {            "hostName": "test1.example.org",            "sessionAffinityEnabledState": "Disabled",            "sessionAffinityTtlSeconds": 0,            "resourceState": "Enabled"        }    },    ...]
JSON

Therefore, the id pattern is: {frontdoorResourceId}/FrontendEndpoints/{frontendEndpointName} (please verify how does it look like in your case). Eventually, this is how the routing rule update script should look like in Powershell (fill variables according to your needs):

$subscriptionId = "00000000-0000-0000-0000-000000000000"$resourceGroupName = "rg-test"$frontdoorName = "fd-test"$frontendEndpointName = "test2"$routingRuleName = "https"
$frontend_endpoint_id ="/subscriptions/${subscriptionId}" +"/resourceGroups/${resourceGroupName}" +"/providers/Microsoft.Network" +"/frontdoors/${frontdoorName}" +"/frontendEndpoints/${frontendEndpointName}"
az network front-door routing-rule update `    --resource-group $resourceGroupName `    --front-door-name $frontdoorName `    --name $routingRuleName `    --add frontendEndpoints "Id=${frontend_endpoint_id}"
PowerShell

Or Bash:

#!/bin/bash
subscriptionId="00000000-0000-0000-0000-000000000000"resourceGroupName="rg-test"frontdoorName="fd-test"frontendEndpointName="test2"routingRuleName="https"
frontend_endpoint_id="/subscriptions/$subscriptionId\/resourceGroups/$resourceGroupName\/providers/Microsoft.Network\/frontdoors/$frontdoorName\/frontendEndpoints/$frontendEndpointName"
az network front-door routing-rule update \    --resource-group $resourceGroupName \    --front-door-name $frontdoorName \    --name $routingRuleName \    --add frontendEndpoints "Id=$frontend_endpoint_id"
Bash

Infrastructure as a code

You could also use tools that let define infrastructure as a code instead. There are some open-source solutions like Terraform or Pulumi for that purpose. Both in theory support Azure Front Door resource.

Personally, as far as Front Door is concerned, I do not have good experience with solutions like these. It can sometimes behave in an unpredictable way and consequently, you may accidentally break your living application. From what I understand there are some sorting problems connected with routing rules and frontend endpoints. As a result, these tools attempt to apply state changes, even though there are no changes at all. It sometimes results in unclear errors or influences other parts of the whole configuration. I would definitely recommend using Terraform or Pulumi for other types of resources, but not Front Door.

Conclusion

To sum up, adding the frontend domain to the routing rule with CLI is not that simple. As shown above, it requires some low-level knowledge of how Azure Front Door is defined. However, after inspecting the resource template it is doable.

Comments

The comments system is based on GitHub Issues API. Once you add your comment to the linked issue on my GitHub repository, it will show up below.