Not deploying DLLs in GAC for multi server environments where DeployDB=false?

Topics: Server Deployment
Oct 7, 2015 at 5:07 AM
Hello,

We recently deployed our many BizTalk applications via BTDF 5.5 into an environment that has three Biztalk servers.

On the first and second server, DeployDB is set to false. On the second and last server DeployDB is set to true.

We were puzzled when on the first two servers, it did not appear to GAC the BizTalk artefact DLLs? This caused our IIS web services we also deployed to fail as it had unresolved dependancies due to the DLLs not being in the GAC.

Is this expected behaviour for BTDF 5.5? Is there a way we can get an BTDF installation on a non primary server (DeployDB=false) to install all the Biztalk DLL artefacts to the GAC too?

Thanks!
Oct 7, 2015 at 6:00 AM
Doing more investigations... I can see the following in the BizTalkDeploymentFramework.targets for V5.5:
  <Target Name="DeploySchemas" DependsOnTargets="UndeploySchemas" Condition="'$(IncludeSchemas)' == 'true'">
    <!-- Deploy schema assemblies. -->

    <Exec
      Command="BTSTask.exe AddResource -Type:BizTalkAssembly -Source:&quot;@(SchemasQualified)&quot; -ApplicationName:&quot;$(BizTalkAppName)&quot; -Options:GacOnAdd,GacOnImport,GacOnInstall"
      Condition="'$(DeployBizTalkMgmtDB)' == 'true' and '%(Identity)' == '%(Identity)'" />

    <Exec Command="&quot;$(Gacutil)&quot; /f /i &quot;@(SchemasQualified)&quot;"
          Condition="'$(DeployBizTalkMgmtDB)' == 'false' and '%(Identity)' == '%(Identity)'" />
  </Target>
I can see where if the DeployBizTalkMgmtDB flag is false it should just do a GAC only... I assume that is case sensitive?
Coordinator
Oct 7, 2015 at 6:16 AM
The condition is not case sensitive. Are you sure you're looking in the right GAC? There are two -- one for .NET 2.x and one for .NET 4.x. Ensure that all of your assemblies across your BizTalk solutions have the same target framework version. I'm assuming that you're on 4.x, so you should be checking \Windows\Microsoft.NET\assembly not \Windows\assembly.

Are you using a custom script for these deployments, or using the built-in deployment commands in the Start menu? If custom, please try with the built-in commands first.

You should see all the GACUTIL output in the deployment logs on the first two servers.

Thanks,
Tom
Oct 7, 2015 at 6:34 AM
I have compared the logs for a server that has DeployBizTalkMgmtDB set to false and one set to true.
It appears to be skipping the DeploySchema and other standard Artifact steps altogether.

I also noticed this in the BizTalkDeploymentFramework.targets which I would assume should just GAC standard artefacts if they have their Include* flags set to true.
I have a feeling I am missing something...
  <!-- Used for a deployment that will NOT deploy assemblies to the BizTalk management database. 
        Only one server in a BizTalk group should actually deploy assemblies to the management database. -->
  <Target Name="DeployBizTalkMgmtDB_false" DependsOnTargets="$(DeployBizTalkMgmtDBfalseDependsOn)">
    <!-- Support server deployments that do not include BizTalk management database. -->
    <!-- Need to handle these differently than standard targets - just putting in gac... -->

    <Exec Command="&quot;$(Gacutil)&quot; /f /i &quot;@(SchemasQualified)&quot;" Condition="'$(IncludeSchemas)' == 'true' and '%(Identity)' == '%(Identity)'" />

    <Exec Command="&quot;$(Gacutil)&quot; /f /i &quot;@(PipelinesQualified)&quot;" Condition="'$(IncludePipelines)' == 'true' and '%(Identity)' == '%(Identity)'" />

    <Exec Command="&quot;$(Gacutil)&quot; /f /i &quot;@(TransformsQualified)&quot;" Condition="'$(IncludeTransforms)' == 'true' and '%(Identity)' == '%(Identity)'" />

    <Exec Command="&quot;$(Gacutil)&quot; /f /i &quot;@(OrchestrationsQualified)&quot;" Condition="'$(IncludeOrchestrations)' == 'true' and '%(Identity)' == '%(Identity)'" />
  </Target>
Oct 8, 2015 at 3:10 AM
Hello again,

All DLLs are built for .NET 4.0
We normally use a custom deployment script triggered by Octopus Deploy.
I tried doing it manually as you suggested using the Wizard UI for the deployment and got the same result.

Here is the log file for the Wizard UI based deployment. I can't see where it GACs the schemas/maps/orchestrations.

I can offer the log files for when the deployment is triggered from Octopus for comparison too?

Here is the log file for when the DeployBizTalkMgmtDB set to false.
((the command to trigger the deployment is right at the top)

Here is the log file for when DeployBizTalkMgmtDB is set to true. This one works and we can see where it GACs the artefact DLLs.
((the command to trigger the deployment is right at the top)

I am missing something? Just not sure what.
Oct 8, 2015 at 3:32 AM
I think I have found it. We are doing stuff in the CustomPostDeployTarget section, and it looks like the GACing of BizTalk Artefacts when DeployBizTalkMgmtDB is false occurs after that!

Sample log of a different app that didn't have any fancy stuff in CustomPostDeployTarget:
<snip>
CustomPostDeployTarget:
  Running SQL scripts for TESTESB.Channel.GLProcessor...
  sqlcmd.exe -S PEMPCRESBDB4001\BZTDBINST -d BAMPrimaryImport -E -i "..\SolutionItems\SQL\Create_TESTEsbGLProcessorBamViews.sql"
  Changed database context to 'BAMPrimaryImport'.
  Msg 208, Level 16, State 1, Server PEMPCRESBDB4001\BZTDBINST, Procedure TEST_GLProcessor_InsurancePolicyTransactions_AllInstances, Line 19
  Invalid object name 'dbo.bam_Channel_GLProcessor_InsurancePolicyTransactions_AllInstances'.
  Creating the Event Log Source for TESTESB.Channel.GLProcessor...
  %SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -ExecutionPolicy Unrestricted -command "..\CreateEventLogSource_v1.0.ps1 TESTESB TESTESB.Channel.GLProcessor"
DeployBizTalkMgmtDB_false:
  "C:\Program Files (x86)\TESTESB.Channel.GLProcessor for BizTalk\100.0\Deployment\Framework\DeployTools\gacutil.exe" /f /i "..\TESTESB.Channel.GLProcessor.Schemas.dll"
  Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.1
  Copyright (c) Microsoft Corporation.  All rights reserved.
  
  Assembly successfully added to the cache
  "C:\Program Files (x86)\TESTESB.Channel.GLProcessor for BizTalk\100.0\Deployment\Framework\DeployTools\gacutil.exe" /f /i "..\TESTESB.Channel.GLProcessor.Pipelines.dll"
  Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.1
  Copyright (c) Microsoft Corporation.  All rights reserved.

<snip>  
My question now is: is there a target we can use for our post tasks that would occur after DeployBizTalkMgmtDB_false ? :)
Coordinator
Oct 8, 2015 at 3:52 AM
You are right -- on all but the last server the targets run in the wrong order... and it has been that way for many, many years. I can fix it for v5.6.

That said, you're running a SQL script in CustomPostDeployTarget that should probably only run once for the entire deployment -- on the last server when '$(DeployBizTalkMgmtDB)' == 'true'. You can make that conditional.

Thanks,
Tom
Coordinator
Oct 8, 2015 at 3:54 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Oct 8, 2015 at 4:08 AM
Yes we will add that condition for the SQL scripts. Thanks for that :)

Is there any work around you could suggest in the meantime?
Hmmm... Maybe add the exec statements from DeployBizTalkMgmtDB_false to the start of our CustomPostDeployTarget on the condition that DeployBizTalkMgmtDB is false?
<Exec Command="&quot;$(Gacutil)&quot; /f /i &quot;@(SchemasQualified)&quot;" Condition="'$(IncludeSchemas)' == 'true' and '%(Identity)' == '%(Identity)'" />
<Exec Command="&quot;$(Gacutil)&quot; /f /i &quot;@(PipelinesQualified)&quot;" Condition="'$(IncludePipelines)' == 'true' and '%(Identity)' == '%(Identity)'" />
<Exec Command="&quot;$(Gacutil)&quot; /f /i &quot;@(TransformsQualified)&quot;" Condition="'$(IncludeTransforms)' == 'true' and '%(Identity)' == '%(Identity)'" />
<Exec Command="&quot;$(Gacutil)&quot; /f /i &quot;@(OrchestrationsQualified)&quot;" Condition="'$(IncludeOrchestrations)' == 'true' and '%(Identity)' == '%(Identity)'" />
Coordinator
Oct 8, 2015 at 5:48 AM
That's not a bad workaround, because there's no harm in having gacutil run twice on the same DLL's. I'd go ahead with your suggestion until v5.6.

Thanks,
Tom