azure-functionspowershell-core

Azure Function App: "Exception calling ".ctor"


Within an Azure Function App (Powershell 7.4; Windows, TimeTrigger, App Service Plan Y1) I am trying to load a certificate from a KeyVault:

$pfxSecret = Get-AzKeyVaultSecret -VaultName "myVault" -Name "mySecret -AsPlainText
$certBytes = [Convert]::FromBase64String($pfxSecret)

During the conversion to an X509 certificate ...

$x509Cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($certBytes, "")

Powershell crashes:

System.Management.Automation.ParentContainsErrorRecordException Message : [ERROR] while converting Certificate to X509: Exception calling ".ctor" with "2" argument(s): "The system cannot find the file specified."

HResult : -2146233087 CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException FullyQualifiedErrorId : RuntimeException WasThrownFromThrowStatement : True Message : [ERROR] while converting Certificate to X509: Exception calling ".ctor" with "2" argument(s): "The system cannot find the file specified."

However, this error only occurs after the cold start of a function. It seems that for a certain reason my command within profile.ps1 is not working correctly:

Add-Type -AssemblyName System.Core

Solution

  • Primarily, I enabled managed identity in function app and granted the permissions using Access policies or you can use RBAC roles too, to fetch the certificate.

    I only have 'Az.KeyVault' = '4.*' module in requirements.psd1 file.

    I have below given code in the function app.

    using namespace System.Net
    
    param($Request, $TriggerMetadata)
    
    Write-Host "PowerShell HTTP trigger function processed a request."
    
    $pfxSecret = Get-AzKeyVaultSecret -VaultName "afreenKvv" -Name "testcert" -AsPlainText
    $certBytes = [Convert]::FromBase64String($pfxSecret)
    $x509Cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($certBytes, "")
    
    Write-Host "Certificate: $x509Cert"
    
    $body = "Retrieved certificate: $x509Cert"
    
    Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
        StatusCode = [HttpStatusCode]::OK
        Body = $body
    })
    

    This gives me expected response and also it worked after a cold start.

    enter image description here

    For App Service Plan Function App, use below command.

    $pfxSecret = Get-AzKeyVaultSecret -VaultName "KeyVaultName" -Name "testcert" -AsPlainText
    $certBytes = [Convert]::FromBase64String($pfxSecret)
    $x509Cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($certBytes, "", [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet)