WATK in F#, Part 2: Deploying an Azure Web Site with Git

WATK in F#, Part 2: Deploying an Azure Web Site with Git

UPDATE: The code for the first three posts in this series is now on GitHub.

In Part 1 we did the first part of the first WATK Hands-On Lab by deploying an F# / C# MVC 4 application to an Azure web site. We saw that having F# in the solution made no difference.

In this post we'll continue the HOL by deploying the app from a git repository. This is a bit more tricky due to a fundamental difference between the two deployment methods (which the lab manual doesn't mention). When you publish from Visual Studio as we did in Part 1 , Visual Studio builds the solution on your computer and uploads the compiled assemblies to Azure. But when you deploy from a git repository, you upload source code to Azure, and Azure builds your application in the cloud using an open-source build engine called Kudu. So publishing Azure web sites with git means that your code will be built by a different engine than you're probably using, in an environment you don't control. The results won't necessarily be the same as when you build locally.

In fact until recently Kudu couldn't build F# projects at all. It was unable to locate Microsoft.FSharp.targets (because it's stored in a different .NET Framework folder than the C# and VB.NET targets), so all deployments from git to Azure would fail if they included F# projects. The Kudu team fixed this bug, and the fix became public on Azure on 5/24/2013, so we can now proceed with the HOL.

We open the lab manual to Exercise 2: Publishing an MVC 4 Application using Git, and we do Task 1 and Task 2 exactly as the manual says. One small change is that there are more choices than when the lab manual was written.

Set up deployment from source control

  Chose local git repo

Now we need to put our F# / C# solution in a git repository. The lab manual shows how to do this using the bash shell in Git for Windows. I decided to try it using Microsoft's Visual Studio Tools for Git, which is supposed to allow me to use git like it's just another source control plugin. This tool is still very much "in development" and will never expose all the rich awesomeness of git (;~>), but it worked well enough for the HOL. You can use the bash shell or some other git tool if you prefer.

(UPDATE: you can find more complete instructions for using Visual Studio Tools for Git here.)

After installing Git for Windows and Visual Studio Tools for Git we right click on the solution and select Add Solution to Source Control ..., and chose Git provider.

Choose git provider

Then we right-click on the solution again and chose Commit. This brings up Team Explorer, where we type the required commitment message. Git users customarily put quite a bit more information in this message, but we can get by with just "commit 1".

Commit to git


These actions place our solution in a local git repository.

Commit succeeded

We now click the Commits link (to the right of Branch: master) to set up publication to our remote repository in Azure. Under "Publish to Remote Repository" we copy the git URL from the Azure deployment page and click Publish. As explained in the lab manual, we will need to provide a special user name and password for git publication, which we set up in our Azure subscription for all web sites.

Publish to Remote Repository

Once we publish, Visual Studio thinks the deployment succeeded.

Publican Succeeded -- Not!

However, when we look on the Deployment tab in Azure, we see that it failed. (The current Visual Studio Tools for Git can't detect Kudu build errors. Had we pushed with bash, the shell would have displayed the errors.) To see what went wrong, we need to expand the deployment details and display the final log.

Deployment Failed

The log tells us that Kudu wasn't able to locate all the assemblies referenced in the F# project. In particular, it wasn't able to find the assemblies relating to ASP.NET Web API.

Deployment log: build failed

Fortunately there's an easy way to solve this, though it may not be obvious. The trouble is that the F# project is targeting the wrong version of the .NET Framework. The project is targeting .NET Framework 4.0, but it's referencing assemblies that were built for .NET Framework 4.5. We can see this if we expand the References section in Visual Studio and notice some yellow exclamation points beside some assemblies. This didn't prevent Visual Studio from compiling the project, but Kudu is not so forgiving. So we need to change the project to target .NET 4.5.

Change to .NET 4.5

Now we return to Team Explorer, click the Home icon, click the Changes link, and commit the new changes.

Commit the new changes

Then we click the Commits link, then click the Push button.

Push the new changes

And now our deployment succeeds!

Deploy succeeded

In reality, dear reader, it has taken me a very long time to figure out how to get this deployment to work. I've been actively engaged with the Kudu team on two GitHub issues over this, which you can read about here and here. Kudu is a tiny island at the intersection of some big tectonic plates: Azure, Git, Nuget and Visual Studio. I see no reason why F# can't thrive on this island as well as any other language, provided the Kudu team can accommodate its somewhat special position in the Visual Studio / .NET ecosystem.

In Part 3 of this series we'll finish the HOL by using F# to persist  Contacts in a SQL Azure database with Entity Framework.