Export (0) Print
Expand All

Enable Communication for Role Instances in Windows Azure

Updated: December 18, 2013

The role instances running in a cloud service in Windows Azure communicate through internal and external connections that vary depending on the type of communication that is needed. An external connection that is used to communicate with external clients is called an input endpoint, and an internal connection that is used to communicate with other role instances in the cloud service is called an internal endpoint. An input endpoint can connect by using a protocol of HTTP, HTTPS, or TCP. An internal endpoint can connect by using a protocol of HTTP or TCP. Endpoints are associated with IP addresses and ports, where the input endpoint is associated to a port that you define, and the internal endpoints are dynamically assigned ports by Windows Azure. You can statically assign the internal port to the same external port that is used by specifying the localPort attribute when defining the endpoints in the service definition.

A cloud service that is created in Windows Azure can be deployed into one of two different environments; a production environment and a staging environment. A service that is deployed in either of these environments has a DNS name and an IP address assigned to it. The DNS name that is associated with the production environment is assigned at runtime and is fixed for the lifetime of the service. The DNS name for the staging environment is dynamically generated each time a service is deployed. Each time that a service is deployed to one of these environments, the DNS name that is associated with it has an IP address assigned to it from a pool of available addresses. The IP address is kept until the service deployment is deleted. Upgrading your application, altering the configuration, or swapping the production and staging environments will not cause the IP address to change.

noteNote
The range of IP addresses that are used by Windows Azure can change. If you are setting up firewall polices or other IP based security, you should not use IP based filtering. You should use other security mechanisms that do not depend on IP address ranges.

Using input endpoints and internal endpoints

Input endpoints are used to communicate with role instances from outside of Windows Azure. Internal endpoints are used for internal role communication, for example, role-to-role communication. Each input endpoint defined for a role must listen on a unique port. The port that is defined for an input endpoint is used by the load balancer of Windows Azure to make your cloud service available on the Internet. The Windows Azure Fabric Controller assigns internal ports unless you use the localPort attribute in the service definition. When the Windows Azure Fabric Controller chooses the internal port number, you can discover it by using the following code example:

int port = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["EndPointName"].IPEndpoint.Port;

A maximum of 25 web role or worker role instances can be deployed to a cloud service and a maximum of 25 input endpoints can be distributed among the these instances. For example, a cloud service could have one web role or worker role instance running and have all 25 input endpoints defined for that role instance, or the cloud service could have 25 web role or worker role instances running that each use one endpoint. A cloud service can deploy a maximum of 50 Virtual Machines with a maximum of 150 endpoints.

You can define input endpoints for roles by adding an Endpoints element that contains InputEndpoint elements to the WebRole and WorkerRole elements in the service definition file. The InputEndpoint element defines the name, protocol, and port for the endpoint. For more information about these elements, see the Windows Azure Service Definition Schema (.csdef File). For setting up communication on deployments of Virtual Machines, see How to Set Up Endpoints to a Virtual Machine.

Add an input endpoint

  1. Open the ServiceDefinition.csdef file for your service in the text editor.

  2. Add the Endpoints element that contains an InputEndpoint element to the role element. The following example shows how to add an HTTP input endpoint for a web role that listens on port 80 and also defines the internal port of 80:

    
    <ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
      <WebRole name="WebRole1">
        <Endpoints>
          <InputEndpoint name="HttpIn" protocol="http" port="80" localPort="80" />
        </Endpoints>
      </WebRole>
    </ServiceDefinition>
    
    
    noteNote
    The localPort attribute is optional. If this attribute is not defined, the fabric assigns the internal port number at run time.

    The following example shows how to add a TCP input endpoint for a worker role that listens on port 10000.

     
    <ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
      <WorkerRole name="WorkerRole1">    
        <Endpoints>
          <InputEndpoint name="Endpoint1" protocol="tcp" port="10000" />
        </Endpoints>
      </WorkerRole>
    </ServiceDefinition>
    
  3. Set the name of the endpoint to the name that you want to use.

  4. Set the protocol to be the type of communication that you want to use. The possible choices are HTTP, HTTPS, or TCP.

  5. Specify the port number that you want to use for the role communication.

  6. Save the file.

You can define a maximum of 25 internal endpoints for roles by adding an Endpoints element that contains InternalEndpoints elements to the WebRole and WorkerRole elements in the service definition file. You can define up to 5 internal endpoints per role instance. For more information about these elements, see the Windows Azure Service Definition Schema (.csdef File).

Add an internal endpoint

  1. Open the ServiceDefinition.csdef file for your service in the text editor.

  2. For a web role, worker role or VM role, add the Endpoints element that contains InternalEndpoint elements to the WebRole element. The following example shows how to add an HTTP internal endpoint for a web role with a specified port number:

    
    <ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
      <WebRole name="WebRole1">
        <Endpoints>
          <InternalEndpoint name="InternalHttpIn" protocol="http" port="1000"/>
        </Endpoints>
      </WebRole>
    </ServiceDefinition>
    
    noteNote
    Port is optional. You can let Windows Azure assign the port number.

    The following example shows how to add a TCP internal endpoint for a worker role.

    
    <ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
      <WorkerRole name="WorkerRole1">
        <Endpoints>
          <InternalEndpoint name="Endpoint1" protocol="tcp" />
        </Endpoints>
      </WorkerRole>
    </ServiceDefinition>
    

    You can also optionally define a range of port numbers:

    
    <InternalEndpoint name="InternalPoint1" protocol="tcp">
      <FixedPortRange min="1000" max="2000" />
    </InternalEndpoint>
    
  3. Set the name of the endpoint to the name that you want to use.

  4. Set the protocol to be the type of communication that you want to use.

  5. Save the file.

You can define direct ports (instance input endpoints) for roles by adding an Endpoints element that contains InstanceInputEndpoints elements to the WebRole, WorkerRole, and VirtualMachineRole elements in the service definition file. For more information about these elements, see the Windows Azure Service Definition Schema (.csdef File). A direct port endpoint is used to communicate with load balanced role instances.

Add a direct port endpoint

  1. Open the ServiceDefinition.csdef file for your service in the text editor.

  2. For a web role, worker role or VM role, add the Endpoints element that contains InstanceInputEndpoint elements to the role element. The following example shows how to add a TCP direct port endpoint for a web role with a specified local port number and a range of public direct ports:

    
    <ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
      <WebRole name="WebRole1">
        <Endpoints>
          <InputEndpoint name=”Endpoint1” protocol=”http” port=”10101” localPort=”80” />
          <InstanceInputEndpoint name="Endpoint2" localPort="1000" protocol="tcp">
            <AllocatePublicPortFrom>
              <FixedPortRange min="10016" max="10020"/>
            </AllocatePublicPortFrom>
          </InstanceInputEndpoint>
        </Endpoints>
      </WebRole>
    </ServiceDefinition>
    
    ImportantImportant
    The XML shown in the previous example has an InputEndpoint element defined prior to the InstanceInputEndpoint (Direct Port) element. If not present, a schema configuration error will be generated and you will not be able to deploy your application. All web role services must have an HTTP/HTTPS endpoint defined as the first endpoint and if none is present, the Windows Azure Fabric will create one for you and this automatic creation process generates an error when an InstanceInputEndpoint is the first endpoint in the service definition. The Visual Studio user interface element that allows you to add endpoints without modifying the service definition XML file (.csdef) does not enforce this requirement.

    The following example shows how to add a TCP internal endpoint for a worker role with direct port public access.

    
    <ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
      <WorkerRole name="WorkerRole1">
        <Endpoints>
          <InstanceInputEndpoint name="InstanceInputEndpoint1" localPort="1000" protocol="tcp">
            <AllocatePublicPortFrom>
              <FixedPortRange min="10016" max="10020"/>
            </AllocatePublicPortFrom>
          </InstanceInputEndpoint>
        </Endpoints>
      </WorkerRole>
    </ServiceDefinition>
    
  3. Set the name of the endpoint to the name that you want to use.

  4. Set the protocol to be the type of communication that you want to use.

  5. Save the file.

The sample code shown below shows how to create a socket and listen for requests on your direct port endpoints from within a worker role.

WarningWarning
This code will only work for a deployed service. When running in the Windows Azure Compute Emulator, service configuration elements that create direct port endpoints (InstanceInputEndpoint elements) are ignored.


using System;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
 
namespace WorkerRole1
{
  public class WorkerRole : RoleEntryPoint
  {
    public override void Run()
    {
      try
      {
        // Initialize method-wide variables
        var epName = "Endpoint1";
        var roleInstance = RoleEnvironment.CurrentRoleInstance;
        
        // Identify direct communication port
        var myPublicEp = roleInstance.InstanceEndpoints[epName].PublicIPEndpoint;
        Trace.TraceInformation("IP:{0}, Port:{1}", myPublicEp.Address, myPublicEp.Port);
 
        // Identify public endpoint
        var myInternalEp = roleInstance.InstanceEndpoints[epName].IPEndpoint;
                
        // Create socket listener
        var listener = new Socket(
          myInternalEp.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                
        // Bind socket listener to internal endpoint and listen
        listener.Bind(myInternalEp);
        listener.Listen(10);
        Trace.TraceInformation("Listening on IP:{0},Port: {1}",
          myInternalEp.Address, myInternalEp.Port);
 
        while (true)
        {
          // Block the thread and wait for a client request
          Socket handler = listener.Accept();
          Trace.TraceInformation("Client request received.");
 
          // Define body of socket handler
          var handlerThread = new Thread(
            new ParameterizedThreadStart(h =>
            {
              var socket = h as Socket;
              Trace.TraceInformation("Local:{0} Remote{1}",
                socket.LocalEndPoint, socket.RemoteEndPoint);
 
              // Shut down and close socket
              socket.Shutdown(SocketShutdown.Both);
              socket.Close();
            }
          ));
 
          // Start socket handler on new thread
          handlerThread.Start(handler);
        }
      }
      catch (Exception e)
      {
        Trace.TraceError("Caught exception in run. Details: {0}", e);
      }
    }
 
    public override bool OnStart()
    {
      // Set the maximum number of concurrent connections 
      ServicePointManager.DefaultConnectionLimit = 12;
 
      // For information on handling configuration changes
      // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
      return base.OnStart();
    }
  }
}

Setting up network traffic rules to control role communication

After you define internal endpoints, you can add network traffic rules based on the endpoints that you created to control how role instances can communicate with each other. The following diagram shows some common scenarios for controlling role communication:

Network Traffic Rules Scenarios
  • Scenario 1 – Only allows network traffic from WebRole1 to WorkerRole1.

  • Scenario 2 – Only allows network traffic from WebRole1 to WorkerRole1 and WorkerRole2.

  • Scenario 3 – Only allows network traffic from WebRole1 to WorkerRole1, and WorkerRole1 to WorkerRole2.

  • Scenario 4 – Only allows network traffic from WebRole1 to WorkerRole1, WebRole1 to WorkerRole2, and WorkerRole1 to WorkerRole2.

The following code example shows role definitions for the roles shown in the previous diagram. Each role definition includes at least one internal endpoint defined:


<ServiceDefinition name="MyService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="WebRole1" vmsize="Medium"> 
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="HttpIn" endpointName="HttpIn" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
      <InternalEndpoint name="InternalTCP1" protocol="tcp" />
    </Endpoints>
  </WebRole>
  <WorkerRole name="WorkerRole1">
    <Endpoints>
      <InternalEndpoint name="InternalTCP2" protocol="tcp" />
    </Endpoints>
  </WorkerRole> 
  <WorkerRole name="WorkerRole2">
    <Endpoints>
      <InternalEndpoint name="InternalTCP3" protocol="tcp" />
      <InternalEndpoint name="InternalTCP4" protocol="tcp" />
    </Endpoints>
  </WorkerRole>
</ServiceDefinition>
noteNote
Restriction of communication between roles can occur with internal endpoints of both fixed and automatically assigned ports.

By default, after an internal endpoint is defined, communication can flow from any role to the internal endpoint of a role without any restrictions. To restrict communication, you must add a NetworkTrafficRules element to the ServiceDefinition element in the service definition file.

Control network traffic to role instances

  1. Open the ServiceDefinition.csdef file for your service in the text editor.

  2. Add the XML code to define the network traffic rules.

    • For Scenario 1, add the following code inside the ServiceDefinition element:

      
      <NetworkTrafficRules>
        <OnlyAllowTrafficTo>
          <Destinations>
            <RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
          </Destinations>
          <AllowAllTraffic/>
          <WhenSource matches="AnyRule">
            <FromRole roleName="WebRole1"/>
          </WhenSource>
        </OnlyAllowTrafficTo>
      </NetworkTrafficRules>
      
    • For Scenario 2, add the following code inside the ServiceDefinition element:

      
      <NetworkTrafficRules>
        <OnlyAllowTrafficTo>
          <Destinations>
            <RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
            <RoleEndpoint endpointName="InternalTCP3" roleName="WorkerRole2"/>
          </Destinations>
          <WhenSource matches="AnyRule">
            <FromRole roleName="WebRole1"/>
          </WhenSource>
        </OnlyAllowTrafficTo>
      </NetworkTrafficRules>
      
      
    • For Scenario 3, add the following code inside the ServiceDefinition element:

      
      <NetworkTrafficRules>
        <OnlyAllowTrafficTo>
          <Destinations>
            <RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
          </Destinations>
          <AllowAllTraffic/>
          <WhenSource matches="AnyRule">
            <FromRole roleName="WebRole1"/>
          </WhenSource>
        </OnlyAllowTrafficTo>
      </NetworkTrafficRules>
      <NetworkTrafficRules>
        <OnlyAllowTrafficTo>
          <Destinations>
            <RoleEndpoint endpointName="InternalTCP3" roleName="WorkerRole2"/>
          </Destinations>
          <WhenSource matches="AnyRule">
            <FromRole roleName="WorkerRole1"/>
          </WhenSource>
        </OnlyAllowTrafficTo>
      </NetworkTrafficRules>
      
      
    • For Scenario 4, add the following code inside the ServiceDefinition element:

      
      <NetworkTrafficRules>
        <OnlyAllowTrafficTo>
          <Destinations>
            <RoleEndpoint endpointName="InternalTCP2" roleName="WorkerRole1"/>
          </Destinations>
          <AllowAllTraffic/>
          <WhenSource matches="AnyRule">
            <FromRole roleName="WebRole1"/>
          </WhenSource>
        </OnlyAllowTrafficTo>
      </NetworkTrafficRules>
      <NetworkTrafficRules>
        <OnlyAllowTrafficTo >
          <Destinations>
            <RoleEndpoint endpointName="InternalTCP3" roleName="WorkerRole2"/>
          </Destinations>
          <AllowAllTraffic/>
          <WhenSource matches="AnyRule">
            <FromRole roleName="WorkerRole1"/>
          </WhenSource>
        </OnlyAllowTrafficTo>
      </NetworkTrafficRules> 
      <NetworkTrafficRules>
        <OnlyAllowTrafficTo >
          <Destinations>
            <RoleEndpoint endpointName="InternalTCP4" roleName="WorkerRole2"/>
          </Destinations>
          <AllowAllTraffic/>
          <WhenSource matches="AnyRule">
            <FromRole roleName="WebRole1"/>
          </WhenSource>
        </OnlyAllowTrafficTo>
      </NetworkTrafficRules>
      
      
  3. Save the file.

For more information about the elements that are used in the examples, see NetworkTrafficRules Schema.

Retrieve role instance data

The Windows Azure Managed Library provides methods for role instances to communicate at runtime. From code running within a role instance, you can retrieve information about the existence of other role instances and their endpoints, as well as information about the current role instance.

noteNote
You can only retrieve information about role instances that are running in your cloud service and that define at least one internal endpoint. You cannot obtain data about role instances running in a different service.

You can use the Instances property to retrieve instances of a role. First use the CurrentRoleInstance to return a reference to the current role instance, and then use the Role property to return a reference to the role itself.

The Instances property returns a collection of RoleInstance objects. This collection always contains the current instance. If the role does not define an internal endpoint, the collection includes the current instance but no other instances. The number of role instances in the collection will always be 1 in the case where no internal endpoint is defined for the role. If the role defines an internal endpoint, its instances are discoverable at runtime, and the number of instances in the collection will correspond to the number of instances specified for the role in the service configuration file.

noteNote
The Windows Azure Managed Library does not provide a means of determining the health of other role instances, but you can implement such health assessments yourself if your service needs this functionality. You can use Windows Azure Diagnostics to obtain information about running role instances. For more information about collecting diagnostic data, see Collect Logging Data by Using Windows Azure Diagnostics.

To determine the port number for an internal endpoint on a role instance, you can use the InstanceEndpoints property to return a Dictionary object that contains endpoint names and their corresponding IP addresses and ports. The IPEndpoint property returns the IP address and port for a specified endpoint. The PublicIPEndpoint property returns the port for a load balanced endpoint. The IP address portion of the PublicIPEndpoint property is not used.

Retrieve role instance data

  1. Open the source file that you want to use for retrieving role instance data.

  2. Add the code to iterate through the role instances. The following code example shows how to write out the identifier, port, and IP address information for role instances:

    
    foreach (RoleInstance roleInst in RoleEnvironment.CurrentRoleInstance.Role.Instances)
    {
       Trace.WriteLine("Instance ID: " + roleInst.Id);
       foreach (RoleInstanceEndpoint roleInstEndpoint in roleInst.InstanceEndpoints.Values)
       {
          Trace.WriteLine("Instance endpoint IP address and port: " + roleInstEndpoint.IPEndpoint);
       }
    }
    
  3. Save the file.

Show:
© 2014 Microsoft