Multiple sites within one Azure WebRole - azure

Goal:This is all about paying for one WebRole instance but demoing/testing multiple sites what are completely independent VS projects (ASP MVC 5, but this must not matter). Sites are differentiated not by port number instead domain (host) name)
Maybe I want too much, but this can be easily done using IIS by configuring IIS sites by host name (or IP, or port).
I understand (and can accept) that restriction, that these different VS projects must exist together in a VS solution, and can not deployed independently, I suppose a common Azure project exist which contains all configuration metainfo.
Tools: VS 2013 (Premium) and Azure tools 2.2
Now I have a solution with 2 projects in it:
MySite (an ASP MVC 5 project)
MySite.Azure
I would like to add a 2nd MVC project, and would like to modify config and other files in MySite.Azure to deploy both MySite and MySite2 and I would like to assign different hostname s to MySite and MySite2. (I do know how to assign my hostnames to my Azure IP using my DNS provider, please suppose that's already done)
If differentiating by host name is not possible, still is it possible to differentiate by port number?

Just to start from the top
You don't need all projects in a single solution but it does make it easier, so I will assume you will at this stage.
Add in your second project to your solution.
On your Azure project (MySite.Azure), on the Roles folder, Right Click and press Add > Web Role Project In Solution and add in the other project to your Azure project.
Next in your ServiceDefinition.csdef in the section
<Site>
<Site name="Site1" physicalDirectory="C:\Users\User\Documents\Visual Studio 2012\Projects\Project1">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" hostHeader="domain1.com" />
<Binding name="Endpoint2" endpointName="Endpoint2" hostHeader="domain1.com" />
</Bindings>
</Site>
<Site name="Site2" physicalDirectory="C:\Users\User\Documents\Visual Studio 2012\Projects\Project2">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" hostHeader="domain2.com" />
<Binding name="Endpoint2" endpointName="Endpoint2" hostHeader="domain2.com" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="80" />
<InputEndpoint name="Endpoint2" protocol="https" port="443" certificate="SSLName" />
</Endpoints>
This shows 2 endpoints as well for SSL usage.

Related

How can I publish an Azure Cloud Services project with multiple sites on a single service using Visual Studio Team Services?

I have a classic Cloud Services project that has multiple websites on a single service, configured in ServiceDefinition.csdef like so:
<WebRole name="PE.Roles.API" vmsize="Small">
<Sites>
<Site name="API" physicalDirectory="..\..\..\PE.Roles.API">
<Bindings>
<Binding name="http" endpointName="PE.API" />
</Bindings>
</Site>
<Site name="PE.Services.Authorization" physicalDirectory="..\..\..\PE.Services.Authorization">
<Bindings>
<Binding name="http" endpointName="PE.Services.Authorization" />
</Bindings>
</Site>
<!-- Etc -->
</Sites>
</WebRole>
This compiles and packages correctly in Visual Studio 2015, and deploys without a problem from a precompiled .cspkg file to the Cloud Service.
We have recently moved to Visual Studio Team Services for DevOps, and I'm trying to set this solution up to build and deploy in the cloud, using the provided Azure Cloud Services build template.
The .sln build step completes correctly, but the .ccproj build step fails with the following error:
PE.Azure\bin\ServiceDefinition.csdef (0, 0)
PE.Azure\bin\ServiceDefinition.csdef(0,0): Error CloudServices079: Cannot find the physical directory 'D:\a\1\PE.Roles.API' for virtual path API/.
Process 'msbuild.exe' exited with code '1'.
My build arguments are: /t:Publish /p:TargetProfile=$(targetProfile) /p:DebugType=None /p:SkipInvalidConfigurations=true /p:OutputPath=bin\ /p:PublishDir="$(build.artifactstagingdirectory)\\"
I've found a number of blog posts and SO questions covering similar issues, but nothing that addresses this precisely (and nothing posted in the last few years).
Update
I've created a TFVC repo for the project and implemented the mapping step, as suggested below:
...but I still get the same error:
What do I need to do to get this working?
You need to modify source mapping per to the setting of physicalDirectory.
Refer to this sample to modify it:
<Site name="API" physicalDirectory="..\..\..\WebGeneralDemo">
<Bindings>
<Binding name="http" endpointName="WebGeneralDemo" />
</Bindings>
</Site>
Update:
If these projects are in a git repository, you can keep the structure in repository like this:
-Repo
--AzureCloudServiceDemo
---AzureCloudServiceDemo
---WebRole1
--WebGeneralDemo
If the structure isn't like this, you can copy folders (include files) by using Copy file task
Update
In the case of this specific question, the original structure of the Repo was as follows:
... where the .ccproj file is in the PE.Azure folder, and the site being published is in the PE.Roles.API folder.
The compiler was looking for the site content in the directory one above the $(build.sourcesDirectory) (so D:\a\1\), so the correct Copy File task to fix the error was:
A Copy Files task was required for each site, and the tasks had to be positioned after the Build Solution ***.sln step, but before the Build Solution ***.ccproj step.

Azure WebRole - how do I remote debug when there is more than one site hosted as part of a WebRole?

I am deploying more than one website as part of a WebRole deployment in Azure. Example .csdef to illustrate what I mean:
<Sites>
<Site name="MySiteOne" physicalDirectory="../MySiteOne">
<Bindings>
<Binding name="HttpsIn" endpointName="HttpsIn" hostHeader="mysiteone.cloudapp.net" />
</Bindings>
</Site>
<Site name="MySiteTwo" physicalDirectory="../MySiteTwo">
<Bindings>
<Binding name="HttpsIn" endpointName="HttpsIn" hostHeader="mysitetwo.cloudapp.net" />
</Bindings>
</Site>
</Sites>
The deployment works fine and I have two sites set up in IIS as I would expect. However, I am unable to remote debug either site. Once they are both activated (i.e. have loaded from the initial request sent following deployment), I go to Remote Debug in Visual Studio. When I try to Attach to Process -> w3wp.exe there are actually 4 of these processes (2 sites x 2 instances) and I cannot select which one to debug. I cannot even do this by Trial & Error as the message that comes up is that there is more than one object to attach to.
Is it possible to remote debug multiple sites in Azure? Or will I need to deploy each site as a seperate WebRole/instance (and pay the cost to do this - thanks Microsoft) in order to do this?

This operation requires IIS integrated pipeline mode

After taking the updates from TFS i start getting this error, Some one suggest me to check the applicationhost file in Documents\IISExpress\config, I think its fine because i can see
<site name="EnviznServicesPlatformGlobal" id="15">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="E:\Dot Net\Timothylos\EnviznGlobalWeb\Test\LatestCode\EnviznGlobalWeb\EnviznServicesPlatformGlobal\EnviznServicesPlatformGlobal" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:1937:localhost" />
</bindings>
</site>
Here applicationPool is showing Clr4IntegratedAppPool mode which seems to be correct to me
I want to change the Manage pipeline mode to integrated like this images
but when i click on properties window i can just just see.
My question is how can i change the Managed Pipeline Mode to Integrated in VS2012?
If you are running an asp.net website you may need to R-click your project and select "Use IIS Express".
If it is a web application you'll need to go into your project's properties pages, select the Web tab then select "Use Local IIS Web server" and check "Use IIS Express".
I had an error (about not using integrated pipeline) which was solved in this way.

IIS express: Cannot add duplicate collection entry of type 'add' with unique key attribute 'name' set to

In Visual studio, Solution->Web.Project->Properties->Web, I have changed my Project Url from http://localhost:51123/ to http://localhost:51123/NewProjectName and I keep getting this error:
"Cannot add duplicate collection entry of type 'add' with unique key attribute 'name' set to ...." on every module added.
Adding a remove tag works but then it should have been a problem even before i changed the url. Any suggestions?
I think IIS Express probably has 2 <application>-blocks and both will be pointing to the same physicalPath.
Go to the IIS Express config file in: My Documents\IISExpress\config\applicationhost.config
Search for NewProjectName
Change the physicalPath for the root application to something else. Point it to an empty folder.
Should look something like this:
<site name="NewProjectName" id="1">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="c:\Temp" />
</application>
<application path="/NewProjectName" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="c:\sourcecode\NewProjectName" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:51123:localhost" />
</bindings>
</site>
Also, ensure you don't have a duplicate web.config file in one of the parent folders (eg: a web.config backup file). That was the issue with mine!
I started randomly getting this error. I noticed that the iis express had two sites.
This double layer is causing IIS to read the web.config from the first site and second at \WFM, therefore finding duplicates. I just stopped all the sites and removed the \WFM from my web project path. However you could go clear the files and folders from your temp file in IIS express. In my case I had multiple versions of the solution and one solution's project\user config had an extra path in the web project URL. VS 2015 added it, or someone checked in their own user config to TFS. Hope this helps others.
All web.config files work off multiple cascading levels of inheritance at the machine, IIS, project, and folder level locations, with each providing a higher degree of specificity.
If you're getting this error, it means you've either:
Added the same key twice in the same file (unlikely since you would've seen it)
The same key already exists in a separate file higher up the inheritance chain
There can be a lot of different root causes for #2, but if you want to side step them, you can just remove any previous declarations and then re-add your own at that level (I'd pay good money for an upsert feature).
So just add <remove> tags like this for any offending elements:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="ErrorLog" />
<remove name="ErrorMail" />
<remove name="ErrorFilter" />
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler" />
</modules>
</system.webServer>
If you create an IIS website with the physical path the same as the project folder, and then use it create a virtual folder for the project, you are going to see this issue.
Your Web.config file is being loaded twice.
Instead as orjanto pointed out, create an empty folder and point the IIS website to it and then use it to create a virtual folder from Visual Studio.
I had the same problem. It turned out that I had a different project that uses IISExpress with the same port number. Once I changed the project to use a different port number, the error went away.
What worked for me. I deleted the {projectFolderParent}/.vs/config (you have to "show hidden folders/files)
After deleting that, I restarted my computer.
My Project Url in Web tab inside project properties pointed to wrong url and I was not able to change it ("Would you like to create Virtual Directory?" and VS was locked in a loop (Yes -> Unable to create, No -> Operation Canceled) until I manually reverted Url to the (incorrect) state it was before. The solution was to run VS as Admin. I was able to change that url and everything started to work. Hope it helps!
You may find that after upgrading to the latest windows 10 service pack June 2017, this issue is because certain nodes seem to now appear under the root config (machine.config). I removed my duplicates from web.config and it all worked again.
I had a problem of same type. Running my site published on IIS, the same error was shown.
I saw a web.config file in the wwwroot folder (out of application folder).
I removed this file and the application ran OK.
Look for a web.config file placed in a wrong folder (above your folder application).
Good luck!
The answer that #orjanto posted solved the problem for me, but I had an additional problem on top of that. After fixing, Internet Explorer still thought that my HTML page was a directory instead of a file.
I had duplicates in my IIS Express config file:
<site name="MyAPI" id="56">
<application path="/" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\source\repos\MyAPI" />
</application>
<application path="/login.html" applicationPool="Clr4IntegratedAppPool">
<virtualDirectory path="/" physicalPath="C:\source\repos\MyAPI" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:57018:localhost" />
<binding protocol="https" bindingInformation="*:44302:localhost" />
</bindings>
</site>
Note the path="/login.html" in the second <application> entry.
My page was redirecting to "localhost:57018/login.html/" like it was a directory.
Removing the second entry fixed the problem with the configuration file duplicates, however I continued to have a problem where Internet Explorer seemed to think that /login.html/ was a directory (Internet Explorer 11). To diagnose the problem, I checked Chrome and Chrome worked fine.
I went into Internet Explorer, went to Tools > Internet Options > General Tab. Then under "Browsing History" section, I deleted History, Cookies and Website Data, & Temp. Internet Files.
I tried all of the above methods and nothing worked for me. I was keep on getting the error something like
Cannot add duplicate collection entry of type 'add' with unique key attribute 'name' set to 'QueryStringModule'
At last I changed my server from
IIS Express to Local IIS in the project property build as given below.
and it worked for me.
I had the same problem, here's what I did:
I changed my Server settings from Local IIS to IIS Express:
If it still doesn't work, I changed the port number to different port
number then click the Create Virtual Directory button. Clean the
solution then Rebuild.
Just Change the port number which is not yet used by another application and it works

Virtual application on Azure has RoleEnvironment.IsAvailable == false overnight

I have the following configuration in my Azure web role deployment :
<WebRole name="FrontOffice" vmsize="Small">
<Sites>
<Site name="Web">
<VirtualApplication name="mag_admin" physicalDirectory="../../Sites/BackOffice" />
<Bindings>
<Binding name="EndpointFrontOffice" endpointName="EndpointFrontOffice" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="EndpointFrontOffice" protocol="http" port="80" />
</Endpoints>
Which is, a FrontOffice MVC 3 web application and a BackOffice MVC 3 web application in a virtual directory (VirtualApplication).
I have upgraded to SDK 2.0 a couple of weeks ago, but stayed on StorageClient 1.7, since there are some breaking changes. Everything was OK for a while.
Last monday, all of sudden (and I checked and double-checked source control to be sure nobody changed the configuration), the BackOffice stopped working, because the "msshrtmi.dll" 1.7 file was missing. I think it used to be in the GAC (on my own machine it is) but was effectively missing on the Azure host (only 2.0 was present). I added the DLL in my web application references and it worked.
But now... that same web application complains it cannot connect to SQL Server because the connectionString is wrong. No wonder, it looks into web.config when it should look into the Azure ServiceConfiguration. We have a connectionString provider that checks if RoleEnvironment.IsAvailable returns true, in which case it will take the connectionString from ServiceConfiguration. And for the BackOffice, it now returns false. Everything works fine for the FrontOffice.
Does anyone knows if some changes have been made to Azure last week-end that could explain this sudden behavior?
I finally understand what happened.
When I upgraded to Azure SDK 2.0, it updated only the Azure web role project, not the web applications projects, which were still referencing the SDK 1.7 DLLs.
But no one noticed and it worked for a while. Lukos is probably right : Microsoft made some changes to their VMs, and the GAC now only contains the DLLs for 2.0 (since my deployment is targeting 2.0).
I made the necessary changes to my web applications (switching the DLLs) and now everything is fine.

Resources