Azure / azure-powershell

Microsoft Azure PowerShell
Other
4.26k stars 3.86k forks source link

Import-AzurePublishSettingsFile throws CryptographicException when called from Bamboo OnDemand #16

Closed jnsn closed 9 years ago

jnsn commented 9 years ago

I am trying to automate Azure deployment from a Bamboo OnDemand Amazon EC2 Elastic Instance. Unfortunately, I've hit a bump in the road and I'm not quite sure why or how to solve it.

As an example, I tried the following script:

Write-Output "Importing Azure Module"
Import-Module Azure

Try {
    Write-Output "Importing Azure Publish Settings"
    Import-AzurePublishSettingsFile "C:\Users\Bamboo\azure2.publishsettings" -ErrorAction Stop
}
Catch {
    Write-Output "An error occurred"

    Write-Output $_.Exception.Message
    Write-Output $_.Exception.ItemName
    Write-Output $_.Exception.StackTrace

    exit 1
}

The exception info:

27-Nov-2014 19:01:05    Importing Azure Module
27-Nov-2014 19:01:05    Importing Azure Publish Settings
27-Nov-2014 19:01:05    An error occurred
27-Nov-2014 19:01:05    An internal error occurred.
27-Nov-2014 19:01:05    
27-Nov-2014 19:01:05       at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
27-Nov-2014 19:01:05       at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx)
27-Nov-2014 19:01:05       at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags)
27-Nov-2014 19:01:05       at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password)
27-Nov-2014 19:01:05       at Microsoft.WindowsAzure.Commands.Utilities.Common.PublishSettingsImporter.PublishSubscriptionToAzureSubscription(ProfileClient azureProfileClient, PublishDataPublishProfile profile, PublishDataPublishProfileSubscription s, String environment)
27-Nov-2014 19:01:05       at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
27-Nov-2014 19:01:05       at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
27-Nov-2014 19:01:05       at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
27-Nov-2014 19:01:05       at Microsoft.WindowsAzure.Commands.Common.ProfileClient.ImportPublishSettings(String filePath, String environmentName)
27-Nov-2014 19:01:05       at Microsoft.WindowsAzure.Commands.Profile.ImportAzurePublishSettingsCommand.ImportFile(String fileName)
27-Nov-2014 19:01:05       at Microsoft.WindowsAzure.Commands.Profile.ImportAzurePublishSettingsCommand.ExecuteCmdlet()
27-Nov-2014 19:01:05       at Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet.ProcessRecord()
27-Nov-2014 19:01:05    Failing task since return code of [powershell -ExecutionPolicy bypass -Command C:\Users\Bamboo\AppData\Local\Temp\2457601-2555906-2752561-ScriptBuildTask-1993266622499637567.ps1] was 1 while expected 0
27-Nov-2014 19:01:05    Finished task 'Deploy' with result: Failed

This script is invoked through the build system with the following command:

powershell -ExecutionPolicy bypass -Command C:\Users\Bamboo\AppData\Local\Temp\2457601-2555906-2752561-ScriptBuildTask-1993266622499637567.ps1

The weird part is that, if I RDP onto the VM with the bamboo user and run the Import-AzurePublishSettingsFile "C:\Users\Bamboo\azure2.publishsettings" manually every following execution of the build script succeeds and prints out the result of the Import-AzurePublishSettingsFile call.

In order to save costs, the build server is set on a schedule to shut down between 8 PM and 7 AM which means that currently someone has to log on onto the virtual machine every day and run the command manually before any deployment succeeds. It's understandable that this is becoming a burden on our deployment process.

I know that Bamboo might be a factor in this, but I would like to understand what could be the problem and why this could occur. Could it be something with the way the script is invoked, is there a PowerShell command I must run to elevate certain permissions, ...

Thanks

jnsn commented 9 years ago

I made some, but not much progress.

I noticed that running the Import-AzurePublishSettingsFile once is enough to keep the certificate stored, even after a machine reboot. Then I could use another way to load my subscription info.

$subscriptionId = "MY_SUBSCRIPTION_ID"
$subscription = "MY_SUBSCRIPTION"
$thumbprint = "MY_THUMBPRINT"
$myCert = Get-Item cert:\\CurrentUser\My\$thumbprint
$service = "MY_SERVICE"

Write-Output "Import Azure Module"
Import-Module Azure

Write-Output "Setting Azure Subscription"
Set-AzureSubscription –SubscriptionName $subscription -SubscriptionId $subscriptionId -Certificate $myCert -CurrentStorageAccountName $service
Select-AzureSubscription -SubscriptionName $subscription

Write-Output "Getting deployment info"
$deployment = Get-AzureDeployment -ServiceName $service -Slot $slot -ErrorVariable a -ErrorAction silentlycontinue

But this also fails, with the following output:

28-Nov-2014 08:43:41    Import Azure Module
28-Nov-2014 08:43:41    Setting Azure Subscription
28-Nov-2014 08:43:41    Selecting Azure Subscription
28-Nov-2014 08:43:41    Getting deployment info
28-Nov-2014 08:58:32    An error occurred while sending the request.
28-Nov-2014 08:58:32    The request was aborted: Could not create SSL/TLS secure channel.
28-Nov-2014 08:58:32       at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
28-Nov-2014 08:58:32       at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)
28-Nov-2014 08:58:32       at Microsoft.WindowsAzure.DeploymentOperationsExtensions.GetBySlot(IDeploymentOperations operations, String serviceName, DeploymentSlot deploymentSlot)
28-Nov-2014 08:58:32       at Microsoft.WindowsAzure.Commands.ServiceManagement.HostedServices.GetAzureDeploymentCommand.<OnProcessRecord>b__1()
28-Nov-2014 08:58:32       at Microsoft.WindowsAzure.Commands.Utilities.Common.ServiceManagementBaseCmdlet.ExecuteClientActionNewSM[TResult](Object input, String operationDescription, Func`1 action, Func`3 waitOperation, Func`3 contextFactory)
28-Nov-2014 08:58:32       at Microsoft.WindowsAzure.Commands.Utilities.Common.ServiceManagementBaseCmdlet.ExecuteClientActionNewSM[TResult](Object input, String operationDescription, Func`1 action, Func`3 contextFactory)
28-Nov-2014 08:58:32       at Microsoft.WindowsAzure.Commands.ServiceManagement.HostedServices.GetAzureDeploymentCommand.OnProcessRecord()
28-Nov-2014 08:58:32       at Microsoft.WindowsAzure.Commands.Utilities.Common.CloudBaseCmdlet`1.ProcessRecord()
28-Nov-2014 08:58:32       at System.Management.Automation.CommandProcessor.ProcessRecord()

Again, if I RDP onto the virtual machine and run those commands manually, they perfectly succeed. Any following run of those commands through the build script also succeeds without troubles, until the virtual machine is rebooted again.

markcowl commented 9 years ago

I suspect this has to do with access to certain APIs or to the certificate store on the machine - You should conside using Add-AzureAccount - Credential instead to set up your credentials.

jnsn commented 9 years ago

I posted the same question on the Atlassian forums, as I suspect there's a difference between the use of the user account when the build is triggered through the build agent, opposed to when I RDP into the virtual machine.

For now, I used a workaround to trigger the subscription file import as a scheduled task when the machine boots.

bbonn commented 9 years ago

Hi There,

I am struggling mightily with this exact problem. Have you made any further progress trying to execute the powershell scripts remotely?

I too manually run the importsettings file cmdlet and it seems to stick. But once i try to do certain cmdlets remotely like Get-AzureDeployment I get the ssl error like you did. Any advice?? Stuggling for days :(

Thanks for any info!

bernie

jnsn commented 9 years ago

I ended up using a startup task which imports the publish settings file when the machine booted.

I can't remember whether I just do it for the administrator, or also for the limited bamboo user account which is present on the virtual machine.