Posts mit dem Label Team Build werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Team Build werden angezeigt. Alle Posts anzeigen

Dienstag, 4. April 2017

Team Build with Remote Powershell Cross Domain

I ran into a series of issues when trying to establish a release pipeline in TFS where the build agent is located in the company domain whereas the target server is inside a DMZ-domain. I tried to run the "Run Powershell on Remote Machine" from the company domain build agent computer with a target machine located in the DMZ domain. I do not memorize all the errors I got in detail, but they were all around "WinRM, Could not process request, Kerboros, No authentication Server, Host not found".

Basically the problem comes down to open a remote powershell session. So if this succeeds when logged in to the company domain build agent computer and you connect to srv.mydmz.de being the target server in the dmz-domain:

Enter-PSSession 
    -ComputerName "srv.mydmz.de" 
    -Credential mydmz\username

then your build / release Task "Run Powershell on Remote Machine" should succeed as well. This is useful for testing purposes because you do not need to create a release definition upfront and create a release every time you try to get things up and running.

I found the steps to solve my problem in a blog post from Christopher Hunt, but I want to stress out on thing that I got wrong from many other blog posts providing the same solution.

The solution is rather simple. On the build agent computer and on the target DMZ computer run: 

WinRM Quickconfig 

Then, log in to the build agent computer and run this from an elevated command prompt:

Set-Item wsman:\localhost\Client\TrustedHosts -value "srv.mydmz.de" 

This adds the target server located in the DMZ as trusted host on the company domain joined build agent computer. Then the above command to open a remote powershell succeeded for me where it formerly failed. So a release definition like this should work then if the build agent computer is configured as stated above:

Release Definition executing a powershell across domains


So, call me dumb, but here is the thing I always got wrong until now: you have to add the DMZ-Server as trusted host on the company domain joined server, not the other way round.

To me it appeared more logical that the computer being called (the DMZ-server), i. e. where the remote powershell executes stuff, should trust the computer calling it (the company domain joined server). So I repeatedly tried the Set-Item-Command on the DMZ-Server setting the domain joined build agent computer as the trusted host.

Now that my incompetence in this case is revealed, maybe it might save others some time :-)

Donnerstag, 22. August 2013

Getting WebDeploy to work with Team Build with VS2012 & TFS2012

Lately I could finally make WebDeploy work from our Team build, deploying a WebSite that uses EF Code first as a database.

There is a lot of confusing stuff out there regarding this issue, and it took me some time to put all the pieces together to make it finally work.

That's why I am adding my own five Cents to it, as well as for having a reference if I ever have to do this again.

My Setup

Before going into detail on my solution, here is my Setup:
  • Two VS 2012 web-Solutions: one MVC WebApi Hosting a Service layer, and one vanilla ASP.NET Website using AngularJs for the Client. The former one was using an EF Code first model to store it's data and to run queries.
  • A Team build to be performed on an TFS 2012 Server, the build Agent running on the target web Server.
  • A web Server running IIS7 on a Windows Server 2012 machine

Install WebDeploy

The first step is to install WebDeploy on the target Server. On the web you find that using WebDeploy is different on IIS6 and IIS7 (Tory Hunts bolg entry was a good reference for that). IIS6 uses the "Web Deployment Agent Service" while IIS7 uses "Web Management Service".

It turned out, that with VS2012 you can use either way if you have IIS7 as in my case. I could not get the Web Management Service method to work, so I got along with Web Deployment Agent Service, which requieres a Admin-User to do the deployment. Due to the fact that the target Server was on our own Network, this was not a Problem for me.

The easiest way to install web deploy is using the Web Platform Installer. Under the Products-Tab search for web deploy and install "Web Deploy 3.5".



Installing Web Deploy using WebPI
The installer should configure the Firewall accordingly by adding a rule called "WdeployAgent" allowing incoming Connections on TCP Port 80. It also started the "Webbereitstellungs-Agent-Dienst" for me, which according to web sources you should not take for granted - so better double check.

Deploying a solution from Visual Studio

Next I tried to deploy a solution using Visual Studio. To do that, you need to create the target Website on the IIS of the target Server. I created a new Website that contains two applications: api and Client, one for the MVC WebApi Project and one for the Client.
IIS configuration on the target IIS
I started to deploy the Client Project, as it needed no database and so I thought it was easier to do. To publish a Project using VS2012 right-click the Project node and select "Publish". This fires up a Dialog that was different to all descriptions I found on the web, because they mostly referred to VS2010. On MSDN there is a nice Explanation of all the Settings that can be made.

You can create multiple publish profiles there. The most important Settings site is the "Connection"-Tab. The publish method of choice is "Web Deploy", which means you want to use either the Agent Service or the Management Serivce. Which one is acutally choosen depends on the Service Url you enter. According to MSDN, if you use http://machineName , the Agent Service is used. If your URL starts with https it should use the Management Service - but as I said, I could not get this one to work for me.
As Site/application I specified to use the IIS site and application that I have formerly created. The UserName / Password must be the built-in local Administrator account of the deployment machine (or a Domain admin account, which did not work for me). It is documented that a different user that has Administrator privileges will NOT work. If you tick the Save Password box, the Password will be saved encrypted in an local Settings file.
Visual Studio Deployment Settings
If you hit Validate Connection and everything is properly configured, you should get a green tickmark indicating that the Connection to the Agent Service can be established. Otherwise you get a more or less cryptic error message which are more or less well documented.
If you get the green tickmark, you can rush through the next steps of the wizzard without any further Action, or you just hit Publish. This Triggers a VS build and should publish your solution to the target server.

The Information you entered to the wizzard are being stored in your Project in the Properties Folder. There is a Sub Folder named PublishProfiles that contains a .pubxml File for each Profile. Alongside, but not shown in VS by Default, is a .pubxml.user file for each Profile, which contains the encrypted Password, in case you ticked the Save Password box. We Need to Change the .pubxml file later on, so it is good to know where it resides.

Integration with Team build

So far, this was quite easy and I was in a good mood to just integrate this with my Team build. To do this, you first Need to Setup a Team build for your solution. I skip that part here, as it is not the scope of this post. Given you have a Team build, you Need to tell it that it should deploy your solution(s). On the web you find the solution to add bunch of MSBuild-Parameters at the Process-Tab of the build Definition. This seemed to be messy to me, and you are totally lost if you want to publish more than one Project in one build.
I wanted to use the publish Profile I formerly created to be used by my Team build. That way I don't Need to maintain the Information more than once. After crawling the web for a while Scott Hanselmans blog post put me back on track: you can specify a PublishProfile Parameter for MSBuild to tell it to use the .pubxml-File. For being able to publish multiple Websites, you must not pass this as a Parameter to MSBuild using the build Definition, but you must incorporate the Switches in the .csproj file.
To do so, right click the Project and select "Unload Project" and then "Edit .csproj" from the context menu. Add the following snippet to the Project file:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DeployOnBuild>True</DeployOnBuild>
    <PublishProfile>pos.client.deploy.pubxml</PublishProfile>
  </PropertyGroup>

The condition ensures, that the Publishing only takes place for release builds. The DeployOnBuild Switch activates the deployment, and the PublishProfile Parameter Points to your publish Settings. So far you will Encounter a "USER_NOT_ADMIN" error from WebDeploy. This is due to the fact, that the .pubxml file does not contain the Password for the supplied Administrator user. This is stored in the .pubxml.user file, which is not added to source control. So in order to make things go right, you must manually edit the .pubxml-File and include the Password. My file Looks like this:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <CreatePackageOnPublish>True</CreatePackageOnPublish>
    <WebPublishMethod>MSDeploy</WebPublishMethod>
    <SiteUrlToLaunchAfterPublish />
    <MSDeployServiceURL>http://machineName</MSDeployServiceURL>
    <DeployIisAppPath>posDeploy/client</DeployIisAppPath>
    <RemoteSitePhysicalPath />
    <SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
    <MSDeployPublishMethod>RemoteAgent</MSDeployPublishMethod>
    <UserName>machineName\administrator</UserName>
    
    <Password>yourSecretPassword</Password>
    
    <PublishDatabaseSettings>
      <Objects xmlns="" />
    </PublishDatabaseSettings>
  </PropertyGroup>
</Project>

The CreatePackageOnPublish-Parameter yields to the creation of a WebDeploy package along with the deployment itself. It is located in the build drop Folder under _PublishedWebsites\YourProject_Package Folder and helps to Keep track of what was acutally published. Please notice the Password-Parameter, that mus contain the Password for the given built-in Administrator account for the deployment machine.

So far, so good...

Up to this Point, you should be able to Queue up your Team build and see your Website published to the target IIS Server.

In the next blog post, I will talk about how to get your EF code first database deployed during the Publishing process.



Montag, 4. Juni 2012

Incremental Builds with TFS

A very handy TFS feature is kind of well hidden in the settings. The setting is so "tiny" that I did not find it for a long time. But first things first.

The task: set up a team build that compiles only those assemblies that have been modified since the last build. You can call this an incremental build.

The whole magic is the "Clean Workspace" parameter in the build definitions process tab. Here one can choose how the build handles its workspace. You have three choices:

  1. All: Delete Sources & Binaries, then get all and build all. This is a complete rebuild. This is the default
  2. Outputs: Delete the binaries but keep the sources. Gets only the sources that have changed (incremental get). Recompiles all the sources so you get a full set of binaries.
  3. None: Delete nothing. Gets only the sources that have changed and rebuilds only assemblies that have changed. 

Option three is the one that does the trick. If you trigger a build, than change something and trigger another build, your drop location will hold two folders. You will see all the files in both folders but dont be disappointed. All files are moved to the drop location, but mind the changed date: they are all different.


This way you can figure out easily what has acutally changed. This comes in handy if you want to ship hotfixes that only contain files that have really changed to keep installing the hotfix quick.

Have a nice build ;-)
Tobias.