ASP.Net 5 deployment with VSO Build and Release vNext
Microsoft has documented the process for building and deploying ASP.Net 5 applications to Azure Web Apps using Visual Studio Online build, but accomplishes the deployment using a PowerShell step in the build pipeline. We want to make use of VSO Release Management vNext to be able to stage releases through different environments. This post shows how we finally got this up and running.
Build
Microsoft’s documentation gave us the starting point for this step. The PreBuild.ps1 script provided takes care of bootstrapping the DNX runtime onto the build agent and selecting the right runtime based on the solution’s global.json and the Visual Studio build step builds and packages the web project (using dnu publish under the covers). However, the first problem we encountered was how to run the XUnit unit tests and failing the build if they don’t all pass.
Test
Our test projects are using xUnit and have a “test” command defined in the
project.json, allowing them to be executed using dnx test
.
At least they could be if only
this didn’t result in The term 'dnx' is not recognized as the name of a cmdlet, function, script file, or operable program.
.
Despite the presence of the -p
argument to dnvm install
the dnx
command was still not available to a subsequent PowerShell execution
task.
The solution proved to be a slight modification to the PreBuild.ps1 to set an alias for the DNX runtime version installed.
The test script then calls dnvm use default
before it tries to run
dnx test
. In addition, the RunTests.ps1 script passes the -xml
argument to dnx test
which tells the xUnit test runner to output
test results to an xml file that VSO can use to present nicely
formatted details of test execution by adding a Publish Test Results
build step.
Publish
The final build step added to the build definition in VSO was to
package the output of dnu publish
into a Zip file suitable for
deployment with the Publish-AzureWebSiteProject
cmdlet.
Another PowerShell script calling out to the .Net System.IO.ZipFile
class checked into source control is run by a PowerShell build step,
passing in the path to the publish folder as the source parameter.
Release
Deploy
With a VSO Release vNext definition created and linked to the build
definition set up above, we automatically have access to the Zip
file artifact containing the output of dnu publish
. Passing this
file to the Publish-AzureWebSiteProject
cmdlet by adding an Azure Web
App Deployment task handles connecting to our Azure subscription,
uploading the package to the web app and unzipping. But accessing the
website results in
Using the excellent Kudu diagnostic console (yourwebsite.scm.azurewebsites.net) we can look at the folder layout and spot our prolem.
dnu publish
packs up the web application with web assets and a
web.config configuring the httpPlatformHandler in a wwwroot folder, and
all runtimes, packages and assemblies in an approot folder. The problem?
Publish-AzureWebSiteProject
uploads and extracts our Zipped artifact
under /site/wwwroot folder of the site, not directly into /site as we
need.
Reconfigure
So how to resolve this? I started digging around in the source code
for Publish-AzureWebSiteProject
to see if there might be a
configuration option but without any joy. So the next step was to try
reconfiguring the web app configuration. This SO thread
pointed to this being a working solution and a quick test by changing
the configuration in the Azure Preview Portal proved it worked.
I wasn’t keen on leaving this as a pre-requisite of the site configuration for the deployment to work, especially as our reason for using VSO Release is to be able to deploy to multiple environments. A bit of hunting around found David Ebbo explaining how to use Azure Resource Management PowerShell to script this sort of update. An Azure PowerShell script task in VSO makes sure this is done with each deployment. This isn’t entirely as straightforward as it might sound given that the underlying ARM REST API doesn’t support management certificate authentication, so we need to use an AD Service User with the PowerShell commands.
Conclusion
The documentation was mostly there for us to implement our automated build strategy with just a few minor pieces of the puzzle missing, mainly around running unit tests. Guidance on how to use VSO Release vNext to manage releasing an ASP.Net 5 application to Azure was tricky to come by, but a bit of trial and error has got us there. Hopefully this blog post will help anyone else that finds themselves facing similar challengs.
Modifying the virtual directory configuration of the web app feels
dirty but I’m hoping this is a temporary fix until
Publish-AzureWebSiteProject
or similar has better support for
uploading the package into /site instead of /site/wwwroot. If it does
prove to be a longer term solution, then as our solution matures
to the level where we have an ARM template for our Azure architecture
then we should be able to incorporate the virtual directory
configuration into the web app definition and not require the separate
PowerShell step.