I can create a custom domain using the Azure Management REST API, and I can create an App Service Managed certificate, which is associated with the custom domain (I think). Maybe not. However, under custom domains in my app service, it shows that I need to add a binding.
Here is the certificate:
https://management.azure.com/subscriptions/xxx-xxx-479a-bb9f-4c7e01d9a379/resourceGroups/MyResourceGroup/providers/Microsoft.Web/sites/xxx20211028195113/hostNameBindings/my.site?api-version=2016-08-01
and
https://management.azure.com/subscriptions/xxx-xxx-479a-bb9f-4c7e01d9a379/resourceGroups/MyResourceGroup/providers/Microsoft.Web/certificates/my.site?api-version=2021-02-01
I used the first end-point to create the custom domain, and the second end-point to create the certificate. I'm not sure how to bind the certificate to the custom domain. I expected the call to create certificate to do that for me since I included the serverFarm in the request body, but it didn't work.
I want to use the Azure Management API to bind the certificate to the custom domain. How can I do that? which endpoint should I use and what values need to be set in the request body?
Any help would be appreciated. Thanks.
For my full code reference, see my other post here: C# .Net Azure Management REST API - Add App Service Managed Certificate - Response = Not Found
EDIT: Showing the Complete Answer
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MyShoppingCart.Helpers.ManagementLibrarySample
{
public class ManagementLibrarySample
{
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 _AlternateResourceGroupName = Startup.StaticConfig.GetValue<string>("Azure:AlternateResourceGroupName");
static string _AppName = Startup.StaticConfig.GetValue<string>("Azure:AppName");
static string _AppServicePlanName = Startup.StaticConfig.GetValue<string>("Azure:AppServicePlanName");
static Uri _baseURI = new Uri($"https://management.azure.com/");
private static string GetAccessToken()
{
var context = new AuthenticationContext("https://login.windows.net/" + _TenantId);
ClientCredential clientCredential = new ClientCredential(_ClientId, _ClientKey);
var tokenResponse = context.AcquireTokenAsync(_baseURI.ToString(), clientCredential).Result;
return tokenResponse.AccessToken;
}
public static async Task<bool> CreateCustomDomainAndCertificate(string sHostName)
{
bool ret = false;
HttpResponseMessage responseMessage = await CreateCustomDomain(sHostName);
if (responseMessage.IsSuccessStatusCode)
{
responseMessage = await CreateAppManagedCertificate(sHostName);
/*
it can take a good 5 minutes to create the certificate
but you get the 202 status code right away.
You cannot bind the certificate to the custom domain
name until after the certificate actually exists.
*/
if ((long)responseMessage.StatusCode == 202)// Accepted
{
DateTime dtStart = DateTime.Now;
while ((long)responseMessage.StatusCode != 200 && DateTime.Now < dtStart.AddMinutes(10))
{//Wait until the certificate has been created, up to 10 minutes
Thread.Sleep(60000);//1 minute
responseMessage = await BindCertificateToCustomDomain(sHostName);
}
if ((long)responseMessage.StatusCode == 200)
ret = true;
}
}
return ret;
}
private static async Task<HttpResponseMessage> CreateCustomDomain(string sHostName)
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + GetAccessToken());
string requestURl = _baseURI + $"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");
return await client.PutAsync(requestURl, stringContent);
}
}
private static async Task<HttpResponseMessage> CreateAppManagedCertificate(string sHostName)
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + GetAccessToken());
string requestURl = _baseURI + $"subscriptions/{_SubscriptionId}/resourceGroups/{_ResourceGroupName}/providers/Microsoft.Web/certificates/{sHostName}?api-version=2021-02-01";
string serverFarm = $"/subscriptions/{_SubscriptionId}/resourceGroups/{_AlternateResourceGroupName}/providers/Microsoft.Web/serverfarms/{_AppServicePlanName}";
string body = $"{{\"location\": \"West US\", \"properties\": {{\"canonicalName\": \"{sHostName}\", \"hostNames\": [\"{sHostName}\"], \"serverFarmId\": \"{serverFarm}\"}}}}";
var stringContent = new StringContent(body, Encoding.UTF8, "application/json");
return await client.PutAsync(requestURl, stringContent);
}
}
private static async Task<HttpResponseMessage> BindCertificateToCustomDomain(string sHostName)
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + GetAccessToken());
string requestURl = _baseURI + $"subscriptions/{_SubscriptionId}/resourceGroups/{_ResourceGroupName}/providers/Microsoft.Web/sites/{_AppName}?api-version=2016-08-01";
string serverFarm = $"/subscriptions/{_SubscriptionId}/resourceGroups/{_AlternateResourceGroupName}/providers/Microsoft.Web/serverfarms/{_AppServicePlanName}";
string body = $"{{\"location\": \"West US\", \"properties\": {{\"HostNameSslStates\": [ {{ \"SslState\" : \"1\", \"ToUpdate\" : \"True\", \"Name\": \"{sHostName}\"}}]}}, \"kind\": \"app\", \"location\": \"West US\", \"tags\" : {{\"hidden-related:{serverFarm}\": \"empty\"}}}}";
var stringContent = new StringContent(body, Encoding.UTF8, "application/json");
return await client.PutAsync(requestURl, stringContent);
}
}
}
}
How can I use the Management API to secure the custom domain with the app service managed certificate? Thanks @David.Warwick for the confirmation, As we have discussed to achieve the above requirement we have to use the below Rest API .
You can try with PUT method for binding SSL certificate with Custom domain.
https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroup}/providers/Microsoft.Web/sites/{snapshotName}?api-version={api-version}
For more information please refer this SO THREAD