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.
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”.
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')]" } ], ... }}
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" } }, ...]
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}"
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"
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.