7

I have configured a CI build for a Service Fabric application, in Visual Studio Team Services, according to this documentation: https://azure.microsoft.com/en-us/documentation/articles/service-fabric-set-up-continuous-integration

But instead of having my CI build do the publishing, I only perform the Build and Package tasks, and include all Service Fabric related output, such as pkg folder, scripts, publish profiles and application parameters, in the drop. This way I can pass it along to the new Release pipeline (agent-based releases) to do the actual deployment of my service fabric application.

In my release definition I have a single Azure Powershell task, that uses an ARM endpoint (with proper service principals configured).

When I deploy my app to an existing service fabric cluster, I use the default Deploy-FabricApplication cmdlet passing along the pkg folder and a publish profile that is configured with a connection to the existing cluster.

The release fails with an error message "Cluster connection instance is null". And I cannot understand why?

Doing some debugging I have found that: The Deploy-FabricApplication cmdlet executes the Connect-ServiceFabricCluster cmdlet just fine, but as soon as the Publish-NewServiceFabricApplication cmdlet takes over execution, then the cluster connection is lost.

I would expect that this scenario is possible using the service fabric cmdlets, but I cannot figure out how to keep the cluster connection open during depoyment.

UPDATE: The link to the documentation no longer refers to the Service Fabric powershell scripts, so the pre-condition for this question is no longer documented. The article now refers to the VSTS build and release tasks, which can be prefered over the powershell cmdlets I tried to use.

riQQ
  • 9,878
  • 7
  • 49
  • 66
mikanyg
  • 393
  • 4
  • 15
  • Can you share the error logs? Did it always occurs? And which agent are you using? Usually, the cluster connection shouldn't lost when run Publish-NewServiceFabricApplication . – Eddie Chen - MSFT Mar 01 '16 at 08:52

4 Answers4

31

When the Connect-ServiceFabricCluster function is called (from Deploy-FabricApplication.ps1) a local $clusterConnection variable is set after the call to Connect-ServiceFabricCluster. You can see that using Get-Variable.

Unfortunately there is logic in some of the SDK scripts that expect that variable to be set but because they run in a different scope, that local variable isn't available.

It works in Visual Studio because the Deploy-FabricApplication.ps1 script is called using dot source notation, which puts the $clusterConnection variable in the current scope.

I'm not sure if there is a way to use dot sourcing when running a script though the release pipeline but you could, as a workaround, make the $clusterConnection variable global right after it's been set via the Connect-ServiceFabricCluster call. Edit your Deploy-FabricApplication.ps1 script and add the following line after the connection logic (~line 169):

$global:clusterConnection = $clusterConnection  

By the way, you might want to consider setting up custom build/release tasks that deploy a Service Fabric application, rather than using the various Deploy-FabricApplication.ps1 scripts.

charisk
  • 3,190
  • 2
  • 24
  • 18
  • Thx for the explanation, will try it out soon, and I had an idea that this was due to some powershell variable scoping issue. I'll look into the custom build tasks, once I have a functional release pipeline up and running. I started with the Deploy-FabricApplication.ps1 since it was mentioned and used in the documentation that I linked to. – mikanyg Mar 01 '16 at 14:52
  • Accept this answer – parek Jun 14 '16 at 11:14
  • THANKS @charisk. :D – Iain Sep 13 '16 at 04:18
  • @charisk, Deploy-FabricApplication.ps1 does not define or use $ClusterConnection anywhere (you can do full text search on entire folder C:\Program Files\Microsoft SDKs\Service Fabric\Tools\PSModule\ServiceFabricSDK\. It's the Connect-ServiceFabricCluster which defines this variable and some SDK functions seem to be depending on it (ones which require connection present). See https://github.com/Azure/service-fabric-issues/issues/137 – illegal-immigrant Jan 18 '17 at 22:17
2

There now exists a built-in VSTS task for deploying a Service Fabric app so you no longer need to bother with executing the PowerShell script on your own. Task documentation page is at https://www.visualstudio.com/docs/build/steps/deploy/service-fabric-deploy. The original CI article has also been updated which provides details on how to set everything up: https://azure.microsoft.com/en-us/documentation/articles/service-fabric-set-up-continuous-integration/.

Matt Thalman
  • 3,540
  • 17
  • 26
  • Saw it a couple days ago, I am really exited since I suggested it on uservoice a couple of month ago. Great work. – mikanyg Aug 04 '16 at 19:54
1

Try to use "PowerShell" task instead of "Azure PowerShell" task.

Eddie Chen - MSFT
  • 29,708
  • 2
  • 46
  • 60
  • Using the "pure" powershell build task made sure that the script was executed using the . (dot) notation which worked like a charm. – mikanyg Mar 01 '16 at 21:46
0

I hit the same bug today and opened a GitHub issue here

On a side note, VS generated script Deploy-FabricApplication.ps1 uses module

"$((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Service Fabric SDK" -Name "FabricSDKPSModulePath").FabricSDKPSModulePath)\ServiceFabricSDK.psm1"

That's where Publish-NewServiceFabricApplication comes from. You can check the deployment logic and rewrite it in more sane way using lower-level ServiceFabric SDK cmdlets (potentially getting connection using Get-ServiceFabricClusterConnection instead of global-ling it)

illegal-immigrant
  • 8,089
  • 9
  • 51
  • 84