I can use the Azure Management REST API to add a custom domain to my Azure App Service. I also need to secure that custom domain by adding a App Managed Certificate to my app service.
static string _ClientId = Startup.StaticConfig.GetValue<string>("Azure:ClientId");
static string _ClientKey = Startup.StaticConfig.GetValue<string>("Azure:ClientSecret");
static string _TenantId = Startup.StaticConfig.GetValue<string>("Azure:TenantId");
static string _SubscriptionId = Startup.StaticConfig.GetValue<string>("Azure:SubscriptionId");
static string _ResourceGroupName = Startup.StaticConfig.GetValue<string>("Azure:ResourceGroupName");
static string _AppName = Startup.StaticConfig.GetValue<string>("Azure:AppName");
static string _AppServicePlanName = Startup.StaticConfig.GetValue<string>("Azure:AppServicePlanName");
public static string ResourceGroupName { get => _ResourceGroupName; set => _ResourceGroupName = value; }
public static async Task<HttpStatusCode> AddHostNameFromForumResponse(string sHostName)
{
HttpResponseMessage responseMessage;
var appId = _ClientId;
var secretKey = _ClientKey;
var tenantId = _TenantId;
var context = new AuthenticationContext("https://login.windows.net/" + tenantId);
ClientCredential clientCredential = new ClientCredential(appId, secretKey);
var tokenResponse = context.AcquireTokenAsync("https://management.azure.com/", clientCredential).Result;
var accessToken = tokenResponse.AccessToken;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
var baseUrl = new Uri($"https://management.azure.com/");
var requestURl = baseUrl + $"subscriptions/{_SubscriptionId}/resourceGroups/{_ResourceGroupName}/providers/Microsoft.Web/sites/{_AppName}/hostNameBindings/{sHostName}?api-version=2016-08-01";
string body = $"{{\"properties\": {{\"azureResourceName\": \"{_AppName}\"}}}}";
var stringContent = new StringContent(body, Encoding.UTF8, "application/json");
responseMessage = await client.PutAsync(requestURl, stringContent);
if (((long)responseMessage.StatusCode == 200)) // Trying to create the app managed certificate here
{
//requestURl = baseUrl + $"subscriptions/{_SubscriptionId}/resourceGroups/{_ResourceGroupName}/providers/Microsoft.Web/certificates/{sHostName}?api-version=2019-08-01";
requestURl = baseUrl + $"subscriptions/{_SubscriptionId}/resourceGroups/{_ResourceGroupName}/providers/Microsoft.Web/certificates/{sHostName}?api-version=2021-02-01";
var serverFarm = $"/subscriptions/{_SubscriptionId}/resourceGroups/{_ResourceGroupName}/providers/Microsoft.Web/serverfarms/{_AppServicePlanName}";
body = $"{{\"location\": \"West US\", \"properties\": {{\"canonicalName\": \"{sHostName}\", \"hostNames\": [\"{sHostName}\"], \"serverFarmId\": \"{serverFarm}\"}}}}";
stringContent = new StringContent(body, Encoding.UTF8, "application/json");
responseMessage = await client.PutAsync(requestURl, stringContent);
}
}
return responseMessage.StatusCode;
I can add the domain, but when I try to PUT the app managed certificate, I get response message 404 - Not Found
.
I was originally following https://learn.microsoft.com/en-us/answers/questions/491924/creating-app-service-managed-certificates-via-api.html which has an api version of 2019-08-01, but then I found https://learn.microsoft.com/en-us/rest/api/appservice/certificates/create-or-update which has an api version of 2021-02-01.
I am confused by the serverFarm
AppServicePlanName
.
Notice the (B1: 1)
. Not sure if that is part of the app service name or not. I've tried it with and without. It didn't seem to make a difference.
Here are the relevant values:
requestUrl = https://management.azure.com/subscriptions/xxx-xx-4c7e01d9a379/resourceGroups/MyResourceGroup/providers/Microsoft.Web/certificates/contoso.com?api-version=2021-02-01
serverFarm = /subscriptions/xxx-xx-4c7e01d9a379/resourceGroups/MyResourceGroup/providers/Microsoft.Web/serverfarms/ResourceGroup-80c2
{"location": "East US", "properties": {"canonicalName": "contoso.com", "hostNames": ["contoso.com"], "serverFarmId": "/subscriptions/9497817f-xxxx-479a-bb9f-4c7e01d9a379/resourceGroups/MyShoppingCartResourceGroup/providers/Microsoft.Web/serverfarms/ASP-ResourceGroup-80c2"}}
Why would I be getting a 404 Not Found? Anyone have any ideas?
EDIT: Sharing the Answer
I figured out the problem. Apparently there are 2 different versions of the App Service Plan name. I assume this is just to over-complicate things. This wasn't an issue when I was creating the domain. It was only an issue when creating the certificate for the domain. And you have to use both versions of the App Service Plan name in the serverFarm when creating the certificate. See the screen shot from my App Service Plan:
Here is the correct version of the serverFarm Id:
/subscriptions/xxx-xx-xxxx-xx-xxx-4c7e01d9a379/resourceGroups/X-XXX-Resource-Group/providers/Microsoft.Web/serverfarms/XXX-XXXResourceGroup-80c2
After /resourceGroups put the one that I highlighted in Yellow. After serverfarms put the other one, without the (B1: 1).