azurepowershellazure-web-app-serviceazure-cli

How do I change from Bring Your Own Certificate to Azure Managed for an App Service?


I have multiple App Service with custom domains that I've uploaded a certificate for. Now I want to change from Bring Your Own Certificate to using Azure Managed Certificate so I don't have to update them once a year. How can I create new certificates in bulk?


Solution

  • Using Azure CLI and powershell we can first create a new certificate that is managed by Azure and then bind that certificate to the custom hostname.

    param([string[]]$resourceIds)
    
    foreach ($resourceId in $resourceIds)
    {
        # Gather info about the web app
        $output = az webapp show --ids $resourceId
        $webApp = ConvertFrom-Json -Input ($output -join ' ')
        $hostname = $webApp.enabledHostNames | Where-Object { $_ -like '*.mydomain.com' } # <-- Here you'll have to change to something that will match the hostname you'll want to bind the certificate to
        $subscription = ($webApp.id -split '/')[2]
        $rg = ($webApp.id -split '/')[4]
    
        # Specifying a cert name is optional but this format will match certs created previously in the Azure Portal
        $certificateName = "$hostname-$($webApp.name)"
    
        # Create the new certificate
        $output = az webapp config ssl create `
            --hostname $hostname `
            --name $webApp.name `
            --certificate-name $certificateName `
            --resource-group $rg `
            --subscription $subscription
    
        $cert = ConvertFrom-Json -Input ($output -join ' ')
    
        $thumbprint = $cert.properties.thumbprint
    
        # Bind the new cert
        az webapp config ssl bind --certificate-thumbprint $thumbprint --ssl-type SNI --ids $resourceId
    }
    

    Save it and invoke with one or more resource ids:

    > .\Use-ManagedCertificate.ps1 -resourceIds /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Web/sites/<app-name>,/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Web/sites/<another-app-name>
    

    If you haven't changed the default name or at least have predictable names this will get you started in figuring out where you are using your own certs using Azure Resource Graph Explorer:

    resources
     | where type has 'microsoft.web/sites'
     | project id, name, properties.hostNameSslStates
     | mv-expand properties_hostNameSslStates
     | where properties_hostNameSslStates.name has '.mydomain.com' // Don't forget to update hostname
     | where properties_hostNameSslStates.certificateResourceId
         !endswith strcat_delim('-', properties_hostNameSslStates.name, name) // This will exclude all certs that has the naming format of the ones that have been created in the Azure Portal
     | project id,
               name,
               resourceGroup = tostring(split(id, '/')[4]),
               thumbprint = properties_hostNameSslStates.thumbprint,
               domain = properties_hostNameSslStates.name
     | order by name