Emil Craciun
Emil Craciun

Reputation: 11

How do I create an Internal Load Balancer in Azure for a Cloud Service (classic)?

I've been trying to wrap my head around creating an ILB for a cloud service containing a Web role and a Worker role (with at least 2 instances of each) and I'm stuck. This is the scenario I'm in.

The thing is that I do not want to use powershell because it doesn't fit my case and the research for a working example of a Service Definition and ServiceConfiguration file for the cloud project led me nowhere.

So, as per several sources that basically state the same thing (official documentation, I'll add other links in comments since I've reached the cap) I ended up with the following configuration files:

ServiceDefinition.csdef

<ServiceDefinition name="Test" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6">
    <WebRole name="Web" vmsize="small">...</WebRole>
    <WorkerRole name="Worker" vmsize="small">
        ...
        <Endpoints>
            <InputEndpoint name="lbEndpoint1" protocol="tcp" localPort="31010" port="31010" loadBalancer="TestILB" />
        </Endpoints>
    </WorkerRole>
</ServiceDefinition>

ServiceConfiguration.Cloud.cscfg

<ServiceConfiguration serviceName="Test" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="4" osVersion="*" schemaVersion="2015-04.2.6">
    <Role name="Web">...</Role>
    <Role name="Worker">...</Role>
    <NetworkConfiguration>
        <LoadBalancers>
            <LoadBalancer name="TestILB">
                <FrontendIPConfiguration type="private" subnet="Test-ILB-Subnet-Backend" staticVirtualNetworkIPAddress="10.0.0.1" />
            </LoadBalancer>
        </LoadBalancers>
    </NetworkConfiguration>
</ServiceConfiguration>

(The virtual network and subnet are already provisioned in Azure)

Now when I try to run the solution locally, the azure emulator stops with the following error: ".cscfg and .csdef do not match". Also deploying to Azure fails.

Can anyone help me and tell me what I'm doing wrong please?

Upvotes: 1

Views: 1350

Answers (2)

Emil Craciun
Emil Craciun

Reputation: 11

Ok so finally a lucky break! There is a slight confusion between the deployment model of VMs and classical cloud services in the official documentation. What needs to be done for each differs.

So in the case of cloud services, this wonderful example project did the trick.

There are two main things one needs to do:

  1. Provision a virtual network with subnets (you have a documentation page as a linked resource in the link above - Prerequisites section). This ended up a powershell script that basically checks if the vnet exists, and if not it just uses the following cmdlet:

    Set-AzureVNetConfig -ConfigurationPath [path_to_your_vnet_xml_config_file]
    
  2. Indeed the .cscfg and .csdef need the more extensive changes described in the example project. As a note, the input endpoints defined and connected to an ILB will become only visible to the ILB, thus they are not exposed to the outside world.

ServiceConfiguration.Cloud.cscfg:

<NetworkConfiguration>
    <!-- Doc: https://azure.microsoft.com/en-us/documentation/articles/virtual-networks-create-vnet-classic-netcfg-ps/ -->
    <VirtualNetworkSite name="VNET_NAME" />
    <AddressAssignments>
        <InstanceAddress roleName="Web">
            <Subnets>
            <Subnet name="Frontend" />
            </Subnets>
        </InstanceAddress>
        <InstanceAddress roleName="Worker">
            <Subnets>
            <Subnet name="Backend" />
            </Subnets>
        </InstanceAddress>
        <ReservedIPs>
            <ReservedIP name="RESERVED_IP" />
        </ReservedIPs>
    </AddressAssignments>
    <!-- Doc: https://github.com/Azure-Samples/cloud-services-dotnet-internal-load-balancer -->
    <LoadBalancers>
        <LoadBalancer name="testilb">
            <FrontendIPConfiguration type="private" subnet="Backend" />
        </LoadBalancer>
    </LoadBalancers>
</NetworkConfiguration>

ServiceDefinition.csdef:

<Endpoints>
      <!-- Doc: https://github.com/Azure-Samples/cloud-services-dotnet-internal-load-balancer -->
      <InputEndpoint name="OdbcEndpoint" protocol="tcp" port="31010" localPort="31010" loadBalancer="testilb" />
      <InputEndpoint name="HttpEndpoint" protocol="http" port="80" localPort="80" loadBalancer="testilb" />
</Endpoints>

Also as an important note when running the solution locally in the emulator, be sure to create a ServiceDefinition.Local.csdef with xdt transforms that remove the input endpoints. This gets rid of the error stating that the .cscfg and .csdef are not matching.

This has been quite a pain to get it right for my specific, but not uncommon, case.

Upvotes: 0

Marvin Dickhaus
Marvin Dickhaus

Reputation: 805

I encountered the same error today. The error message that you face probably also contains: If a deployment is not in a virtual network, any load balancer associated with this deployment cannot be in a virtual network. As the current deployment is not to a virtual network, please remove the subnet field for load balancer 'TestILB'

Removing the subnet and staticVirtualNetworkIPAddress fields in the .csdef file did the trick as far as the upload is concerned.

Executing Get-AzureService | Get-AzureInternalLoadBalancer returns the following

InternalLoadBalancerName : TestLoadBalancer
ServiceName              : Test
DeploymentName           : {GUID}
SubnetName               :
IPAddress                : 100.120.xx.xxx
OperationDescription     : Get-AzureInternalLoadBalancer
OperationId              : {GUID}
OperationStatus          : Succeeded

The Cloud Service displays two IPs in the Public IP adresses section now. One is an internal one in the 100.64.0.0/10 range. Strangely, this is not in the ILB IP Range (192.168.0.0/16) I specified.

Upvotes: 0

Related Questions