Brian Loesgen's Blog

BizTalk, Enterprise Service Bus (ESB), SOA, Oslo, San Diego .NET User Group, San Diego Software Industry Council Web Services... and stuff!

  Home  |   Contact  |   Syndication    |   Login
  105 Posts | 0 Stories | 77 Comments | 84 Trackbacks

News

Tag Cloud


Archives

Post Categories

Image Galleries

My Blog Friends

Consultants (like me) tend to exist in very different worlds than enterprise architects and developers. We get exposure across a broad range of companies, flitting from site to site, solving problems, spewing wisdom, and moving on. That’s a great position to be in as you get to see a lot of different business problems and solutions. That’s also sometimes a not-so-good position as you see people struggling, often with the same problems, and coming up with solutions that can vary wildly in both approach and effectiveness.

In BizTalk-land, nowhere is this as evident as around deployment. Why, I don’t know, but many people seem to struggle with it. Developers will focus on making the solution work, and then suddenly realize they need to deploy, and wonder how they will go about doing that. This made more complex as BizTalk solutions can, and often do, span a wide range of technologies.

The BizTalk product team has come up with a great deployment story. This has not always been the case, but it certainly is now. We have all the bits and pieces we need to be able to implement highly-repeatable deployment packages. However, many developers seem to either not realize that, or they’re not in a position (due to budgets and tight deadlines) to take the time to “do it right”.

I would argue that not taking the time to implement a 100% repeatable build process is something that you CAN’T AFFORD to skip. The ultimate cumulative costs, in ghost-chasing troubleshooting, production outages, and lost productivity can far outweigh the up-front costs of implementing a highly-repeatable, reliable and effective build process. In some shops it may be OK to hand an IT pro a deployment script that has 15 manual steps, however, I’d rather not rely on a human to ensure that every step happens in the prescribed sequence. What if you miss step 12?

I know a lot of others (such as Scott Colestock) have done great focused work in the area of deployments. I embarked on this path somewhat by accident. I was on a client project where we were migrating MSIs, BizTalk’s preferred unit of deployment, between environments. I was doing this by exporting an MSI from the admin tool. One day, I forgot to update a binding file (a resource included with the MSI), and proceeded to chase ghosts for a little while when my import was nattering about ports I knew no longer existed. Frustrated, I promised myself this would never happen to me again, and I wrote a little batch file that would automatically update the binding resources for me, I wouldn’t have to remember, I’d just run an “UpdateBizTalkResources.cmd” script, and magic would happen.

That’s how it began, and it just kind of grew organically from there. This blog post is not about how it ends, but I want to share where I am at now. Ever project adds to this, and it has been an iterative process spanning several projects over the past couple of years.

So where am I at? At a client site last year I was able to take a somewhat simple application, and generate an MSI that reduces the deployment time of that robotics-control BizTalk solution to just a few minutes. Everything is scripted, everything is repeatable. At another client site last year, I took a solution that spans perhaps 20 BizTalk projects, and reduced creation of the MSIs (including compilation, etc) to running a series of scripts. Elapsed time to re-gen the 8 MSIs is under 15 minutes, deployment to a green-field pristine BizTalk environment, also under 15 minutes, for all 8 MSIs (which generate 5 separate BizTalk applications). The IT guys on that particular project loved me, as I took their deployments from being a two day "hope this works" process to a 15 minute highly-repeatable process with only a handful of steps.

To those fortunate few among you that have the luxury of being able to spend the time to implement highly-repeatable, highly-scripted, as-touch-free-as-possible build processes, this may seem pretty routine. However, a lot of BizTalk shops don’t have this degree of process implemented.

For the rest of you, I am posting my current script (with some client info removed, removed items are marked by "[" and "]"). Most of it should be self-explanatory, but at a high level, it:

  • Creates a log file. All steps that occur, and their results, are recorded in the log
  • Compiles the SLN file by calling DEVENV
  • Removes the existing BizTalk app and uninstalls it (if it exists) to ensure a clean “not tweaked by a developer” build
  • Creates a BizTalk application
  • Adds the resources (including binding files for each environment)
  • Exports an MSI

In some cases, you’ll need to do more when the application installs, which you can handle with pore and post-processing scripts. For example, in one case, I needed to move DLLs created by the SAP adapter into a specific folder. Just to make it challenging, the target folder changed with environments. Fortunately, I could detect the environment by querying an environment variable, and move the file accordingly. All of that was transparent to the IT Pro who just ran the MSI. In another case, all solution DLLs needed to be put into specific folder locations. In yet another case, while working on the ESB Guidance, Marty, Tom and I wrote scripts that automatically did everything from creating user accounts and app pools through to creating virtual roots and assigning app pools. Post-processing scripts are a powerful tool, you can do a LOT there.

In practice, I develop this script in my development VM. When the time comes to deploy to the integration environment (pre-QA/UAT), I am actually doing my first pass at testing the build/deploy process. Usually, the REAL MSI is created when the script is run on a "build server". That MSI moves into QA. If everything succeeds and is accepted in QA, then that same MSI (don't re-generate!) moves into production.

I hope you’ll find the techniques used below help improve the quality and repeatability of your builds, and help to simplify your build and deployment process. As always, I'd welcome any comments/thoughts you all may have on how this can be further improved.

---------------------------

 

@echo off

mode con cols=100 lines=120

CLS

SETLOCAL

SET APP_NAME=[name]

SET BIZTALK_APP_NAME=[app name]

SET BinPath=source code\bin

SET  BasePath=[path]\Source Code

SET LOG_LOCATION=%CD%\LogFile.txt

REM Uncomment the following line to echo everything out to the screen

REM set LOG_LOCATION=con

SET Database="BizTalkMgmtDb"

SET Server="."

echo ##################################################################################### >> %LOG_LOCATION%

echo %DATE% %TIME% Running %APP_NAME% build script >> %LOG_LOCATION%

echo ##################################################################################### >> %LOG_LOCATION%

echo Setting up...

echo ############# >> %LOG_LOCATION%

echo Setting up... >> %LOG_LOCATION%

echo ############# >> %LOG_LOCATION%

CALL vsvars32.bat

echo Building....

echo ############# >> %LOG_LOCATION%

echo Building .... >> %LOG_LOCATION%

echo ############# >> %LOG_LOCATION%

cd %BasePath%

echo. >> %LOG_LOCATION%

echo ********************************************************************************************** >> %LOG_LOCATION%

echo *** Working in directory: %CD% *** >> %LOG_LOCATION%

echo ********************************************************************************************** >> %LOG_LOCATION%

echo. >> %LOG_LOCATION%

DEVENV ..\..\%APP_NAME%.BizTalk.sln /build Deployment >> %LOG_LOCATION%

IF %ERRORLEVEL% NEQ 0 (

SET msg=Could not build Visual Studio solution

GOTO ErrorRoutine)

 

rem To ensure we have a clean environment free of any legacy or manually added resources, try to remove and uninstall the app

echo Cleaning environment....

echo ######################## >> %LOG_LOCATION%

echo Cleaning environment.... >> %LOG_LOCATION%

echo ######################## >> %LOG_LOCATION%

BTSTask UninstallApp -ApplicationName:%BIZTALK_APP_NAME% >> %LOG_LOCATION%

BTSTask RemoveApp -ApplicationName:%BIZTALK_APP_NAME% >> %LOG_LOCATION%

BTSTask AddApp -ApplicationName:%BIZTALK_APP_NAME% >> %LOG_LOCATION%

IF %ERRORLEVEL% NEQ 0 (

echo ####################################################################### >> %LOG_LOCATION%

echo #### Warning: BizTalk application %BIZTALK_APP_NAME% already existed. >> %LOG_LOCATION%

echo #### Application is being 1-uninstalled and 2-removed >> %LOG_LOCATION%

echo ####################################################################### >> %LOG_LOCATION%

)

 

echo *** Adding assemblies generated by SAP adapter to %APP_NAME% resources. The post-processing script will move it to the right folder (destination varies by environment)
BTSTask AddResource /ApplicationName:%BIZTALK_APP_NAME% /Type:System.BizTalk:BizTalkAssembly /Source:"C:\Program Files\Microsoft BizTalk Adapter v2.0 for mySAP Business Suite\Bin\Z_MATERIAL_SPECS.dll" /Destination:"%%BTAD_InstallDir%%\Z_MATERIAL_SPECS.dll" /Server:%Server% /Database:%Database% /Overwrite >> %LOG_LOCATION%

IF %ERRORLEVEL% NEQ 0 (

SET msg=Could not add SAP DLL to BizTalk application

GOTO ErrorRoutine)

 

echo Adding binding files...

echo ####################### >> %LOG_LOCATION%

echo Adding binding files... >> %LOG_LOCATION%

echo ####################### >> %LOG_LOCATION%

BTSTask AddResource /ApplicationName:"%BIZTALK_APP_NAME%" /Type:System.BizTalk:BizTalkBinding /Server:%Server% /Database:%Database% /Overwrite /Source:"..\..\build\Bindings\%BIZTALK_APP_NAME%_Bindings_DEV.xml" /Property:TargetEnvironment="Development" >> %LOG_LOCATION%

IF %ERRORLEVEL% NEQ 0 (

echo #################################################################### >> %LOG_LOCATION%

echo #### Warning: could not find DEV binding file >> %LOG_LOCATION%

echo #################################################################### >> %LOG_LOCATION%

)

BTSTask AddResource /ApplicationName:"%BIZTALK_APP_NAME%" /Type:System.BizTalk:BizTalkBinding /Server:%Server% /Database:%Database% /Overwrite /Source:"..\..\build\Bindings\%BIZTALK_APP_NAME%_Bindings_QA.xml" /Property:TargetEnvironment="Q.A." >> %LOG_LOCATION%

IF %ERRORLEVEL% NEQ 0 (

echo #################################################################### >> %LOG_LOCATION%

echo #### Warning: could not find QA binding file >> %LOG_LOCATION%

echo #################################################################### >> %LOG_LOCATION%

)

BTSTask AddResource /ApplicationName:"%BIZTALK_APP_NAME%" /Type:System.BizTalk:BizTalkBinding /Server:%Server% /Database:%Database% /Overwrite /Source:"..\..\build\Bindings\%BIZTALK_APP_NAME%_Bindings_PRD.xml" /Property:TargetEnvironment="Production" >> %LOG_LOCATION%

IF %ERRORLEVEL% NEQ 0 (

echo #################################################################### >> %LOG_LOCATION%

echo #### Warning: could not find PRD binding file >> %LOG_LOCATION%

echo #################################################################### >> %LOG_LOCATION%

)

echo Creating MSI...

echo ############### >> %LOG_LOCATION%

echo Creating MSI... >> %LOG_LOCATION%

echo ############### >> %LOG_LOCATION%

BTSTask ExportApp -ApplicationName:%BIZTALK_APP_NAME% -Package:..\..\build\%BIZTALK_APP_NAME%.msi >> %LOG_LOCATION%

IF %ERRORLEVEL% NEQ 0 (

SET msg=Could not export MSI

GOTO ErrorRoutine)

GOTO :End

:ErrorRoutine

echo #################################################################### >> %LOG_LOCATION%

echo #################################################################### >> %LOG_LOCATION%

echo Error: %msg% >> %LOG_LOCATION%

echo #################################################################### >> %LOG_LOCATION%

echo #################################################################### >> %LOG_LOCATION%

GOTO :End

:End

echo. >> %LOG_LOCATION%

echo. >> %LOG_LOCATION%

echo ##################################################################################### >> %LOG_LOCATION%

echo --> Completed: %DATE% %TIME% Running %APP_NAME% build script >> %LOG_LOCATION%

echo ##################################################################################### >> %LOG_LOCATION%

Technorati Tags:
posted on Monday, January 28, 2008 7:11 AM

Feedback

# re: Creating highly-repeatable builds and deployments 1/28/2008 8:33 PM Andreas Öhlund
Good post!

We are using the same tactics as you and it works great. We are using powershell-scripts -> It's amazing how easy everything to accomplish with powershell. So if you have the time I can really recommend porting your scripts to powershell. (Especially for using wmi-objects to start,stop, enlist orchestrations, ports and locations!)

# re: Creating highly-repeatable builds and deployments 1/29/2008 9:44 AM Mike
Hi Brian,

Nice post. I completely agree with your sentiment about how important it is. Sometimes it shocks me how many people dont do this sort of stuff and how many people just dont use things like BizUnit. I just dont know how they deliver projects, and they must waste so much of their clients money.

Anyway we do a similar thing to yourself, but our process is based around MsBuild. Ive done a few articles on my blog covering how we have integrated some of the community tools into our process which is now pretty good really.

The articles are as follows:

Integrating the Orchestration Profiler into your MsBuild Process
http://geekswithblogs.net/michaelstephenson/archive/2008/01/29/119064.aspx

Configuring binding files for BizTalk
http://geekswithblogs.net/michaelstephenson/archive/2008/01/27/118963.aspx

Generating the C# to call BizUnit Tests
http://geekswithblogs.net/michaelstephenson/archive/2008/01/19/118706.aspx

Integrating BizUnit and LoadGen
http://geekswithblogs.net/michaelstephenson/archive/2007/12/10/117558.aspx

Integrating BizTalk Documenter into your MsBuild Process
http://geekswithblogs.net/michaelstephenson/archive/2007/11/19/116960.aspx

Hope they help
Mike

# re: Creating highly-repeatable builds and deployments 1/29/2008 5:39 PM Brian Loesgen
Andreas:

Thanks, great point about starting orchestrations, ports, etc. all of which can be in the post-processing script. I feel a follow-up post comng on :)

Brian



# re: Creating highly-repeatable builds and deployments 1/29/2008 6:07 PM Brian Loesgen
Mike,

Unfortunately MsBuild is not always an option (depending on the client). There's a broad range of source control systems too. It'd be nice if we could all just pick one that did *everything* (and did it right).

Thanks for the links, I'm sure folks will find them helpful, and it's nice to see others that are passionate about this topic too!

Brian

# re: Creating highly-repeatable builds and deployments 1/30/2008 5:39 AM Andreas Öhlund
If you're interested in the powershell-syntax to manipulate orchestrations and ports I've just blogged about it:


http://andreasohlund.blogspot.com/2008/01/i-love-powershell.html

# re: Creating highly-repeatable builds and deployments 4/17/2008 3:45 PM chris
Nice job.. I'm doing something similiar with generated bat scripts. One thing I cannot figure out on deploy with BTSTask though is how do you programmatically add an application refrence to another deployed biztalk app?

Post Feedback

Title:
Name:
Email: (never displayed)
Url:
Comments: 
Please add 6 and 7 and type the answer here: