Blogging on Azure Stuff

With the introduction of Windows Containers on Window Server 2016 and the ability to run containers in Service Fabric I thought it was time to investigate Windows Containers and I wanted to know how to build one that will run a web site using IIS.

As I’m new to containers, although I’ve done a very similar exercise with Docker on Linux, I decided to follow the Windows Quick Start Guide. I hit a few problems early on so I’ve put the steps I followed here:

After opening a PowerShell window as administrator I ran the following commands:

It turns out that the docker service wasn’t running after the reboot, so open services.msc and find the docker service to start it.

Running the same command again will download the image from docker hub, create a container from it and then run it. As this is a visual container it runs once and then stops.

Every time I do docker run microsoft/dotnet-samples:dotnetapp-nanoserver it creates a new container. What I want to do is to run one that is stopped and view the output on the screen.

For this I needed to start the container I had already created. If you run

docker –ls –a

This will list all the containers that are both running and stopped and you can see from the image below that I had run docker run a number of time. Each time it tried to download the image (which was already downloaded) and then create a new container from it.

docker container start -a 12d382ae0bd6 (-a attached STDOUT so you can see the output)

Now I know how to create and start containers I wanted to build one of my own. This is easier than I first though as there a lots of base templates stored on docker hub and git hub.

This retrieves the template from Docker Hub and I want to use that template to install my ASP.Net MVC site and configure IIS to serve the pages on port 8000. Following the instructions here (https://docs.microsoft.com/en-us/dotnet/articles/framework/docker/aspnetmvc). I published my MVC site and copied the publish folder to my docker machine. Then I needed to create a Dockerfile recipe to instruct docker what to install in my image. So I created a folder that contained the Dockerfile and also the published website as below

The contents of the Dockerfile are:

# The FROM instruction specifies the base image. You are# extending the microsoft/aspnet image.FROM microsoft/aspnet# Next, this Dockerfile creates a directory for your applicationRUN mkdir C:\sdsweb# configure the new site in IIS.RUN powershell -NoProfile -Command \Import-module IISAdministration; \New-IISSite -Name "sdsweb" -PhysicalPath C:\sdsweb -BindingInformation "*:8000:"# This instruction tells the container to listen on port 8000. EXPOSE 8000# The final instruction copies the site you published earlier into the container.ADD sdswebsource/ /sdsweb

Now I need to run this to create the image

In PowerShell, I changed directory to the folder containing my Dockerfile, then ran

docker build -t sdsweb .

This has created an image and we need to now get this running as a container

using docker run again

docker run -d -p 8000:8000 --name sdsweb sdsweb

My container is now running and I should be able to view the web pages in my browser on port 8000, but I need to know the IP address first

I changed the default web page to show the machine name serving the pages under Getting Started. Listing the containers will show the container ID and this matches the machine name displayed on the web page

That’s it running in a container. There are a couple more things I’d like to do before I’ve finished. The first is to make sure that when my Windows Server restarts, then my sdsweb container also starts. At the moment it will not start as I didn’t add a restart parameter when I called docker run. Adding –restart always will cause the container to restart when windows restarts.

docker run -d -p 8000:8000 --name sdsweb --restart always sdsweb

The final thing I want to do is to be able to share this image so I’d like to push it up to docker hub

docker login - enter username and password

docker push recneps/sdsweb

Then to use it on another machine

docker pull recneps/sdsweb

In my next post I am going to look at how I can create a container that can be hosted in Service Fabric

I’m currently evaluating Release Manager in Visual Studio Team Services and I am using it to deploy website to Azure Web Apps. I recently tried to deploy an Asp.Net MVC 4 application and ran into some issues.

I’ve created a build that packages and zips up my web application which runs successfully.I’ve linked a Release pipeline to this build and I can deploy to my test Azure site without any errors, but when I try and run the web application I get the following error:

Could not load file or assembly 'System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.

I’m using Visual Studio 2013 with MVC as a nuget package.Looking at the properties of System.Web.Mvc I can see that it is set to Copy Local = True

I tried a few different things to try to get the assembly to be copied like redoing the nuget install and eventually I toggled the Copy Local to False, saved the project file and then set it back to true. When I looked at the diff of the project file I found an additional property

This seems to fix the build. When I checked this in and rebuild, System.Web.Mvc now appears in the zip file. The build was then release to Azure and the web app worked correctly.

When using configuration in Microsoft Azure websites, ensure that you put configuration that you are likely to change often in AppSettings. This allows you to make configuration changes in the Management portal of Azure rather than having to edit the web.config file directly. An example of where you might like to do this include settings that allow you to disable site features temporarily such as during an upgrade or routine maintenance.

App settings in the web config file are names/value pairs and are accessed as follows:

I’ve been setting up one of our services as the backend service for Azure API management. Part of this process we have mapped DNS to point to the service. As the service is hosted in Azure Websites there are now two urls that exist which can be used to access the service. I wanted to stop a user from accessing the site using the azurewebsites.net url and only access it via the mapped domain. This is easy to achieve and can be configured in the web.config file of the service.

One of our projects involves a web service that implements both SignalR and Web API and we were looking at the quickest and most cost effective way to get it deployed so that one of our customers could run a Windows 8 application as a demo away from the office. The application works well internally as we have the service deployed on one of our servers on IIS. The options we were considering were:

Package the application up in an install package, ship this to our customer and then provide them with instructions and support to allow them to deploy and configure their application

Deploy it on one of our servers and then publish the service through our firewall

Deploy as a Cloud service in Windows Azure

Deploy as a website in Windows Azure

We considered the fact that the first option would probably take us a fair amount of time to make a deployment package, test it and provide enough documentation and support to allow our customer to deploy it on their servers. The other 3 options involved us doing a smaller amount of work, but at least we could get everything working well before shipping the demo out. Option 2 would mean using our internal resources for something that would not be used that often but we would not necessarily know whether and when it was being used so the resources would need to be kept running limiting our capacity internally. Windows Azure was a good fit for this application and the choice was really between setting up a cloud service or use a web site, I guess we could have set up a virtual machine hosted in Windows Azure, but this was a bit excessive just for a simple web service. The two remaining options were to set up a cloud service by creating a web role in deploying to Windows Azure or to use Websites. The cloud service would involve more work for us as we would need to change the project to add in the cloud service project and web role and then do a full PaaS deploy to Windows Azure. This would then utilise a whole virtual machine (although we would have used an Extra Small instance), but the web sites seem a sensible option especially as we already have a number of them available for free. How easy was this going to be and will both Web API and SignalR work with Windows Azure Websites, especially as we were using preview software. I was surprised about how easy this was to deploy and I’ll walk through the process we went through.

Paste this into your web config file of the web api service. You will need to make sure that the Windows Azure SQL Server firewall has your public IP address configured and you will need to make sure that your firewall will allow connections through port 1433. Now run your application and make sure that you can connect to the Windows Azure SQL database. As we are using Code First Entity Framework, the database tables were created for me so I didn’t need to do any database deployment. The only issue I had with this approach was that I had to create the database first in Windows Azure.

Step 3: With our service running locally but with the database in Windows Azure we are now ready to deploy to the cloud. In the Windows Azure Management portal, click the “New” button

The “Quick Create”, enter the url you want to use and click “Create Web Site”

Step 4: We now need to deploy our service. In the Azure management portal, navigate to the web site you just created and click “Download Publishing Profile”. Save this to your computer.

In Visual Studio 2012, open your web api project, right click on the project in Solution Explorer and click publish.

This will display the publish dialog.

Click the import button and navigate to the folder where the publish profile was saved. This should then allow you to complete the wizard

Click Next and check to make sure the correct connection string is displayed, click Next then Publish. This should then start to upload your web api project to the Windows Azure Website. The deploy should be relatively quick and no where near the time it takes to deploy a cloud service. When completed, your deployed website should start in the browser and you can carry out whatever tests you need.

Step 5: With your website deployed you should just need to change the url of your service in the Window 8 application.

This whole process took less than 10 minutes to setup and deploy. One of the nice features of using websites is that changes are quick to deploy.

We had a number of issues to get this all working fully:

As I mentioned earlier we had to ensure that the database was created before the EF code would create the correct tables

When we first ran the Windows 8 application we were getting an error each time we tried to use SignalR. We received an “Incompatible protocol version”. This was because I installed the latest SignalR libraries on the server side code but the client was using an older version. You need to make sure that both the client and server are using the same version of SignalR

We also had an issue when deployed to Windows Azure where it looked like the SignalR hubs were not being created correctly. It looked like the hub creation was hanging and not returning. This is a known issue that has been fixed but not yet deployed to Azure. There is a work around which is to configure SignalR to use long polling (https://github.com/SignalR/SignalR/issues/510). We did that with the following code:

1: hubConnection = new HubConnection(App.SignalRUrl);

2: proxy = App.hubConnection.CreateHubProxy("statushub");

3: App.hubConnection.Start(new LongPollingTransport()).Wait();

Windows Azure Web Sites is not just for web sites, using it also for services can make a lot of sense as the scaling model will allow a lot of flexibility and can provide a cost effective way to host your services, especially if they are not heavily loaded at the start. They are also easy and fast to deploy which is always a bonus

This is a follow on post from my introduction to Windows Azure Websites and shows you how you can synchronise your website in TFS with Windows Azure.

One of the biggest problems with the way you deploy applications to Windows Azure is that minor changes (e.g .markup, content and styling) require a redeploy to publish the changes. Windows Azure Websites solves this problem by allowing you to synchronise your website with Team Foundation Server or GIT.

In this post I will show you how easy it is to manage your websites in version controlled environment using Team Foundation Service. Team Foundation Service is a cloud hosted version of Team Foundation Server.

This works by creating a continuous integration build with your source code that will automatically deploy your website after successful build each time code is checked in.

This site now needs to be link to your Team Foundation Service. Click on the website in the dash board and then select “Setup TFS Publishing”. you will also note that you can use a GIT repository as well as TFS.

Enter your TFS url (or create a new one), then click Authorize Now.

this connects through to your TFS service and setup the CI build that will deploy your application to the cloud.

The TFS site will now be displayed asking you to authorize the connection

You now need to pick the website you want to deploy. If you haven’t create a site yet then you need to go to ~Visual Studio, create your site and check it in to TFS.

You have now linked your web site in TFS to the Azure Website. This will take a few moments to synchronise.

Your website has not been deployed yet. You need to make a change and then check the changes in

upon check-in the build is started

When the build is complete the new website is deployed

You can also revert back to older versions of the web site by clicking the desired version and then clicking redeploy:

This will start the redeploy of the older version:

A new build is kicked off using the same changeset details as the original deployment. Once the build is complete the web site is reverted back. this whole cycle only took a few minutes so it is a lot faster than the redeploy mechanism you had previously.

TFS and Windows Azure provide a good mechanism for version controlling your website. Adding application life cycle management to any software development activity is a good thing.

We recently moved a web application into Windows Azure that was using session state. As it was running on a single webserver the session state was set to InProc but this is not useful when in a multi-server environment as the session is stored on the specific machine and is therefore not accessible to other machines. There were a number of options:

Windows Azure Storage seemed to be the more cost effective version as the site does not currently use SQL Azure and they have purchased a subscription for Azure which includes both transaction and storage costs.

There is a sample asp.net session provider that uses Windows Azure Table Storage as its backing store. The sample can be downloaded from MSDN at

Add your windows azure storage connection string (DataConnectionString) to each web role that requires session state (Not setting this will result in an object reference not set to an instance of an object exception)

Add a reference to the ASPProviders.dll taken from the sample project and make sure that the Copy Local property is set to true (Not setting this will cause an unable to load exception)

We also added a reference to System.DataServices.Client and set copy local to true on this too.(Not sure if this is needed)

Once this is setup and running, add multiple instances to your role configuration and run in the debugger. Make sure you can navigate to the page that has the session data in. I put a break point onto the action of the page and added a watch for Microsoft.WindowsAzure.ServiceRuntime.RoleInstance.CurrentRoleInstance.Id and checked to see if it changed and if it did change checked to see if the session data was visible.

You may well get the following error when you are using session as all the objects that are put into the Azure Table Storage session object need to be serializable.

Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.

You can check to see the session data in the Azure Storage Server Explorer.

We are going to run this for a while to se how well it works and also see what debris is left behind in the table and blob storage due to ended sessions. We might have to have a job running that tidies up the expired sessions later.

Whilst doing an access control service demo I was asked whether you could wire in your own existing authentication mechanisms as customers did not want to have to redo their authentication/registration mechanisms to use Live ID, Google, Yahoo! etc. The answer to this was yes but I had never done it so this was a good time to investigate how.

I started off with the Windows Azure Platform Training Kit(VS2010) and worked through the “Introduction to the AppFabric Access Control Service V2” lab to setup a web site that allows login via Live ID, Google and Yahoo!. Once this was running I needed to create my own provider and wire it into the lab solution that I just created. There is an additional lab ""Federated Authentication in a Windows Azure Web Role Application" which gives the basics of creating your own identity provider. Unfortunately this does not link to ACS so I needed to work out how to wire the provider in. The following instructions are how I created the site and wired it in:

Taking the ACS lab solution as the basis, create an ASP.Net website that will carry out the login process. For this I added a “ASP.NET Security Token Service Web Site”. Right click on your solution and select new website. Make sure that the URL you enter for the site includes https at the start. (e.g. https://localhost/MyIDProvider).

When the project is created, you need to change some of the code in the template as it does not handle the return address correctly when redirecting from your identity provider after logging in.

The template for an STS web site needs the following code changing in App_Code\CustomSecurityTokenService.cs

This takes the replyto address from the query string and uses this to redirect back to ACS once the login process has been completed. There are 2 other changes required to the basic STS template in order for it to work correctly.

Open web.config and search for IssuerName in the application settings section and change it to be the url of your STS website (e.g. https://localhost/MyIDProvider)

Also change the SigningCertificateName to point to a certificate that exists in your local machine certificate store. This website will now provide a simple mechanism for logging in. Without any changes you can enter any username and it will authenticate. At this point you will need to wire in your own authentication mechanism, but for testing purposes the default site will allow you to set it up correctly and test it out.

Click “Identity Providers”, “Add Identity Provider” and add a new “Microsoft Active Directory Federation Service 2.0” provider. The two bits that are important are “WS-Federation metatdata” and the relying party application. Browse to the FederationMetadata.xml file of your STS project you have just created. (e.g. C:\inetpub\wwwroot\MyIDProvider\FederationMetadata\2007-06\FederationMetadata.xml). Also ensure that the ACS website created as part of the labs is checked and press Save.

The final piece of configuration that is required is to add in the rules for your provider. still in the Access Control Service portal, click “Rule Groups”, select the rule group that you setup for your ACS lab and select “Generate Rules”. Ensure that your new identity provider is in the list and that it has been checked and press the “Generate” button. Two new rules should have been added for your provider (Pass through for name and role). You are now ready to test this.

To make it easier to see what is happening I added the following to the Default.aspx of my ACS lab

In default.aspx add the following:

<asp:LoginViewID="LoginView1"runat="server"><AnonymousTemplate><asp:PanelVisible="true"CssClass="secretContent"runat="server"ID="unauthorisedContent">
You are unauthorised to view this page
</asp:Panel></AnonymousTemplate><LoggedInTemplate>
You are logged in
</LoggedInTemplate><RoleGroups><asp:RoleGroupRoles="Administrator"><ContentTemplate><asp:PanelID="SecretContent"runat="server"CssClass="secretContent"Visible="true">
Secret Content (Only administrators can access this section)
</asp:Panel></ContentTemplate></asp:RoleGroup></RoleGroups></asp:LoginView>

This will display the login status so you can see whether the login works or not.

Also add the following style to the site.css file in the ACS lab site:

Run the ACS lab application and check to see if your provider appears in the list of providers and also that when you click on the button it redirects to you page. Login and you should be redirected to the Default.aspx page of the ACS lab site with the text “you are logged in”.

You may want to change the claims that are allowed for specific users. This is done in App_Data\CustomSecurityTokenService.cs in your identity provider web site.

Modify GetOutputClaimsIdentity to change depending upon who is logged in.

Change the code that adds a Manager Role to the following code to allow a user called Steve to be an administrator and everyone else as a user.