Team Foundation Server 2013 Update 3 came with Visual Studio Release Management vNext. vNext is, next to the deployments with agents, another way of doing deployments with VSRM. The most important thing in vNext is that you can do deployments to machines, without having to install an agent.
This is because VSRM vNext uses Powershell Desired State Configuration (Powershell DSC) as the tool/engine to execute powershell on different machines.
Powershell DSC is fairly well documented, but VSRM vNext not really. There is a great blog serie of Colin Dembovsky (here) that goes fairly deep into the engines, and there is good starter from Jeff Levinson, but there was no post that I could follow to start a vNext release from scratch.
So I decided to figure it out with help of the blogs I found and write a post that walks through all the steps without making it too complicated.
Instead of walking you through the steps by creating all the prerequisites first, I will use my own way of thinking and starting and set this all up.
1. Check your prerequisites
I will use the following stuff in this post:
- Azure subscription where I can create a Virtual Machine
- Team Foundation Server 2013.4 installed
- Release Management Server + Release Management Client 2013.4 installed
- TFS Build Server + Agent 2013.4 installed
- Visual Studio 2013.4 (Pro/Premium or Ultimate)
- An empty Team Project (RMvNextForDummies)
2. Create the simplest web application ever
- Start up your Visual Studio and create a new Web Application
- Run to test the solution. If you want to make it pretty you can always change the color or the title.
3. Check in Solution and create a Build
Check in the solution in Source Control in your newly created Team Project. Easiest way is to just right click the solution and choose [Add Solution to Source Control], Choose the right Team Project to add the solution to, Navigate to the [Pending changes] hub in Team Explorer and check in your changes.
Navigate to the [Build Hub] in Team Explorer and create a [New Build Definition]. Leave everything default. on the [Build Defaults], fill in a valid drop location, and on the [Process] Tab, make sure you selected the solution you just created.
MSDN Documentation can be found here
Run the build to check if it builds successfully!
4. Set up Release Management to use your Azure account
Start up the Release Management Client and navigate to the [Administration | Manage Azure] Tab. Click [New] and fill in the details that are asked. The information that should be filled in is described perfectly on MSDN. Click this link and follow the steps described here.
Now create a Virtual Machine with Windows 2012R2 on Azure. Do nothing yet on this virtual!
http://www.visualstudio.com/get-started/deploy-no-agents-vs#SetupAzure
Get the SubscriptionID and ManagementCertificate from the publishsettingsfile you downloaded. Create a new storage account on Azure especially for using in Release Management. Use the name of the storage account as [Storage Account Name]
MSDN on how to create a storage account
Create a vNext Environment and link your newly created Azure Server
5. Create a Release Template and Path
No we need to create stages (our deployment pipeline) and a release template.
For this, follow the steps described here. Keep it simple and add only 1 stage !
http://www.visualstudio.com/get-started/deploy-no-agents-vs#CreateReleaseTemplate
This is my result for the Release Path
My Component
And my Template (still empty)
6. Start my first Release
Now..No further hassle, I want to start a release!
Drag the [Deploy using PS/DSC] to the surface.
When you try to choose the [Componentname] it cannot be chosen yet. In order to do this, you need to add the component to the toolbox first. Right click the components “folder”in the toolbox and add the component.
Now select the ComponentName. and trigger a [New Release]. Select the latest build and start. You ‘ll end up in an approval screen where you can approve the release of the first stage. Approve it and watch what happens.
Sure ! I know that we don’t have a PowerShell DSC script yet do do anything, but we can try to make the communication work first.
7. Troubleshoot and make it work
At this point I started to think about a blog post, because my first release (after a long long wait) failed !
Looking at the log file, it showed the following (somewhat cryptical) message.
System.Reflection.TargetInvocationException: Exception has been thrown by
the target of an invocation. --->
System.AggregateException: One or more errors occurred. --->
Microsoft.TeamFoundation.Release.Common.Helpers.OperationFailedException:
Failed to establish remote power shell session to the deployment machine
machine.cloudapp.net on the port:<port> due to unexpected exception.
Error Message:
System.Management.Automation.Remoting.PSRemotingTransportException:
Connecting to remote server machine.cloudapp.net failed with the following
error message :
WinRM cannot complete the operation. Verify that the specified computer
name is valid, that the computer is accessible over the network, and that a
firewall exception for the
WinRM service is enabled and allows access from this computer.
By default, the WinRM firewall exception for public profiles limits access
to remote computers within the same local subnet.
For more information, see the about_Remote_Troubleshooting Help topic.
Solution: This had something to do with the firewall on my on-premise network. The Remote Management Port (default on 5986 and 5985) was not open. I made sure I could access this port and validated that by doing a telnet session to my machine.
Open a command box and type telnet machine.cloudapp.net 5986. When a blank screen appears it means you can access the port.
Try again to start a new Release. Now I received the following message
System.AggregateException: One or more errors occurred. --->
Microsoft.TeamFoundation.Release.Common.Helpers.OperationFailedException:
Failed to establish remote power shell session to the deployment machine
machine.cloudapp.net on the port:5986 due to unexpected exception.
Error Message:
System.Management.Automation.Remoting.PSRemotingTransportException:
Connecting to remote server machine.cloudapp.net failed with the following
error message : The server certificate on the destination computer
(machine.cloudapp.net:5986) has the following errors:
The SSL certificate is signed by an unknown certificate authority.
So what does this mean. After some searching I found out that you receive this error because the target machine is not part of your domain. You can solve this in 2 ways.
1. Set the SkipCaCheck in your Release Template to true. This skips the check for the certificate. I chose this one for my further post because it is the easiest way and the closest to Release Management.
2. Upload the SSL certificate from the target machine to the store on your RM server. This is described perfectly here
Run Again !
And we run again, and again I got an error!
One or more errors occurred. ---> Microsoft.TeamFoundation.Release.Common.
Helpers.OperationFailedException:
System.AggregateException: Failed to install
'VisualStudioRemoteDeployer6e734d82-cd76-4bfc-b60e-81abdd4179ca' from
service executable path VisualStudioRemoteDeployer.exe .
The account name is invalid or does not exist, or the password is invalid
for the account name specified
What now…My account is an admin account.. With some help of the Visual Studio Product Team, I figured out that you should prefix your username in RM with a domain and slash. So instead of [renevo] it should be [.\renevo]. And we run again!
YES ! We made it.
8. Check some artefacts
We have our end-to-end scenario. Deploy (doing nothing yet) succeeded and we are in the validation step. The steps performed are.
- Upload all the build output to your azure storage. You can check this by logging in to your azure account, navigate to storage, select the storage you configured in RM and choose container. There you see the files from the build.
- On the target machine you have a directory [DtlDownloads] in you c:\windows (c:\windows\dtldownloads). Here you find all the files downloaded from storage and ready for further processing on your machine.
9. Create a simple DSC script that we can execute
Now that we have our connectivity, we can start building some DSC. There are some good posts around the internet about DSC and also some in combination with Release Management. You can find those in the resources section at the bottom of this post.
For now , I will suffice by copying the website bits to the inetpub/wwwroot directory on the target machine. The DSC script we want to execute must be send to the server as well. The easiest way to do this is to make the DSC part of the build.
Open your web application, and add a folder DSC to your web application. Add a file CopyWebSite.ps1 to this folder and put this in the file.
configuration FullSetup { node MACHINENAME { WindowsFeature IIS { Ensure = "Present" Name = "Web-Server" } WindowsFeature ASPNet45 { Ensure = "Present" Name = "Web-Asp-Net45" DependsOn = "[WindowsFeature]IIS" } File CopyDeploymentBits { Ensure = "Present" Type = "Directory" Recurse = $true SourcePath = join-path $applicationPath "_PublishedWebsites" DestinationPath = "C:\inetpub\wwwroot" DependsOn = "[WindowsFeature]ASPNet45" } } } FullSetup
Make sure you replace MACHINENAME with the name of your target Azure machine.
Make sure you set the file properties in VS to Copy Always so that your file ends up in the build.
In your Release Template, add this file to the PSScriptPath
Check in the file, run a build and start a new release.
When this succeeds, you have configured a IIS, Framework 4.5 and copied the bits of your build to a directory.
10. Try more with DSC and RMvNext
Now try more with DSC. Follow the posts listed below for more advanced use.
Resources
Jasper Gilhuis’ – Curah on Release Management (a selection of links)
http://www.colinsalmcorner.com/post/using-powershell-dsc-in-release-management-the-hidden-manual
http://fabriccontroller.net/blog/posts/using-remote-powershell-with-windows-azure-virtual-machines/
http://www.visualstudio.com/en-us/get-started/deploy-no-agents-vs.aspx
DSC
https://gallery.technet.microsoft.com/scriptcenter/DSC-Resource-Kit-All-c449312d
https://technet.microsoft.com/en-us/library/dn249921.aspx
http://www.colinsalmcorner.com/post/install-and-configure-sql-server-using-powershell-dsc
René, Great post. I had pieced together information like you until I found this!
A couple questions about the configuration, I get through pre-deploy, and the validation you recommend works files show up in storage but the deploy fails:
1) You’re using Team Foundation Server for builds, I am using VS oline; is TF Server required on the RM server or client machines?
2) I set up a new Azure VM for the deployment target, then ‘Do nothing with this virtual’ am I supposed to follow the configuration in the provided link to agent-less RM deployment?
a) can I set up a RM agent to accept the bits by way of the DSC sript?
b) seems the scrip provided — thanks — doesn’t configure IIS, should that be done before the first release?
3) The error I get is ‘The term ‘C:\Windows\DtlDownloads\CI Test\Copywebsite.ps1′ is not recognized as the name of a cmdlet …’ and the script is in C:\Windows\DtlDownloads\CI Test\_PublishedWebsites\AppForHTML-CI\bin any advice on fixing that will be appreciated.
The idea of setting up the communication and confirming that it works before attempting to deploy is great. The ‘gotchas’ that you provide undoubtedly will save a lot of people time thanks!
Thanks ! Maybe this post has Some pointers you can use. Trigger a vNext release template from a build definition throws Http Error 500 | The Road to ALM
https://roadtoalm.com/2015/02/23/trigger-a-vnext-release-template-from-a-build-definition-throws-http-error-500/
Hello René,
Thanks for the link, that isn’t really it.
The error was resolved by ‘tweaking’ the file path to Copywebsite.ps1 . Seems a really random place where RM expects the path to start, the whole path is on the target machine is
C:\Windows\DtlDownloads\CI Test\_PublishedWebsites\AppForHTML-CI\DSC\Copywebsite.ps1
in the RM client, release template, I used .\_PublishedWebsites\AppForHTML-CI\DSC\Copywebsite.ps1
to get the .ps1 to execute.
So, does this relate to the ‘Join-Path’ in the DSC script? We did put the script in a DSC folder in the application.
Stephan
Hi René
I’ve been writing software for a while, but this part is all new to me (CI, RM, Build Agents, TFS, TeamCity, Git, etc.). I’m in the middle of learning and getting everything set up. It’s a project!
More specific: Does this subject matter preclude the use of a TeamCity/TFS combination? I’m pretty well settled on that duo for TeamCity’s NuGet feature, which I’m going to need.
But I like the concepts presented here. I’m just a little hazy yet on how it all fits together. Hopefully I’ll be able to use this together with my TeamCity/TFS setup.
Please advise.
Thanks,
Jeff Bowman
Fairbanks, Alaska
I think the easiest way is just read through the pages here https://www.visualstudio.com/get-started/overview-of-get-started-tasks-vs to get a Good overview of All the different aspects of ALM.
Hi René
Thank you for the handy general reference. I’ll be able to make good use of that.
For my question specifically—RM vNext w/TeamCity—I was able to find this:
http://blog.ehn.nu/2015/01/trigger-visual-studio-release-management-vnext-from-teamcity/
So it looks like it is indeed possible. In fact your post and his make a nice pair.
My but these are exciting times 🙂
Thanks,
Jeff Bowman
Fairbanks, Alaska