Working with BizTalk and Octopus Deploy!!!

In this post, I will demonstrate BizTalk solution deployment using BTDF and OctopusDeploy. Octopus Deploy is a friendly deployment automation system mainly for .NET developers. This post mainly describe BizTalk solution deployment using Octopus deploy.

Some of the pre-requisites are:

  • Octopus Tentacles been installed and configure on the BT server. A “bizTalk-app” (it can be any name) role is created.
  • Octopus Tentacles service running under BT Service account.
  • Environments (BT Server configuration) is created and completed on the Octopus server using Octopus portal. The “green tick” confirm that octopus server can communicate with the BT Machine.

image

  • In BTDF project Environment Settings file template, create a column named “Export_OctopusSettings.xml” before generating MSI as per below.

image

  • Generate MSI using TFS Build. Normally the build server create incremented folders for the generated BTDF MSI. We need to copy the MSI from the drop TFS folder to the local folder on machine. To copying the MSI from the drop TFS folder to the local folder, I created the PS script following the below “Create Step Templates” step below. This script get the latest folder from the drop location and copy the MSI file to the local folder.

$TFSDropDir = $OctopusParameters[“TFSRootDir”]
$TargetFolder = $OctopusParameters[“DestinationFolder”]

if ([string]::IsNullOrEmpty($TFSDropDir)) {
Write-Host “No TFSDropDir has been specified”
Exit
}

if ([string]::IsNullOrEmpty($TargetFolder)) {
Write-Host “No TargetFolder has been specified”
Exit
}
if ( (Test-Path $TargetFolder) -eq $false) {
Write-Host “The target directory doesn’t exist. Unable to copy!”
Exit
}

if ( (Test-Path $TFSDropDir) -eq $false) {
Write-Host “The TFS Drop directory doesn’t exist. Unable to copy!”
Exit
}

$TFSCurrentBuildDir = Get-ChildItem -Path $TFSDropDir -name | Sort-Object LastAccessTime -Descending | Select-Object -First 1
$DeployMSICompletePath= “$TFSDropDir\” + “$TFSCurrentBuildDir\”
Write-Host  “MSI Full path: $DeployMSICompletePath”
# Copy the items!
Write-Host “Copying items from $DeployMSICompletePath to $TargetFolder … please wait.”
robocopy $DeployMSICompletePath $TargetFolder

#Robocopy can success with multiple codes!
$exitcode = $LastExitCode

if($exitcode -in 0,1,2,3,4,5,6,7){
$LastExitCode = 0
}

return $LastExitCode

  • “Run – Windows Installer” and “Variable – Substitute in files step” templates should be created in octopus (to create/import templates see below). You can download these templates from octopus library https://library.octopusdeploy.com/#!/listing

Steps to follow on Octopus Server.

  1. Create Step Templates for BTDF Deployment using the below script. You just need to Import the script using the Import button on the Step templates page. Copy the below script in the below window.

image

For Template please contact Shadab.Anwer@SharpTalkTech.com

The above Json template will generate the below PS script.

For PS script please contact Shadab.Anwer@SharpTalkTech.com

2. Save the templates and go to the Parameters tab on the same screen. All parameters can be viewed as per the below screen.

image

3. Navigate to created Project “Test”. Click “Process”, click “add Step”. Chose “Run – Windows Installer” from the step type.

image

4. Select target roles “(this is the role created during configuration of octopus tentacles”).  MSI File Path “C:\Octopus\Test.MSI”. Click Save. If you using nuget package (.nuspec) step to extract MSI on Octopus tentacles folder, you can use the below to run the MSI.

#{Octopus.Action[Deploy Package].Output.Package.InstallationDirectoryPath}\#{Octopus.Project.Name}-#{Octopus.Release.Number}.msi

5. Click “Add Step” to replace variables in the setting file using Octopus variables (mentioned below). Chose “Variables – Substitute in Files” from the step type. Parameter template files should be “C:\Program Files (x86)\Test for BizTalk\1.0\Deployment\EnvironmentSettings\SettingsFileGenerator.xml”. Click Save.

image

6. Click “Add Step” to create BTDF deployment. Chose “Deploy – BizTalk Application” from the step type. Below is the configuration details.

image

Install Directory – #{Octopus.Action[Run – Windows Installer].Output.InstallDirectory}

Package Install – #{Octopus.Action[Deploy Package].Output.Package.InstallationDirectoryPath}

Process page should look like the below.

image

7. Navigate to Variables. Create Variables as mentioned in the below screen. These variables can be distinguished on basis of scope. You can create many variables with the same name for different scope (or environment like TEST, QA, Prod etc).

image

8. Next step is to create Release.  Goto Release, click create release and save. Deploy this release to the specific server and can later promote this release to other servers.

image

9. Click on Task Log – there is all the information including the logging of the deployment steps. The BTDF deployment logging is also in there.

image

BizTalk Continuation Integration Build and Deployment can be fully automated using Teamcity and Octopus, you need to install octopack to do so. At the moment, I am working with automating CI with TFS and Octopus. If someone has already done this, would love to hear from them.

Thanks,

Shadab Anwer

Advertisements

2 thoughts on “Working with BizTalk and Octopus Deploy!!!

    • Hi Venkata, Here it is.

      {
      “Id”: “ActionTemplates-193”,
      “Name”: “Variables – Substitute in Files”,
      “Description”: “Transforms files using the Octopus `#{Variable}` substitution syntax.”,
      “ActionType”: “Octopus.Script”,
      “Version”: 1,
      “Properties”: {
      “Octopus.Action.Script.ScriptBody”: “Add-Type -Path ($OctopusParameters[‘Octopus.Tentacle.Agent.ProgramDirectoryPath’] + \”\\Octopus.Platform.dll\”)\n\nfunction Execute-Template($templateFile, $outputFile)\n{\n Write-Output \”Loading template file $templateFile…\”\n \n $contents = [System.IO.File]::ReadAllText($templateFile)\n \n $template = $null\n $parseErr = $null\n \n if (-not [Octopus.Platform.Variables.Templates.Parser.TemplateParser]::TryParseTemplate($contents, [ref] $template, [ref] $parseErr))\n {\n throw \”The file contents could not be parsed as a valid Octopus template: $parseErr\”\n }\n \n Write-Output \”Binding variables…\”\n \n $binding = [Octopus.Platform.Variables.Templates.Binder.PropertyListBinder]::CreateFrom($OctopusParameters)\n \n $newContents = New-Object System.Text.StringBuilder\n $writer = New-Object System.IO.StringWriter $newContents\n \n Write-Output \”Evaluating template…\”\n \n [Octopus.Platform.Variables.Templates.Evaluator.TemplateEvaluator]::Evaluate($template, $binding, $writer)\n \n $writer.Dispose()\n \n Write-Output \”Writing result to $outputFile…\”\n \n [System.IO.File]::WriteAllText($outputFile, $newContents.ToString())\n}\n\n\n$SubsTemplatePathGlobs.Split(\”;\”) | foreach {\n $glob = $_.Trim()\n Write-Output \”Searching for files that match $glob…\”\n\n $matches = $null\n $splits = $glob.Split(@(‘/**/’), [System.StringSplitOptions]::RemoveEmptyEntries)\n if ($splits.Length -eq 1) {\n $splits = $glob.Split(@(‘\\**\\’), [System.StringSplitOptions]::RemoveEmptyEntries)\n }\n \n if ($splits.Length -eq 1) {\n $matches = ls $glob\n } else {\n if ($splits.Length -eq 2) {\n pushd $splits[0]\n $matches = ls $splits[1] -Recurse\n popd\n } else {\n $splits\n throw \”The segment ‘**’ can only appear once, as a directory name, in the glob expression\”\n }\n }\n\n $matches | foreach {\n $tpl = $_.FullName\n $dest = $tpl\n if (-not [string]::IsNullOrWhiteSpace($SubsTrimSuffix)) {\n $lx = $tpl.LastIndexOf($SubsTrimSuffix)\n if ($lx -eq -1) {\n Write-Output \”File $tpl does not end with the $SubsTrimSuffix suffix, so will be overwritten\”\n } else {\n $dest = $tpl.Substring(0,$lx)\n }\n }\n Execute-Template -templateFile $tpl -outputFile $dest\n }\n}\n\n\nWrite-Output \”Done.\”\n”
      },
      “SensitiveProperties”: {},
      “Parameters”: [
      {
      “Name”: “SubsTemplatePathGlobs”,
      “Label”: “Template files”,
      “HelpText”: “A semicolon-separated list of path expressions that match the template files to be processed.\n\nSimple globbing is supported, for example `C:\\Files\\**\\*.tmpl` will match files in `C:\\Files` and any subdirectory.”,
      “DefaultValue”: null,
      “DisplaySettings”: {}
      },
      {
      “Name”: “SubsTrimSuffix”,
      “Label”: “Trim filename suffix”,
      “HelpText”: “If specified, the results of evaluating the templates will be written to new files by trimming the specified suffix from the end of the filename. For example, specifying `.tmpl` will cause the file `Settings.ini.tmpl` to be transformed into `Settings.ini`.\n\nIf omitted, the files will be transformed in-place.”,
      “DefaultValue”: null,
      “DisplaySettings”: {}
      }
      ],
      “LastModifiedOn”: “2014-11-14T03:16:47.813+00:00”,
      “LastModifiedBy”: “Kevin.Mee@insuranceline.local”,
      “$Meta”: {
      “ExportedAt”: “2015-09-30T23:27:06.926Z”,
      “OctopusVersion”: “2.6.5.1010”,
      “Type”: “ActionTemplate”
      }
      }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s