Using Common SettingsFileGenerator File With BizTalk Deployment Framework

One of the great features of the BizTalk Deployment Framework is the ability to use a SettingsFileGenerator file to set your environment specific settings in an excel file, and use this in your other files, so you can have generic files like portbindings and BRE rules, being updated with the correct settings for the environment we’re working on, like DEV, TEST or PROD. If you are like me, you will probably also have placed a lot of common settings which are used accross all your applications in this file, like SSO user groups, host instance names, common endpoints, webservice users, etc. This means we end up with a lot of duplicate settings accross our environment settings files, which becomes cumbersome to maintain. Fortunatly, there is a way to work around this.

Common SettingsFileGenerator

The BTDF has a nice option which we can use, to have a single SettingsFileGenerator file for all our applications. In this example we have two applications, with a couple of common settings, as well as some application specific settings. The applications were already set up with BTDF, so we already have all necessary placeholders in the PortBindingsMaster file. Lets start by creating a CommonSettingsFileGenerator file which has all these settings in one place. To do this, copy the SettingsFileGenerator from one of my projects to a general Tools directory, rename it, and update it with all the common and application specific settings.

Common SettingsFileGenerator
Continue reading

Automated Build and Deployment With BizTalk Deployment Framework

A while ago I created a post on using the BizTalk Deployment Framework for automated build and deployment. Since then I have worked this out to be more easy and maintainable using PowerShell, which I will show in this post. BizTalk Deployment Framework is one of those pearls for BizTalk developers, allowing complex BizTalk solutions to be deployed easily, having all our artifacts and dependencies together in one MSI. The code with this post can be downloaded from here.

Description

Using PowerShell we will make scripts which will handle all steps of the build and deployment process for us. This will make sure our applications are always deployed in the correct order, using the right versions, and with minimal effort. We have some general helper functions, which will help us clear log files, wait for user input, iterate through directories, etc. We assume you have are using some of the BTDF best practices for these scripts, where it comes to naming conventions and folder structure. Of course, in case anything differs in your environment, you can easily adjust the scripts to meet your requirements.

Continue reading

Using BTDF to create alternative ports for different environments

As you may know, the BizTalk Deployment Framework can help you use different settings for different environments. However, you can also easily use it to have completely different ports in different environments. So for example, if you have use a webservice in your test and production environment, but want to use file locations in your development environment, this can be easily done.
Start by making sure you have the following lines in your .btdfproj file inside of the first PropertyGroup:

<RequireXmlPreprocessDirectives>true</RequireXmlPreprocessDirectives>
<FilesToXmlPreprocess>Portbindings.xml</FilesToXmlPreprocess>

Next, in your SettingsFileGenerator.xml, add a property Environment, and set it’s values for your various environments, as following:
EnvironmentSettings
Here we have a default setting, Development, and separate settings for Test and Production.
Now switch to your PortBindingsMaster.xml, and add the various ports and receive locations you want for your different environments. Enclose the ports as following:

<!-- #if GetProperty("Environment")=="DEV" -->
<SendPort Name="Work on user" IsStatic="true" IsTwoWay="true" BindingOption="0">
.
. 
<SendHandler Name="${SendHost}" HostTrusted="false">
<TransportType Name="FILE" Capabilities="11" ConfigurationClsid="5e49e3a6-b4fc-4077-b44c-22f34a242fdb" />
</SendHandler>
.
.
<!-- #endif -->
<!-- #if GetProperty("Environment")=="TEST" -->
<SendPort Name="Work on user" IsStatic="true" IsTwoWay="true" BindingOption="0">
.
. 
<SendHandler Name="${SendHost}" HostTrusted="false">
<TransportType Name="WCF-BasicHttp" Capabilities="899" ConfigurationClsid="467c1a52-373f-4f09-9008-27af6b985f14" />
</SendHandler>
.
.
<!-- #endif -->

One thing to note, since we have defined RequireXmlPreprocessDirectives, is that we need to enclose all other placeholders as well, for example as following:

<!-- #ifdef _xml_preprocess -->
<Tracking>${TrackingSendPort}</Tracking>
<!-- #endif -->

Excute custom commands using the BizTalk Deployment Framework

As I previously wrote, we are using BizTalk Deployment Framework to deploy webservices for our BizTalk applications.
Now I wanted to make sure that the application pool on which these webservices are running is set up correctly, even though we don’t manage these ourselves.
Since the BTDF is built using MSBuild, we can use MSBuild command to execute custom applications and commands, and I decided to use this functionality for my purposes.
Here is the code I use for this, place this after the last ItemGroup in your .btdfproj file.
This particular piece of code sets the runtime version and pipeline mode of our application pool, but you can pretty much use this with any command.

<!-- Set AppPool .NET version -->
<Target Name="CustomPostDeployTarget">
    <Exec Command="&quot;C:\Windows\System32\inetsrv\appcmd.exe&quot; set APPPOOL /apppool.name:&quot;BizTalkBasicHttp&quot; /managedRuntimeVersion:v4.0 /managedPipelineMode:Integrated" />
</Target>

Create webservice in non default website using BTDF

For our current customer, we have both WCF and SOAP webservices we want to expose, however IIS does not allow these 2 different types to live under the same website.
Therefore, I would have to create one of the webservices in a non-default website.
I wanted to use the BizTalk Deployment Framework for this, to make deployment easy, and to make sure the webservices would always be deployed to the correct website.
After some research, I found out this can be done by adding the following line to the first property group in your .btdfproj file:

<IISMetabasePath>IIS://localhost/w3svc/2/Root</IISMetabasePath>

Here you only have to change the 2 to the ID of the website under which you want the webservice to run, which can be found by opening the advanced properties of the website in IIS Manager.

IIS website advanced properties

Passwords in exported binding files

Today I ran into a small problem with my PortBindingsMaster file.
We use the BizTalk Deployment Framework to deploy our applications.
On one of our WCF-HTTP ports we want to set the password from the SettingsFileGenerator.
I exported the PortBindings from the BizTalk administration console, prepared this for the BTDF, created a placeholder for the password, and set the password in the SettingsFileGenerator file.
However, after deploying the application, the password was not set on the port.
After some research, I found out that the PortBindingsMaster had this for the password:

<Password vt="1">Pass@word1</Password>

The cause was the following, which means the password is hidden:

vt="1"

To solve this, we have to tell the PortBindingsMaster file that this is a plain-text password, by changing it into this:

vt="8"

Deploy webservice using BizTalk Deployment Framework

In one of my projects we expose schema’s as a WCF webservice. I wanted to use the BizTalk Deployment Framework to deploy the webservice along with all the other artifacts. Start by deploying the webservice using the BizTalk WCF Service Deployment Wizard. Once finished, copy the folder for the webservice from C:\inetpub\wwwroot to your project folder. After you have added the files to your project, make sure the build action on the XSD’s is set to None instead of BtsBuild, as the references in these schemas probably can’t be resolved on build. Now you have to make a couple changes in your BTDF project file. To start with, you will have to tell that you want to deploy virtual directories, change the following property to do so:

<IncludeVirtualDirectories>true</IncludeVirtualDirectories>

After the virtual directories have been created IIS has to be restarted. Luckily, this can also be done using BTDF, by setting the SkipIISReset property.

<SkipIISReset>false</SkipIISReset>

Next you will have to specify the settings of the webservice. For this create a new ItemGroup, which should be placed under the PropertyGroup with the ProductID.

<ItemGroup>
  <VDirList Include="*">
    <Vdir>NameOfWebService</Vdir>
    <AppPool>NameOfAppPoolToRunServiceUnder</AppPool>
    <Physdir>..\NameOfWebserviceFolderYouCopiedEarlier</PhysDir>
  </VDirList>
</ItemGroup>

You will also have to specify the user credentials the AppPool will run under. I used the SettingsFileGenerator.xml file for this. Add VDIR_UserName and VDIR_UserPass to this document, and set them for your environments. Now go back to the BTDF project file, and add the following under the ItemGroup you just created.

<ItemGroup>
  <PropsFromEnvSettings Include="VDIR_UserName;VDIR_UserPass" />
</ItemGroup>

Standard, the AppPool will be running .NET2, however we want it running .NET4. In the final release of BTDF v5 there will be a new attribute on the VDirList for this, but for now we have to use a CustomPostDeployTarget.

<Target Name="CustomPostDeployTarget">
  <Exec Command="&quot;C:\Windows\System32\inetsrv\appcmd.exe&quot; set APPPOOL /apppool.name:&quot;NameOfAppPoolToRunServiceUnder&quot; /managedRuntimeVersion:v4.0 /managedPipelineMode:Integrated" />
</Target>

Now when you use the BTDF to deploy your application, it will automatically set up an AppPool and create the WCF webservice for you.

Add additional assemblies to the GAC using BTDF

Using the BizTalk Deployment Framework it is very easy to add additional assemblies to the GAC along with the rest of your application. Just add the following code to the BTDF project file:

<ItemGroup>
    <ExternalAssemblies Include="Assembly1.dll">
        <LocationPath>..PathToAssembly</LocationPath>
    </ExternalAssemblies>
    <ExternalAssemblies Include="OtherAssembly.dll">
        <LocationPath>C:SharedAssemblies</LocationPath>
    </ExternalAssemblies>
</ItemGroup>

One thing to note, is the position where this piece of code should be placed. The BTDF project file should be organized as this:
<PropertyGroup>’s
<ItemGroup>’s
<Import Project=”$(DeploymentFrameworkTargetsPath)BizTalkDeploymentFramework.targets” />

Automated BizTalk Deployment

This post is deprecated, check this new post for improved scripts.

Introduction

At one of our customers, I set up a BizTalk environment with several applications, like applications for warehouse, subsidiary and customer interfaces. Some of these applications also use 2 separate servers, one in the internal network, and one in the DMZ network. These servers have completely different ports; for example. the DMZ server has ports connected to the outside world, which aren’t present on the internal server. Also, some applications are dependent on others, so deploying and undeploying has to be done in a specific order. To make this easy, I have set up a fully automatic BizTalk build and deployment setup. This is done by using PowerShell in combination with the BizTalk Deployment Framework. For my own reference, as well as for helping others set up an automated BizTalk deployment, I wrote this document. A basic understanding of BizTalk and PowerShell is needed to work with these examples. Special thanks go out to the blog of Randy Paulo.
Continue reading