As of Windows Azure SDK 1.7, Microsoft has enabled us to connect a cloud service with a virtual machine in Windows Azure. Now that the general availability of Windows Azure Infrastructure Services has been announced, Microsoft also supports it.
The common scenario for this is connecting from a public ASP.NET web application that is running in a cloud service to a private SQL Server database that is running in a virtual machine via a virtual network. This post walks you through how to deploy this scenario.
Create the virtual network
The first step is to create a virtual network.
For information about how to create this virtual network, see the Create a Virtual Network in Windows Azure tutorial.
This tutorial creates a cloud-only virtual network, but you can also create a point-to-site virtual network (see the Configure a Point-to-Site VPN in the Management Portal article) or a site-to-site virtual network (see the Create a Virtual Network for Site-to-Site Cross-Premises Connectivity tutorial) if you must connect with an on-premises resource such as Active Directory, a DNS server, or similar.
The tutorial creates the YourVirtualNetwork virtual network that has an address space with the following two subnets:
- FrontEndSubnet, which will host the web role running the public ASP.NET web application
- BackEndSubnet, which will host the virtual machine running the private SQL Server database
Create the virtual machine
The next step is to create a virtual machine that is to host the private SQL Server database.
For information about how to create this virtual machine, see the Provisioning a SQL Server Virtual Machine on Windows Azure tutorial.
This tutorial creates a virtual machine using a pre-built SQL Server virtual machine image from the Windows Azure virtual machine gallery, but you can also create one using a “pre-owned” virtual machine image from an on-premises virtual machine template.
A few notes about the tutorial:
- When creating the virtual machine, on the Virtual machine mode page, in the REGION/AFFINITY GROUP/VIRTUAL NETWORK box, select the YourVirtualNetwork virtual network that was created in the previous step and in the VIRTUAL NETWORK SUBNETS box, select the BackEndSubnet subnet that was also created in the previous step.
- After the virtual machine is provisioned, you don’t have to create a TCP endpoint for the virtual machine unless you must connect to it from the public network (which isn’t required for this walkthrough since we are connecting from a web role to the virtual machine via a private network).
- If the virtual network that was created in the previous step wasn’t provisioned with either a public DNS server or an on-premises one, determine the IP address of the virtual machine by running the ipconfig.exe command-line tool.
- After the database engine has been setup, you can deploy the SQL Server database to it.
Deploy the cloud service
The last step is to deploy a cloud service that is to host the public ASP.NET web application.
To connect from the cloud service to the virtual machine via the virtual network , the NetworkConfiguration element must be added to the service configuration file for the cloud service.
The NetworkConfiguration element, which describes the network configuration into which the cloud service is to be deployed, includes the following sub-elements:
- Dns element: Specifies the DNS server(s) to be used by the cloud service.
- VirtualNetworkSite element: Determines the virtual network to which the cloud service is to be deployed.
- AddressAssignments element: Configures mappings from roles for the cloud service to subnets for the virtual network.
To connect the cloud service with the virtual machine in Windows Azure, you must modify both the service configuration for the cloud service and the connection string for the ASP.NET web application.
Service configuration
To connect from the cloud service to the virtual machine via the virtual network, you must add the VirtualNetworkSite and AddressAssignments elements to the service configuration for the cloud service as follows:
[code language=”xml”]
<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration …>
<Role name="WebRole1">
…
</Role>
<NetworkConfiguration>
<VirtualNetworkSite name="YourVirtualNetwork" />
<AddressAssignments>
<InstanceAddress roleName="WebRole1">
<Subnets>
<Subnet name="FrontEndSubnet" />
</Subnets>
</InstanceAddress>
</AddressAssignments>
</NetworkConfiguration>
</ServiceConfiguration>
[/code]
This service configuration deploys the cloud service to the YourVirtualNetwork virtual network and maps the web role to the FrondEndSubnet subnet.
You can only deploy a cloud service to a single virtual network, but you can map a role to multiple subnets, which allows the role to be assigned an IP address from the next subnet if the previous one doesn’t have any more IP addresses when a new instance for the role is created.
If the virtual network that was created in the first step was provisioned with a DNS server, you must also add the Dns element to to the service configuration as follows:
[code language=”xml”]
<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration …>
<Role name="WebRole1">
…
</Role>
<NetworkConfiguration>
<Dns>
<DnsServers>
<DnsServer name="YourDns" IPAddress="10.4.3.1" />
</DnsServers>
</Dns>
<VirtualNetworkSite name="YourVirtualNetwork" />
<AddressAssignments>
<InstanceAddress roleName="WebRole1">
<Subnets>
<Subnet name="FrontEndSubnet" />
</Subnets>
</InstanceAddress>
</AddressAssignments>
</NetworkConfiguration>
</ServiceConfiguration>
[/code]
Connection string
To connect from the public ASP.NET web application to the private SQL Server database, modify the connection string for the ASP.NET web application as follows:
[code]
connectionString="Server{DnsNameOrIPAddressOfVirtualMachine};Integrated Security=false;User ID={LoginUserName};Password={LoginPassword};" providerName="System.Data.SqlClient"
[/code]
Run the ASP.NET web application and it should connect with the SQL Server database!
Thanks a bunch for your post. It gave me a lot of information I needed.
One thing I couldn’t figure out is why you wanted to two separate subnets. Wouldn’t it be even easier to put all of the servers on the same private subnet? I didn’t see the reason for separating public and private subnets.
Brian – it was just by way of demonstration for this blog post. One item to note, however, is that if you enable auto-scale on Cloud Services they will utilise the next free IP address they can so if you put all your machines onto the same subnet they you’ll have little control of IP allocation. By putting Cloud Services into their own subnet you can guarantee that their IP addresses will only be issued from a certain subnet range. HTH.
Thanks Simon. That makes sense.