1
votes

I currently have an Azure cloud service with a web role (so it's a virtual machine with IIS installed on it). This web role currently runs an unique web application (WebAPI project).

What I'm trying to do is to create a new web application, but I need it to run on the same web role (i.e. two applications on the same virtual machine) to reduce the costs. I know it's possible (both web application will then run on the same IIS instance, on the same machine, with different ports) but I can't find resources about how to do it with a recent version of the Azure SDK.

I found great resources :

but all are a bit old (<= 2013) and don't apply anymore.

I'm currently using the Azure SDK 2.6. I've tried modifying my ccproj file (Cloud Service project file) so both WebAPI project share the same RoleName:

<ProjectReference Include="..\MyProject1.csproj">
  <Name>Website</Name>
  <Project>{...}</Project>
  <Private>True</Private>
  <RoleType>Web</RoleType>
  <RoleName>MyRole</RoleName>
</ProjectReference>
<ProjectReference Include="..\MyProject2.csproj">
  <Name>Website</Name>
  <Project>{...}</Project>
  <Private>True</Private>
  <RoleType>Web</RoleType>
  <RoleName>MyRole</RoleName>
</ProjectReference>

This doesn't work, the "roles" node of my project within Visual Studio shows an error ("no project associated [project 2 name]).

I've also tried to modify my ServiceDefinition.csdef file:

<WebRole name="xxxx.Frontend.Azure" vmsize="Small">
    <Sites>
        <Site name="Web">
            <Bindings>
                <Binding name="Endpoint1" endpointName="Endpoint1" />
            </Bindings>
        </Site>
        <Site name="AnotherWeb" physicalDirectory="foo">
            <Bindings>
                <Binding name="Endpoint2" endpointName="Endpoint2" />
            </Bindings>
        </Site>
    </Sites>
    <Endpoints>
        <InputEndpoint name="Endpoint1" protocol="http" port="8080" />
        <InputEndpoint name="Endpoint2" protocol="http" port="8090" />
    </Endpoints>
</WebRole>

No luck either.

How should I proceed?


EDIT :

Here's my current csdef file with modification for multiple sites support:

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="AzureCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6">
  <WebRole name="XXX.YYY" vmsize="Small">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="Endpoint1" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="http" port="80" />
    </Endpoints>
    <Imports>
      <Import moduleName="RemoteAccess" />
    </Imports>
  </WebRole>
  <WebRole name="XXX.ZZZ" vmsize="Small">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="Endpoint1" />
        </Bindings>
      </Site>
      <Site name="ZZZ" physicalDirectory="..\..\..\XXX.ZZZ\azure.publish">
        <Bindings>
          <Binding name="Endpoint2" endpointName="Endpoint2" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="http" port="8081" />
      <InputEndpoint name="Endpoint2" protocol="http" port="8090" />
    </Endpoints>
    <Imports>
      <Import moduleName="RemoteAccess" />
    </Imports>
  </WebRole>
</ServiceDefinition>
2

2 Answers

3
votes

I think you're on the right track with the csdef file changes, and the wrong track with the ccproj changes. So get rid of your second ProjectReference, since you just want one WebRole at the end of the day.

What you should do in the ccproj file is add a line like this:

<MSBuild Projects="..\MyProject2\MyProject2.csproj" ContinueOnError="false" Targets="PublishToFileSystem" Properties="Configuration=$(Configuration);PublishDestination=..\Publish\MyProject2\;AutoParameterizationWebConfigConnectionStrings=False" />

Obviously that has fake paths, but what's important is that you make sure the path to the csproj file is valid, and make sure that the PublishDestination path matches the PhysicalDirectory path you're specifying for that Site in the csdef file, and note that the PhysicalDirectory path and the PublishDestination path are not relative to the same location. For example, we keep a "Publish" directory in the solution root, so for us the PublishDestination looks like

..\Publish\MyProject2\ 

and the physicalDirectory looks like

..\..\..\Publish\MyProject2

Your endpoint configurations look correct, but if a role isn't accessible remotely, make sure that your csdef file has a line in Endpoints:

    <Endpoints>
        <InputEndpoint name="MyProject1Endpoint" protocol="http" port="80" />
        <InputEndpoint name="MyProject2Endpoint" protocol="http" port="8080" />
    </Endpoints>

...with a "name" that corresponds to the endpointName of each Site:

    <Sites>
        <Site name="MyProject1Site" physicalDirectory="..\..\..\MyProject1">
            <Bindings>
                <Binding name="MyProject1Binding" endpointName="MyProject1Endpoint" />
            </Bindings>
        </Site>
        <Site name="MyProject2Site" physicalDirectory="..\..\..\Publish\MyProject2">
            <Bindings>
                <Binding name="MyProject2Binding" endpointName="MyProject2Endpoint" />
            </Bindings>
        </Site>
    </Sites>

That's assuming you want each site publicly accessible on the same port it's hosted on. If, for some reason, MyProject2 were running locally on port 8081, you'd add localPort="8081" to that InputEndpoint.

0
votes

If you can deploy the app as an Azure Web App instead, I would highly recommend it. It is designed to handle this scenario really well. You can create an App Service Plan with however many server instances you need and then multiple apps share that group of servers.