Scott Hanselman

A/B Testing and Testing In Production with Azure Web Apps

July 17, '15 Comments [6] Posted in Azure
Sponsored By

I've got a lot of production web sites running in Azure right now. Some are for small side projects and some are larger like the sites for the Hanselminutes Podcast and This Developer's Life. I like Web Apps/Sites (which is Platform as a Service) rather than Virtual Machines (Infrastructure as a Service) because I don't like thinking about the underlying operating system if I can avoid it. I like to be able to scale the site up (faster, bigger) or out (more machines in the farm) with a slider bar.

In fact, there's some other more advanced and useful features that Azure Web Apps have that keep me using Web Apps almost exclusively.

I'll use a little site I made called that tells you how many keystrokes are left in your hands before you die. Think of it as a productivity awareness tool.

First, I'll add a Deployment Slot to my existing Git-deployed Web App. The source for KeysLeft lives in GitHub here. When I check-in a change it's automatically deployed. But what if I wanted to have a staging branch and automatically deploy to a first? If it works out, then move it to production by swapping sites. That'd be sweet.

Staging Slots for Azure Web Apps

You can see here my main KeysLeft web app has a Staging "side car" app that is totally separate but logically related/adjacent to production. Notice the "swap" button in the toolbar. Love it.

Adding Deployment Slots to an Azure Web App

This Web App has its configuration copied from the main one, and I can setup Continuous Deployment to pull from a different branch, like "staging" for example. The name of the deployment slot becomes a suffix, so unless you set up a custom CNAME like You can have up to 4 deployment slots in addition to production (so dev, test, staging, whatever, production) on Standard Web Apps.

A/B Testing for Azure Web Apps

Once I've got a slot or two set up and running a version of my app, I can do A/B testing if I'd like. I can set up a feature that was called "Testing in Production" and is now "Traffic Routing" and tell Azure what percentage of traffic goes to prod and what goes to staging. Of course, you have to be sure to write your application so such that authentication and session is managed however is appropriate, especially if you'd like the user to have a seamless experience.

Here I've got 10% of the traffic going to staging, seamlessly, and the other 90% is going to production. I can make a small change (background color for example) and then hit the main site over and over and see the occasional (10% of course) request being routed to the staging slot. You can configure this static routing however you'd like.

10% Traffic to Staging

Then I could hook up Application Insights or New Relic or some other event/diagnostics system and measure the difference in user reaction between features that changed.

Advanced Testing in Production

Made it this far? Then you're in for a treat. Static routing is cool, to be clear, but scripting a more dynamic experience is even more interesting. Galin Iliev, one of the developers of this feature, gave me this Powershell script to show off more powerful stuff.

First, you can use PowerShell to manage this stuff. You can change routing values and ramp up or ramp down. For example, here we start at 10% and change it by 5 every 10 minutes.

# Select-AzureSubscription YOURSGOESHERE

$siteName = "keysleft"
$rule1 = New-Object Microsoft.WindowsAzure.Commands.Utilities.Websites.Services.WebEntities.RampUpRule
$rule1.ActionHostName = ""
$rule1.ReroutePercentage = 10;
$rule1.Name = "staging"

$rule1.ChangeIntervalInMinutes = 10;
$rule1.ChangeStep = 5;
$rule1.MinReroutePercentage = 1;
$rule1.MaxReroutePercentage = 80;

Set-AzureWebsite $siteName -Slot Production -RoutingRules $rule1

But! What if you could write code to actually make the decision to continue or fall back dynamically? You can add a callback URL and a Site Extension called the "TiP Callback Extension."

$rule1.ChangeDecisionCallbackUrl =

The Site Extension (and all Site Extensions for that matter) is just a little sidecar Web API. This callback gets a small POST when it's time to make a decision, and you decide what to do based on HTTP-related context that was passed in and then return a ChangeDirectionResult object as JSON. You can adjust traffic dynamically, you can adjust traffic when doing a deployment, do a slow, measured roll out, or back off if you detect issues.

NOTE: The ChangeDescisionCallbackUrl and this code below is totally optional (so don't stress) but it's super powerful. You can just do static routing, you can do basic scripted dynamic traffic routing, or you can have make a decision callback URL. So the choice is yours.

You can check out the code by visiting after installing the TiP callback site extension and look at the Site Extensions folder. That said, here is the general idea.

using System.Web.Http;
using TipCallback.Models;

namespace TipCallback.Controllers
public class RoutingController : ApiController
public ChangeDirectionResult GetRoutingDirection([FromBody] RerouteChangeRequest metrics)
// Use either Step or RoutingPercentage. If both returned RoutingPercentage takes precedence
return new ChangeDirectionResult
Step = (int)metrics.Metrics["self"].Requests,
RoutingPercentage = 10

Here's the object you return. It's just a class with two ints, but this is super-annotated.

/// <summary>
/// Return information how to change TiP ramp up percentage.
/// Use either Step or RoutingPercentage. If both returned RoutingPercentage takes precedence
/// Either way MinRoutingPercentage and MaxRoutingPercentage set in API rule are in force
/// </summary>
public class ChangeDirectionResult
/// <summary>
/// Step to change the Routing percentage. Positive number will increase it routing.
/// Negative will decrease it.
/// </summary>
[DataMember(Name = "step")]
public int? Step { get; set; }

/// <summary>
/// Hard routing percentage to set regardless of step.
/// </summary>
[DataMember(Name = "routingPercentage")]
public int? RoutingPercentage { get; set; }

All this stuff is included in Standard Azure Web Apps so if you're using Standard apps (I have 19 websites running in my one Standard plan) then you already have this feature and it's included in the price. Pretty cool.

Related Links

Sponsor: Big thanks to Infragistics for sponsoring the feed this week. Responsive web design on any browser, any platform and any device with Infragistics jQuery/HTML5 Controls.  Get super-charged performance with the world’s fastest HTML5 Grid - Download for free now!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

Git-deployable F# based Web Applications in the Azure Cloud with WebSharper

May 19, '15 Comments [7] Posted in Azure | Open Source
Sponsored By

Web Apps with WebSharper and F#Last month after I wrote a small prototype to get the F# web framework running on Azure Web Apps (a git deployed managed Platform as a Service) I started looking for more F# Azure resources.

Here's a list of some other existing F# programming technologies that are great with Azure. Did I miss any? I surely did. There's a huge list up at for resources running F# on any cloud.

  • Fog (an F# Azure data scripting API)
  • MBrace (a scalable distributed programming model for F#)
  • FSharp.Data (a set of F# type providers for common cloud data manipulation scenarios)
  • Suave (a simple web development F# library for lightweight microservices including route flow and task composition)
  • FSharp.CloudAgent - a simple framework to easily distribute workloads over the cloud using standard F# Agents as the processing mechanism. Support exists for both simple and reliable messaging via Azure Service Bus, and for both workers and actors.
  • AzureStorageTypeProvider - An F# Azure Type Provider which can be used to explore Blob, Table and Queue Azure Storage assets and easily apply CRUD operations on them
  • Try F# - A web programming console for F# that can be reoriented towards Azure programmability
  • HadoopFs - A lightweight F# implementation of the Hadoop Streaming API
  • FSharp.Azure - A wrapper over WindowsAzure.Store using idiomatic F#

There's also the WebSharper web framework. WebSharper isn't ASP.NET with F#, it's its own idiomatic thing. What's that really mean, "idiomatic?"

You know how when you Google Translate a sentence it doesn't quite work? I mean, it works, but it doesn't feel right. It doesn't feel right because the translator understands the words, and some phrases, but not the idioms - the underlying thoughts that are unique to that language. There was a time a few years back when folks were constantly looking for C# to VB convertors. This is something that's quite possible, almost line for line. However, changing an imperative language into a functional one is not like turning American English into British English. ;) Let functional languages be functional.

F# people like to do things their way and the language has very different goals and ideas than C# so it makes sense there would be a opinionated web framework for F#. I like it.

(Although I'm sure there will be a way to use ASP.NET 5 and MVC with F# in the future, this post isn't about that.)

WebSharper has a VS Extension so you can File New new projects, and here's a hello world ToDo List app (minus the HTML view, which you can see here)

namespace UINextApplication1

open WebSharper
open WebSharper.JavaScript
open WebSharper.JQuery
open WebSharper.UI.Next
open WebSharper.UI.Next.Notation

module Client =
type IndexTemplate = Templating.Template<"index.html">

let Tasks = ListModel.FromSeq ["Have breakfast"]

let Main =

let newName = Var.Create ""

ListContainer =
(ListModel.View Tasks |> Doc.Convert (fun name ->
Task = View.Const name,
Done = (fun e -> Tasks.Remove name)))
Task = newName,
Add = (fun e ->
Var.Set newName "")
|> Doc.RunById "tasks"

More interesting is the recent blog post by Adam Granicz where he expands on my "Suave to Azure via GitHub" prototype and shows how to deploy a real F# WebSharper app to Azure Websites via GitHub.

One of the main improvements is that my solution used FAKE and I found myself wanting a binary version of the FSharp compiler as  NuGet. An issue was open and closed within days, simplifying the deployment. Additionally their WebSharper solution creates an ASP.NET app that runs in the context of ASP.NET and IIS, while my Suave solution needed a separate process. WebSharper 3.1 was recently released, and you can see their sample running live in Azure here:

And of course, you can deploy it to Azure right from here using the Deploy to Azure button!

Deploy to Azure

Do you dabble in F#, are you doing F# professionally? What do you think about F#-based web applications?

Sponsor: Big thanks to Atalasoft for sponsoring the blog and feed this week! If your company works with documents, definitely check out Atalasoft's developer tools for web & mobile viewing, capture, and transformation. They've got free trials and a remarkable support team, too.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

Running and F# with FAKE in Azure Web Apps with Git and the Deploy Button

April 27, '15 Comments [11] Posted in Azure | Open Source
Sponsored By

I was told by some lovely folks in the F# community that there is a nice web framework called Best name ever, eh? Suave is a clean, lightweight, and very F#y (pronounced F-Sharp-ie, I say) in its syntax.

Frameworks like this do well when they are easy to deploy, especially for Hello World. I always find that if a framework can quickly and easily give me a sense of accomplishment I'll be more likely to stick with it. I like to "fall into the pit of success."

I wanted to see if I could make Suave on Azure work easily as well. With the help of Steffen Forkman and the encouragement of the F# community (who have felt historically that support for F# in Visual Studio and Azure has been lacking) I put this little proof of concept together. I used the HttpPlatformHandler that is available in Azure Web Apps now by default, along with a basic Kudu Deployment Script from my Ruby/Middleman post.

Most of the F# community uses a NuGet alternative called Paket that is more F#-friendly. There's also a tiny Paket.Bootstrapper so I could curl things down, then run Paket like this, as part of an Azure Web App deployment. This script modified from Steffen:

@echo off

mkdir .paket
REM TODO - might want to do an IF EXISTS *or* a SHA check
curl -L --insecure -o .paket\paket.bootstrapper.exe

.paket\paket.bootstrapper.exe prerelease
if errorlevel 1 (
exit /b %errorlevel%

.paket\paket.exe restore
if errorlevel 1 (
exit /b %errorlevel%

Then we need web.config to tell Azure Web Apps (IIS8+) to start FAKE to get F# and Suave going. Note the use of %HOME%, full paths and the %HTTP_PLATFORM_PORT%:

<?xml version="1.0" encoding="UTF-8"?>
<remove name="httpplatformhandler" />
<add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified" />
<httpPlatform stdoutLogEnabled="false" stdoutLogFile="fake.log" startupTimeLimit="20" processPath="%HOME%\site\wwwroot\packages\FAKE\tools\FAKE.exe"
arguments="%HOME%\site\wwwroot\build.fsx port=%HTTP_PLATFORM_PORT%">
<environmentVariable name="WhateverYouLike" value="GoesHere"/>

I added logging but it's off by default. You can use it to debug if you have issues, as the FAKE.exe output will go into a series of log files. You can then access them with the Kudu debug console.

I like running "azure site log tail YOURSITE" with the Azure Cross Platform command line. It lets me see the deployment and output as it happens.

FAKE and F# in Azure Web Apps

Here is Steffen's build.fsx:

// --------------------------------------------------------------------------------------
// FAKE build script
// --------------------------------------------------------------------------------------

#r @"packages/FAKE/tools/FakeLib.dll"

open System
open System.IO
open Fake

Environment.CurrentDirectory <- __SOURCE_DIRECTORY__

// Step 2. Use the packages

#r "packages/Suave/lib/net40/Suave.dll"

open Suave // always open suave
open Suave.Http.Successful // for OK-result
open Suave.Web // for config
open Suave.Types
open System.Net

let port = Sockets.Port.Parse <| getBuildParamOrDefault "port" "8083"

let serverConfig =
{ defaultConfig with
bindings = [ HTTP IPAddress.Loopback port ]

startWebServer serverConfig (OK "Hello World! It's on Azure Websites. <a href=''>So easy to setup. Just click Deploy.</a>")

I just added the Azure Deploy button to my like this. This is markdown, of course, but could be HTML

[![Deploy to Azure](](

And you can try this yourself by visiting the repository here and pressing Deploy to Azure, or hit it here:

Hopefully this is a decent clear start towards easily deploying F# Web Apps to Azure via Git, and/or the Deploy Button.

Your thoughts?

Sponsor: Big thanks to the folks over at Grape City for sponsoring the feed this week. GrapeCity provides amazing development tools to enhance and extend application functionality. Whether it is .NET, HTML5/JavaScript, Reporting or Spreadsheets, they’ve got you covered. Download your free trial of ComponentOne Studio, ActiveReports, Spread and Wijmo.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

Introducing Azure Resource Explorer for the Azure Resource Management APIs

April 9, '15 Comments [10] Posted in Azure | Web Services
Sponsored By

When managing Azure resources (Virtual Machines, Web Apps, etc) I like to do most of my work in Azure from the command line using the "Azure xplat cli" - the Azure Cross Platform Command Line Interface. It's an Open Source node.js app that you can get with "npm install -g azure-cli" and it calls the backend REST services that all of Azure uses to manage itself. In fact, when you are using the Azure Portal it's calling the same backend.

It's mostly an "Azure Noun Verb" structure, as you can see in the figure below. You can Azure Site Create or Azure VM Restart, etc.

Azure Command Line Syntax

You can ALSO add --json to the xplat cli to see a JSON representation of the result of your call. So Azure Site List --json gives you a lot more information than without the json switch.

There's a PowerShell interface to Azure, this xplat nodejs one I'm using, as well as other libraries like the Azure Management Libraries for .NET again, all calling the backend REST API.

However, that REST API is huge and confusing. Enter David Ebbo, a Principal Development Lead on the Azure App Platform. He's made the Azure Resource Explorer at as a great way to explore the Azure Resource Management APIs visually and interactively!

And, wait for it, Azure Resource Explorer is, of course, Open Source and hosted here at GitHub It's a preview/beta and not done, but we're all interested in what YOU think! Does it do what you'd expect? Feel free to add issues and get involved in the repository.

Go hit and login with your Azure Credentials. It's an Object Explorer if you've ever used Visual Studio to move around a large object model, except this is a resource try of all the hypermedia nodes within your view of Azure.

Azure Resource Explorer

Here I am moving around my Web Applications that I host in the West US Region of Azure. I can see the deployment slots for staging and production, the source control system and web hooks that deploy my site and lots more. Notice that I can click Actions as well, and (when I turn Read-Only off) perform POST and DELETE calls that will affect my Azure resources.

If you're familiar with Postman, the REST API development tool, this is kind of like Postman for Azure. Here's a 5 min YouTube video by David Ebbo walking you through the Azure Resource Explorer.

To be clear, this is NOT a new Portal, and it IS very low level. This is a tool for folks who want to know what's really going on when an Azure API is called. Perhaps you're creating your own explorer or your own API client in another language. This tool can give you documentation and live examples on how to call those APIs correctly.

Again, it's Open Source and hosted here at GitHub. They would be thrilled to hear your thoughts. Is this useful? In what direction would you like it to go?

By the way, if you'd like to try Azure for an hour for free without signing up for any trials or anything, go check out and play! Also, check out Azure Friday at and subscribe on iTunes.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

Getting admin by adding a new user to sudoers when you're locked out of an Azure Linux VM

March 17, '15 Comments [11] Posted in Azure | Open Source
Sponsored By

So I got locked out of an Ubuntu VM that's running in Azure  Long story, but an employee left and somehow the "admin" user I had access to no longer had "sudo" powers anymore. I needed to run apt-get update && apt-get upgrade but literally had no user available with admin on the box.

If the machine was local, I could perhaps boot into recovery mode but this is a VM in the cloud.

I do however, have access to the Azure portal because I do own the VM. While the operating system  doesn't think I'm powerful inside, I am powerful outside. ;)

Corey Sanders, the head of the IAAS team was kind enough to remind me of the CustomScriptForLinux "VM Extension." VM Extensions can inject/install software like Chef and Puppet into VMs. I talked to Kundana Palagiri about this on Azure Friday (

He pointed me to his "" script on GitHub. It's pretty straightforward, but how do I run it?

# Script to add a user to Linux system
if [ $(id -u) -eq 0 ]; then
        echo "Creating $username"
        egrep "^$username" /etc/passwd >/dev/null
        if [ $? -eq 0 ]; then
                echo "$username exists!"
                exit 1
                pass=$(perl -e 'print crypt($ARGV[0], "password")' $password)
                useradd -G adm,dialout,cdrom,floppy,sudo,audio,dip,video,plugdev,netdev -m -p $pass $username
                [ $? -eq 0 ] && echo "User $username has been added to system!" || echo "Failed to add a $username!"
        echo "Only root may add a user to the system"
        exit 2

I don't have root, but Azure has root. Azure has all the power, in fact. I need to run this script with parameters (my new username and password) then SSH in and put things right. I can return my original user to sudoers:

sudo adduser <username> sudo

And there's other administration I may want to do, including deleting this user I just added. Doing this dance is how I'm going to regain access to my VM, though.

NOTE: There are other ways to regain access to a Linux VM if you've lost a SSH Key or forgotten your password, like the VMAccess Extension in PowerShell. However, not everyone has a Windows machine, and I wanted in fast without any local setup. I'm going to use the Custom Script extension.

First, I'll log into the Azure Portal at and select the VM, then under All Settings, select Extensions. Click ADD and pick Custom Script for Linux.

Adding Custom Script for Linux

Note that my bash script has two parameters, so I'll put my preferred USERNAME and PASSWORD in the Arguments box there and hit done.

Successfully added a VM Extension

After it's done, I click look at the detailed results. Do note that the Azure Portal is called into the backend REST services that manage all of Azure so you can certainly script all of this if you need to.

Script Success

Now I can SSH into the machine (I use bitvise) and then add my original user back into sudoers.

Adding user to group sudo

At this point I can generally tidy up this machine and put it as it was. I've regained control of a Linux VM that I no long had root on.

Please check out, subscribe on iTunes, and tweet and tell your friends! There are over 150 episodes of Azure Friday, each just around 15 min long!

Sponsor: Big thanks to Aspose for sponsoring the blog feed this week! Are you working with Files?Aspose.Total for .NET has all the APIs you need to create, manipulate and convert Microsoft Office documents and many other formats in your applications. Start a free trial today.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Page 1 of 7 in the Azure category Next Page

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.