10
votes

Problem:
If I call command Get-AzureDeployment(also Get-AzureService) from 'Azure Powershell' task in DevOps Pipeline I am getting: 'The request was aborted: Could not create SSL/TLS secure channel.'

Introduction:

  • I use Azure DevOps to deploy Azure Cloud service (classic) into Azure
  • The 'Azure Powershell' task was working the whole time but then without changing anything it stopped working
  • I have also imported the certificate(used by DevOps) into my pc (by Import-AzurePublishSettingsFile) and tried to run the same powershell script and everytnig works fine so I expect problem in DevOps

DevOps connection:

  • I have created 'Service connection' in Azure DevOps to connect into Azure
  • The Service connection is type of 'Azure Classic' (because 'Azure Resource Manager' is not for 'Cloud service classic')
  • Autentication method of the 'Azure Classic service connection' is 'Certificate based'.
  • I used certificate generated by 'Publish Settings File' for my azure subscription. The certificate was placed by azure into My-subscription->Management certificates (expiration date is in mid 2021)
  • I use this service connection for deploying app (Cloud service classic) into Azure with no problem (by DevOps task 'Azure Cloud Service deployment') but just the 'Azure Powershell' task start failing.

This all was working for 3 months and then stopped working for any reason. The weird thing is that when I was playing with DevOps to find out what is wrong the task was once successfully run, but when I tried that again I got the error again.

I have both logs, from sucessful call and failing call. 2506 lines of logs are identical and the change is after this line.

I can send you both full logs but I don't want to place here so long logs.

Successful try:

VERBOSE: 8:31:40 AM - Begin Operation: Get-AzureDeployment
VERBOSE: 8:31:42 AM - Completed Operation: Get-AzureDeployment
... some other info about the deployment in slot

Log from failing call:

VERBOSE: 9:53:39 AM - Begin Operation: Get-AzureDeployment
##[debug]Caught exception from task script.
##[debug]Error record:
##[debug]Get-AzureDeployment : An error occurred while sending the request.
##[debug]At D:\a\r1\a\_Tools\Powershell\cloud-service_swap-slot.ps1:14 char:15
##[debug]+ ... eployment = Get-AzureDeployment -Slot "Staging" -ServiceName $CloudSe ...
##[debug]+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
##[debug]    + CategoryInfo          : CloseError: (:) [Get-AzureDeployment], HttpRequestException
##[debug]    + FullyQualifiedErrorId : Microsoft.WindowsAzure.Commands.ServiceManagement.HostedServices.GetAzureDeploymentComma    nd
##[debug] 
##[debug]Script stack trace:
##[debug]at <ScriptBlock>, D:\a\r1\a\_Tools\Powershell\cloud-service_swap-slot.ps1: line 14
##[debug]at <ScriptBlock>, <No file>: line 1
##[debug]at <ScriptBlock>, D:\a\_tasks\AzurePowerShell_72a1931b-effb-4d2e-8fd8-f8472a07cb62\3.171.2\AzurePowerShell.ps1: line 145
##[debug]at <ScriptBlock>, D:\a\_tasks\AzurePowerShell_72a1931b-effb-4d2e-8fd8-f8472a07cb62\3.171.2\AzurePowerShell.ps1: line 141
##[debug]at <ScriptBlock>, <No file>: line 1
##[debug]at <ScriptBlock>, <No file>: line 22
##[debug]at <ScriptBlock>, <No file>: line 18
##[debug]at <ScriptBlock>, <No file>: line 1
##[debug]Exception:
##[debug]System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
##[debug]   at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
##[debug]   at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
##[debug]   --- End of inner exception stack trace ---
##[debug]   at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
##[debug]   at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)
##[debug]   at Microsoft.WindowsAzure.Management.Compute.DeploymentOperationsExtensions.GetBySlot(IDeploymentOperations operations, String serviceName, DeploymentSlot deploymentSlot)
##[debug]   at Microsoft.WindowsAzure.Commands.Utilities.Common.ServiceManagementBaseCmdlet.ExecuteClientActionNewSM[TResult](Object input, String operationDescription, Func`1 action, Func`3 contextFactory)
##[error]An error occurred while sending the request.
##[debug]Processed: ##vso[task.logissue type=error]An error occurred while sending the request.
##[debug]Processed: ##vso[task.complete result=Failed]

In both logs I can also find this for adding Azure account into Powershell:

##[debug]Added certificate to the certificate store.
##[command]Set-AzureSubscription -SubscriptionName PXX -SubscriptionId XXXXXX01-09f5-4703-bcc9-6ff914XXXXXX -Certificate ******** -Environment AzureCloud 
##[command]Select-AzureSubscription -SubscriptionId XXXXXX01-09f5-4703-bcc9-6ff914XXXXXX
##[debug]Leaving Initialize-Azure.
## Initializing Azure Complete 

(I have replaced some strings with X)

There is the Powershell task in YAML:

steps:
- task: AzurePowerShell@3
  displayName: 'Swap slots'
  inputs:
    azureConnectionType: ConnectedServiceName
    azureClassicSubscription: 'PXX subscription'
    ScriptPath: '$(System.DefaultWorkingDirectory)/_Tools/Powershell/cloud-service_swap-slot.ps1'
    ScriptArguments: '-CloudServiceName $(CloudServiceName)'
    FailOnStandardError: true
    azurePowerShellVersion: LatestVersion

And the Powershell script for swapping slots that works from local pc (with the same cert) but failing in DevOps:

[CmdletBinding(PositionalBinding=$True)]
Param(
    [Parameter(Mandatory = $true)]
    [String]$CloudServiceName              # required
)

# Check if Windows Azure Powershell is avaiable 
if ((Get-Module -ListAvailable Azure) -eq $null) 
{ 
    throw "Windows Azure Powershell not found! Please install from http://www.windowsazure.com/en-us/downloads/#cmd-line-tools" 
} 
 
# VIP Swap
$Deployment = Get-AzureDeployment -Slot "Staging" -ServiceName $CloudServiceName #It's failing here
if ($Deployment -ne $null -AND $Deployment.DeploymentId  -ne $null) 
{ 
     Write-Output ("Current Status of staging in {0}" -f $CloudServiceName); 
     Write-Host ($Deployment | Select-Object -Property * -ExcludeProperty Configuration,RolesConfiguration | Format-List | Out-String);

     $MoveStatus = Move-AzureDeployment -ServiceName $CloudServiceName 
     Write-Output ("Vip swap of {0} status: {1}" -f $CloudServiceName, $MoveStatus.OperationStatus)     
}else 
{ 
     Write-Output ("There is no deployment in staging slot of {0} to swap." -f $CloudServiceName) 
} 

Does anyone the same experience like me? Where could be the problem?

# Update

I have tried to add this security protocol setting at the begining of the script but with the same error.

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
8
try adding this to the script content before calling azure endpoints: [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls124c74356b41
I have tried that but without any changePetofi
@Petofi Not get your latest information, is Neil's workaround helpful for you?Hugh Lin
@HughLin-MSFT no it didn't helpPetofi
We're experiencing the same issues. Our CI builds have been broken for a day now can we can't release fixes to our customer :(Phil Martin

8 Answers

1
votes

This appears to be an issue with the Microsoft build agents, but adding the following code to the beginning of each Azure Powershell task seems to have resolved this for us until they can figure that out.

$pcert = (Get-Variable Endpoint -ValueOnly).Auth.Parameters.certificate
$bytes = [convert]::FromBase64String($pcert) 
[IO.File]::WriteAllBytes("C:\cert.pfx",$bytes) 
$null = Import-PfxCertificate -FilePath C:\cert.pfx -CertStoreLocation cert:\CurrentUser\My
2
votes

There are few workarounds which are working.

  1. Workaround 1

    1. Use Azure Powershell Task Version 5
    2. Select "Azure Resource Manager Connection"
    3. Change ASM Module commands to Az commands
  2. Workaround 2

    1. Use Azure Powershell Task Version 3
    2. Classic Connection
    3. Downgrade Azure Powershell Version to 4.2.1
  3. Workaround 3 (for private agents)

    1. Create a self-signed cert in your CurrentUser\My store. you can find details on creating a self-signed cert here: https://docs.microsoft.com/en-us/azure/cloud-services/cloud-services-certs-create
    2. Export the public key for the cert as a DER-encoded CER file (you can use mmc or any other cert tool for this)
    3. Upload the .Cer file as a management certificate through the portal: https://docs.microsoft.com/en-us/previous-versions/azure/azure-api-management-certs
    4. Authenticate using Set-AzureSubscription:
     PS C:\> Clear-AzureProfile
     PS C:\> $cert = Get-Item Cert:\CurrentUser\My\
     PS C:\ > Set-AzureSubscription -SubscriptionName "" -SubscriptionId  -Certificate $cert
     PS C:\> Select-AzureSubscription -SubscriptionId 
     
  4. Workaround 4

    1. Add below script to each Azure Powershell task

        $p = (Get-Variable Endpoint -ValueOnly).Auth.Parameters.certificate
        $bytes = [convert]::FromBase64String($p)
        [IO.File]::WriteAllBytes("C:\cert.pfx",$bytes)
        Import-PfxCertificate -FilePath C:\cert.pfx -CertStoreLocation cert:\CurrentUser\My
        .
        .
        actual script
        .
        .
        #remove certificate from store
        $thumb = (Get-PfxData -FilePath "C:\cert.pfx").EndEntityCertificates.Thumbprint
        Remove-Item -Path cert:\CurrentUser\My\$thumb -recurse -Force
      
1
votes

We had the same issue. It only manifested on windows-2019 agents, not vs2017-win2016. So you could fix it by changing the agent type, but a better fix is to use a specific Powershell version of 5.1.1 instead of latest. It seems that latest recently increased to 5.3.0 which causes this error.

1
votes

I have the same issue and tried all these, for me it worked only if I added this after the Initialize-Azure part: "Set-AzureSubscription -SubscriptionId [my subscription id] -CurrentStorageAccountName [storage name]"

1
votes

This issue is caused by a change of behavior introduced with the .NET September update. The following code will restore implicit storage of keys (the previous .Net 4.x behavior) through an environment variable:

Set-Item env:\COMPLUS_CngImplicitPersistKeySet 1

NOTE: You will then need to create a new publishsettings file, as the old certificate and keys will not be overwritten by a subsequent import.

0
votes

Downgrading the Az Powershell version to 4.2.1 works using the AzurePowerShell@3 task.

0
votes

In my case I had this problem in a Get-AzureServiceRemoteDesktopExtension command in a "Run Inline Azure Powershell" task on our on-premises Team Foundation Server 2017.

I tried adding the line @damien-caro suggested here ...

Set-Item env:\COMPLUS_CngImplicitPersistKeySet 1

... to my script, but that only solved the problem for a single release. All subsequent releases/deploys failed with Could not create SSL/TLS secure channel once more.

Simply adding it as a variable to the release definition did solve the problem. (To test it I have successfully deployed the same release to two environments, three times in a row.)

enter image description here

I found this solution here: https://github.com/Azure/azure-powershell/issues/13117#issuecomment-706665722

0
votes

In my case I had accidentally mentioned https instead of http. My report server was http, without cert, but it used to redirect in browser even if I type https internally in our organization. But powershell needs the exact url. The version I used was powershell@2 and I invoked a powershell script file.