Saturday, October 18, 2014

Multiple web applications in single cloud service web role with multiple SSL certificates and custom domains over https using Server Name Indication


I know the title of this post is quite big and hard to understand in first go. But I wanted to highlight the important aspect I am going to touch in the article and hence such a long name.
Ok, so here in this post I am going to demo how you can host multiple web applications in single cloud service. I know you may say that there are numerous posts on the same topic what is different in here? Yes the difference is there. You may find that most of the posts talks about hosting multiple web sites in single cloud service web role but they do not focus on running them on HTTPS and with custom domain name. Exactly this is what I am explaining in this post.
So in essence, we will see that, how can we host multiple web applications in single cloud service web role. Then we will see how the same applications can be hosted on HTTPS using SSL certificates in single cloud service web role. After that we will extend the talk to hosting same apps with custom domains using new feature of IIS 8.0 called as Server Name Indication (SNI).
Applicable software stack – VS 2013 and above, Azure SDK 2.3 and above, IIS 8.0 and above. [IIS 7 not supported].
Create required project in Visual Studio
This part is pretty straightforward implementation. To start with I created a simple cloud service project in VS2013 and added one web role in it. I renamed the web role to ManegementAppWebRole as shown below –

I changed the default.aspx UI text to just make it identify as Management App. Now I added another ASP.NET web project in the same solution. This will be my survey app. In this also I changed the default.aspx text to just make it identify as Survey app. So in all my projects structure is as follows –

Hosting multiple web applications in the same cloud service web role
Okay, so here I am representing a way by which you can have two web sites hosted in the same cloud service web role. In my case one of the applications is Management app web role itself and another is Survey web application which is not the part of cloud service. So I will run the survey app as part of Management app web role. To configure this full IIS capability can be leveraged. We have a special file in cloud service project know ServiceDefinition.csdef file. My current structure of .csdef file is as shown below –


The <Sites> tag is the key to make this possible. So I just added another site in .csdef file and provided the path of Survey web application. And provided the actual physical path of my survey app. Most importantly if you observe I have provided the host header for my survey app as “surveyapp.kunal.com”. This is the main differentiator of the survey app running in the Management app web role. IIS do not allow to have more than one site listening on the same port without adding host header. We need to provide host header because both of our applications will be running on the same Endpoint port which is 80. Therefore there has to be some way by which IIS can understand the request of user need to be served by which application. Therefore we need host header. The complete structure of my .csdef file is as shown below –

Now in reality my host header site “surveyapp.kunal.com” do not exists. Therefore to make survey app resolve to this URL I need to update “hosts” file of my machine. Hosts file is located at C:\Windows\System32\drivers\etc\hosts. I copied the file to desktop and opened in notepad and added an entry as highlighted below –
Then from desktop I replaced / copy-pasted the hosts file back to its location.
Now let’s run the project in debug mode by pressing F5 and it open the browser with management app with url similar to below – http://127.0.0.1:60123/ Here 60123 is port opened by my emulator, this will different in your case. Open another browser and cope the same url of management app and just replace 127.0.0.1 by our host header name i.e. surveyapp.kunal.com. So final url in new browser window will be - http://surveyapp.kunal.com:60123/and bingo!! I see my management app and survey app running on the same port as shown below –

Let’s run the same implementation in Full IIS and Full emulator mode. This can be configured from the cloud service project properties. To open the properties of cloud service project, right click on Cloud service project and select Properties.
Note – With Azure SDK 2.4 FULL Emulator has been deprecated; however I guess you should be able to run the Full IIS with Emulator Express. This is what I think!!
Ok, now let’s run the project by pressing Ctrl+F5 [DO NOT RUN in DEBUG MOE!!] and here is what I see in browser and IIS –

As you can see, host header has been applied for my Survey Application. This is how we can run multiple web application in single cloud service web role.
Advantage – You are running the tow different web apps in the same IIS. In other words you are running two different web applications in same instance of Azure role and hence you save money. In case of 2 different roles for 2 different web app, you will be charged for role VM instances of 2 applications. In this case you are charged for only one role VM instances.
Now in next part we will see how we can run these web applications over HTTPS and custom domain. This means, I have custom domain mapped for survey as “surveyapp.kunal.com” and now we will have custom domain name updated in hosts file for Management app as “managementapp.kunal.com” plus to run them on https and certificates.