2

How to upload a private, public certificate to the Azure AppService using Azure Powershell. I am aware of New-AzureRmWebAppSSLBinding but I am not doing any SSL binding.

We have Azure App Services that use SSL binding. I used New-AzureRmWebAppSSLBinding to upload a certificate for this purpose. I did upload a cert for each host on my web app. This works fine. But I wanted to upload additional private and public certs on to this app service for API validation. I did not find any azure powershell command to upload a private or public certificate.

Azure portal allows uploading a private certificate along with its password or a public certificate. However I want to do the same using powershell. The portal UI also has an option to import certificate from key vault. I sure can upload a certificate to key vault but there is no powershell command to import it on to Azure app service.

<a href="https://ibb.co/Kh7t5DL"><img src="https://i.ibb.co/fFt3X9n/Capture-Cert.jpg" alt="Capture-Cert" border="0"></a>

I have gone through these articles but they both use the same command. https://github.com/Azure/azure-powershell/issues/2108 How to add a certificate to an Azure RM website with Powershell

New-AzureRmWebAppSSLBinding -ResourceGroupName $RGName -WebAppName $webAppName -CertificateFilePath $filePath -CertificatePassword $pass

If I call this method it asks for the host name. Since I already uploaded a certificate with SSL binding for this hostname I cannot use it. Without supplying a hostname this command will fail.

Raja Chava
  • 81
  • 2
  • 9

2 Answers2

3

Ok, finally I was able to figure it out and upload both private and public certs. Azure resource explorer was really helpful to understand the folder structure and certificate location.

To upload Public certificate: These are attached per app service.

$webApps = @{
            "Dev_AppServicesGroup" = "DevUserService"
        }
$certName = "chain-cert.cer"
$Path = "C:\Certs"    

$fullpath = $path + '\' + $certname
$pwd = ConvertTo-SecureString -String 'anyPwd' -AsPlainText -Force
$cert  = New-AzureRmApplicationGatewaySslCertificate -Name 'someCert' -CertificateFile $fullpath -Password $pwd
$apiVersion = '2018-02-01'

if($cert)
{
    $PropertiesObject = @{
        blob=$cert.Data; 
        publicCertificateLocation= "CurrentUserMy"
    }

    foreach($resourceGroup in $webApps.Keys)
    {
       $webAppName = $webApps.Item($resourceGroup)        
       $resource = Get-AzureRmWebApp -ResourceGroupName $resourceGroup -Name $webAppName
       $resourceName = $resource.Name + "/"+$certName
       New-AzureRmResource -Location $resource.Location -PropertyObject $PropertiesObject -ResourceGroupName $resource.ResourceGroup -ResourceType Microsoft.Web/sites/publicCertificates -ResourceName $resourceName -ApiVersion $apiVersion -Force        

       #Apply the cert to the deployment slots if any
       $slots = Get-AzureRmResource -ResourceGroupName $resource.ResourceGroup -ResourceType Microsoft.Web/sites/slots -ResourceName $webAppName -ApiVersion $apiVersion
       foreach($slot in $slots)
       {            
          $resourceName = $slot.Name + "/"+$certName                     
          New-AzureRmResource -Location $slot.Location -PropertyObject $PropertiesObject -ResourceGroupName $slot.ResourceGroupName -ResourceType Microsoft.Web/sites/slots/publicCertificates -ResourceName $resourceName -ApiVersion $apiVersion -Force            
       }
    }
}

To upload Private certificate: These are uploaded per resource group and are available to all app services under that group.

#Private certs needs to be uploaded to each resource group with app services
$resourceGroups = @("Dev_AppServicesGroup1", "Dev_AppServicesGroup2")
$certName = "event-store-user.p12"

$certPwd = "Your certificate password" #This is the private cert password
$Path = "C:\Certs"   

$fullpath = $path + '\' + $certname    

$pwd = ConvertTo-SecureString -String 'SomePwd' -AsPlainText -Force
$cert  = New-AzureRmApplicationGatewaySslCertificate -Name someCert -CertificateFile $fullpath -Password $pwd
$apiVersion = '2018-02-01'

if($cert)
{
    $PropertiesObject = @{
        pfxBlob=$cert.Data;  
        password =$certPwd; #This is the private cert password        
        ResourceType = "Microsoft.Web/Certificates"
    }

    foreach($resourceGroup in $resourceGroups)
    {
        $resource = Get-AzureRmResourceGroup -Name $resourceGroup       
        New-AzureRmResource -ResourceName $certName -Location $resource.Location -PropertyObject $PropertiesObject -ResourceGroupName $resource.ResourceGroupName -ResourceType Microsoft.Web/certificates -ApiVersion $apiVersion -Force        
    }
}

That's it. To upload SSL certificate and bind it to the app service you can use the command 'New-AzWebAppSSLBinding'.

Raja Chava
  • 81
  • 2
  • 9
0

According to my test, if you want to bind ssl for your Azure web app, you can refer to the following script:

$webappName=""
$groupName=""
# set custom doamin
$fqdn="<your custom domain name>"
Set-AzureRmWebApp -Name $webappName -ResourceGroupName $groupName -HostNames($fqdn, "$webappName.azurewebsites.net") 

#bind ssl
$pfxPath="<Replace with path to your .PFX file>"
$pfxPassword="<Replace with your .PFX password>"
#Upload and bind the SSL certificate to the web app
New-AzureRmWebAppSSLBinding -WebAppName $webappName -ResourceGroupName $groupName -Name $fqdn -CertificateFilePath $pfxPath -CertificatePassword $pfxPassword -SslState SniEnabled   

#bind an existing Azure certificate
New-AzureRmWebAppSSLBinding -WebAppName $webappName -ResourceGroupName $groupName -Name $fqdn -Thumbprint "the thumbprint of the cert"
Jim Xu
  • 21,610
  • 2
  • 19
  • 39
  • As I mentioned I already used that command to bind SSL certificate to my app. I was talking about uploading additional private and public certificates. – Raja Chava Sep 18 '19 at 12:30
  • According to my research, we can use Azure CLI command ```az webapp config ssl upload``` to upload Private Key Certificates. For more details, please refer to https://learn.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-custom-ssl#azure-cli – Jim Xu Sep 19 '19 at 06:18
  • that command is the equivalent of New-AzWebAppSSLBinding. See the example code of CLI and powershell in the page you have shared. My requirement is to upload private and public certs and not SSL binding. These are different things. – Raja Chava Sep 19 '19 at 13:41
  • The command ```az webapp config ssl upload``` just is used to upload Private Key Certificates. If you want to bind ssl, we should continue to run the command ```az webapp config ssl bind``` – Jim Xu Sep 19 '19 at 13:44
  • 1
    Regarding how to upload public certs, I need to do some test. – Jim Xu Sep 19 '19 at 13:45
  • Hi @RajaChava According to my research, Azure Powershell does not provide the command to upload private or public certificate. If you want to upload it, you can use the [Azure rest api](https://learn.microsoft.com/en-us/rest/api/appservice/webapps/createorupdatepubliccertificate) to implement it. For more details, please refer to https://github.com/MicrosoftDocs/azure-docs/issues/39122. – Jim Xu Sep 23 '19 at 05:31
  • Thanks Jim. I will explore further and try the API route. – Raja Chava Sep 24 '19 at 12:40