Installing an Exchange 2010 Test Environment on Windows Azure (Part 2)

If you would like to read the first part in this article series please go to Installing an Exchange 2010 Test Environment on Windows Azure (Part 1).

Disclaimer

Image

The following article details a configuration which is not officially supported by Microsoft for Production Environments. You can read the official documentation about supported workloads at the following link: Microsoft server software support for Windows Azure Virtual Machines.

1.    Install Exchange Server 2010

Installing Exchange Server is probably the easiest part, since there are no significant differences from installing Exchange on any virtual machine, on any virtualization system.

After downloading Microsoft Exchange Server 2010 Service Pack 2 and saving it to the Exchange virtual machine, I just had to run Setup (Figure 24). All the Readiness Checks were completed and the only warning was that the AD Forest was going to be prepared for Exchange Server 2010 (Figure 25), as expected.

The complete setup process, for a typical Exchange Server 2010 installation (CAS, Hub and Mailbox) took only a little bit more than half an hour (Figure 26).

The latest Update Rollup was installed (Figure 27) and, after that, all the services came up without any glitch (Figure 28). We even have Outlook Web App available, since we opened the necessary endpoints, by accessing the URL https://az-e2k10.cloudapp.net/owa (Figure 29).

Image
Figure 24: Launching Exchange Server 2010 SP2 Setup

Image
Figure 25: Exchange Server 2010 Setup: Readiness Checks

Image
Figure 26: Exchange Server 2010 Setup: Completion

Image
Figure 27: Exchange Server 2010 SP2 Update Rollup 5-v2

Image
Figure 28: Microsoft Exchange services

Image
Figure 29: Outlook Web App

Performance Notes

After installing Exchange Server 2010, I moved the Database and Logs to the 2 data disks that were created (Figure 30).

Image
Figure 30: Move Database Path

Since this is just for test purposes, performance shouldn’t be a problem. Nevertheless, and just for academic reasons, we’ll discuss the performance impact of the cache policy on the data disks, considering that we’ll use them to store the Exchange Databases and logs.

The Virtual Machine operating system disk and data disks have a host caching setting that enables improved performance under some circumstances. However, these settings can also negatively affect performance in other circumstances, depending on the application. Host caching is OFF by default for both read operations and write operations for data disks. Host-caching is ON by default for write operations for operating system disks.

When deploying a Virtual Machine, the OS disk has two host caching choices:

  • Read/Write (Default) – write back cache
  • Read – write through cache

When you setup a data disk on a virtual machine, you get three host caching choices:

  • Read/Write – write back cache
  • Read – write through cache
  • None (Default)

The type of cache to use for data disks and the OS disk is not currently exposed through the portal. To set the type of host caching, you must either use Powershell commands Add-AzureDataDisk or Set-AzureDataDisk.

Using the read cache will improve sequential IO read performance when the reads ‘hit’ the cache. The cache’s size for a disk varies based on instance size and the number of disks mounted. Caching can only be enabled for up to four data disks.

If you noticed, when we created the Exchange virtual machine using the PowerShell script, we defined the cache policy of the data disks as ReadOnly, which translates to Read/Write-Through cache. According to some technical literature, this should be the best configuration for Exchange databases, but since there are no certainties until we prove that, I strongly advise you to run a tool like JetStress (if that really matters for a test environment).

As for CPU and memory, we must use one of the available machine sizes that go from Extra Small to Extra Large (8-core, 14GB RAM). As you can infer, with these hardware figures, we could hardly run an Exchange production server for a mid-size organization. Let’s wait for the General Availability of Virtual Machines to see if new machine sizes will be provided, and hope that Exchange Server will be supported by then.

Bring Your Own Servers

Most probably, you already have some kind of test environment with Exchange Server. Whether you’re using Hyper-V or a different virtualization technology, you can just upload those virtual machines to Windows Azure, provided there are some required steps to be followed.

The requirements to upload your virtual machines to Windows Azure are:

  • VHD format: only Hyper-V VHD format is supported (VHDx it’s not supported at this time). If you are using Vmware, Microsoft provides a tool to automate the conversion of the .VMDK disks to VHD: Virtual Machine Converter Solution Accelerator.
  • Enable Remote Access: without Remote Access enabled you’ll never be able to connect to the server.
  • Static VHD: dynamic VHDs are not supported. If you use the CSUpload tool, it will convert the disk to static during the upload process.
  • DHCP only: static IP addresses are not supported.
  • OS Version: only Windows Server 2008 R2 and Windows Server 2012 are supported.

When you are uploading your VHD into storage, you will want to use a tool that only uploads the portions of the VHD that have actual data in them. Also, if you have dynamic VHDs, you want to use a tool that will convert your dynamic VHD into a fixed VHD as it is doing the upload. CSUpload will do both of these things for you, and it is included as part of the Windows Azure SDK (WindowsAzureAuthoringTools).

To upload a VHD using CSUpload, follow these steps:

  1. You must set the connection string that is used to access the subscription. Open a Command Prompt window as an administrator. CSUpload can be found in the C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\<sdk-version>\bin folder. Set the connection string by using the following command and replacing Subscriptionid and CertThumbprint with the values for your Windows Azure subscription:
    csupload Set-Connection “SubscriptionID=<Subscriptionid>;CertificateThumbprint=<Thumbprint>;
    ServiceManagementEndpoint=https://management.core.windows.net”
  2. Upload the VHD file by using the following command and replacing Subscriptionid and CertThumbprint with your specific values:
    csupload Add-PersistentVMImage -Destination “<BlobStorageURL>/<YourImagesFolder>/<VHDName>” -Label <VHDName> -LiteralPath <PathToVHDFile> -OS WindowsWhere BlobStorageURL is the URL for the storage account that you created earlier. You can check the BlobStorageURL by clicking the storage account created (e2k10), and then clicking CONTAINERS (Figure 31). You can place the VHD file anywhere within your Blog storage. YourImagesFolder is the container within blob storage where you want to store your images. VHDName is the label that appears in the Management Portal to identify the VHD. PathToVHDFile is the full path and name of the VHD file.
  3. After uploading your own images, creating virtual machines can be done using the Management Portal, just like we did with the Domain Controller (the uploaded images will appear in the Gallery), or by using PowerShell, just like we did with the Exchange server.

Image
Figure 31: Blob storage URL

Automating the Provisioning of the Whole Environment

Although it can be fun and fast to provision this test environment with only 2 servers, for more complex scenarios with more servers, one may ask for an automated way of provisioning and configuring the whole Exchange Server infrastructure.

In Windows Azure you only pay what you are using. This means that, if you want to save some money, you can deprovision the virtual machines (keeping the VHDs) and thus you’ll not be charged on compute resources. With the power of PowerShell cmdlets, we can come up with a script that will mount all the necessary servers in just minutes.

To demonstrate a complete automation of such provisioning method, I deleted the 2 virtual machines created in this article (DC and Exchange Server), keeping the VHDs, and also removed the Virtual Network configuration. But before deleting the VNet configuration, I exported the configuration to a .XML file, by going to the NETWORKS section and then clicking EXPORT (Figure 32).

By browsing to the DISKS section of the VIRTUAL MACHINES we can see the unattached available disks (Figure 33). There are 2 OS Disks and 2 Data Disks, as expected.

Image
Figure 32: Export network configuration

Image
Figure 33: Windows Azure disks

There are 3 necessary scripts and 1 configuration file to automatically provision all the required resources:

  • MASTER.PS1 – this is just the orchestrator script that connects to the Windows Azure subscription and then launches the other 2 scripts.
  • CREATE-VNET.PS1 – creates the affinity group and the virtual network configuration with all the subnets.
  • PROVISION-DC-E2K10.PS1 – creates the necessary cloud services and provisions the 2 virtual machines, domain controller and Exchange server.
  • E2K10-VNET.XML – configuration file for the virtual network (previously exported).

MASTER.PS1

Import-AzurePublishSettingsFile 'C:\Temp\e2k10-demo\MSExchange.org-credentials.publishsettings'
Set-AzureSubscription -SubscriptionName 'MSExchange.org' -CurrentStorageAccount 'e2k10'

Invoke-Expression C:\Temp\e2k10-demo\create-vnet.ps1
Invoke-Expression C:\Temp\e2k10-demo\provision-dc-e2k10.ps1

CREATE-VNET.PS1

# Create Exchange Virtual Network

CLS

# Affinity Group parameters
$AGLocation = "North Europe"
$AGDesc = "Exchange Affinity Group"
$AGName = "e2k10-ag"
$AGLabel = "e2k10-ag"

# Create a new affinity Group
New-AzureAffinityGroup -Location $AGLocation -Description $AGDesc `
                                        -Name $AGName -Label $AGLabel

# Clear current settings
Remove-AzureVNetConfig -ErrorAction SilentlyContinue

# Apply new network
$configPath = (Split-Path -Path $MyInvocation.MyCommand.Definition -Parent) `
                    + "\E2K10-VNET.xml"

Set-AzureVNetConfig -ConfigurationPath $configPath

PROVISION-DC-E2K10.PS1

# Provision Exchange Server Test Environment

CLS

# Cloud Service Paramaters
$dcServiceName = "az-dc"
$dcServiceLabel = "az-dc"
$dcServiceDesc = "Cloud Service for DC"
$e2k10ServiceName = "az-e2k10"
$e2k10ServiceLabel = "az-e2k10"
$e2k10ServiceDesc = "Cloud Service for Exchange Server 2010"

# Disks
$e2k10disk= 'az-e2k10-AZ-E2K10-01-0-20121215171608'
$e2k10datadisk1= 'az-e2k10-AZ-E2K10-01-0-20121215171610'
$e2k10datadisk2= 'az-e2k10-AZ-E2K10-01-1-20121216115442'
$dcdisk= 'AZ-DC-01-AZ-DC-01-0-20121215161247'

#Network Settings
$vnetname = 'e2k10-vnet'
$e2k10SubnetName = 'E2K10-Subnet'
$dcSubnetName = 'DC-Subnet'
$ag = 'e2k10-ag'
$primaryDNS = '10.10.10.4'

# Availability Sets
$avsete2k10 = 'e2k10-as'

## Create DC Configuration
$dcsize = 'Small'
$dc1 = New-AzureVMConfig -Name 'AZ-DC-01' -AvailabilitySetName $avsete2k10 `
        -InstanceSize $dcsize -DiskName $dcdisk |
    Add-AzureEndpoint -Name 'RemoteDesktop' -LocalPort 3389 -PublicPort 3389 -Protocol tcp |
    Set-AzureSubnet -SubnetNames $dcSubnetName

## Create Exchange Server Configuration
$e2k10size = "Medium"
$e2k10 = New-AzureVMConfig -Name 'AZ-E2K10-01' -AvailabilitySetName $avsete2k10 `
            -DiskName $e2k10disk -InstanceSize $e2k10size |
        Add-AzureDataDisk -Import -DiskName $e2k10datadisk1 -LUN 0 -HostCaching ReadOnly |
        Add-AzureDataDisk -Import -DiskName $e2k10datadisk2 -LUN 1 -HostCaching ReadOnly |
        Add-AzureEndpoint -Name 'smtp' -LocalPort 25 -PublicPort 25 -Protocol tcp |
        Add-AzureEndpoint -Name 'http' -LocalPort 80 -PublicPort 80 -Protocol tcp |
        Add-AzureEndpoint -Name 'https' -LocalPort 443 -PublicPort 443 -Protocol tcp |
        Add-AzureEndpoint -Name 'RemoteDesktop' -LocalPort 3389 -PublicPort 3389 -Protocol tcp |
        Set-AzureSubnet $e2k10SubnetName

$dns1 = New-AzureDns -Name 'E2K10-DNS' -IPAddress $primaryDNS

## Create DC
New-AzureVM -ServiceName $dcServiceName -ServiceLabel $dcServiceLabel -ServiceDescription $dcServiceDesc `
                        -AffinityGroup $ag -VNetName $vnetname -VMs $dc1

Start-AzureVM -ServiceName $dcServiceName -Name 'AZ-DC-01'


## Create Exchange Server
New-AzureVM -ServiceName $e2k10serviceName -ServiceLabel $e2k10serviceLabel `
            -ServiceDescription $e2k10serviceDesc -Verbose `
            -AffinityGroup $ag -VNetName $vnetname -DnsSettings $dns1 `
            -VMs $e2k10

Start-AzureVM -ServiceName $e2k10ServiceName -Name 'AZ-E2K10-01'

E2K10-VNET.XML

<NetworkConfiguration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/ServiceHosting/2011/07/NetworkConfiguration">
  <VirtualNetworkConfiguration>
    <Dns />
    <VirtualNetworkSites>
      <VirtualNetworkSite name="e2k10-vnet" AffinityGroup="e2k10-ag">
        <AddressSpace>
          <AddressPrefix>10.10.0.0/16</AddressPrefix>
        </AddressSpace>
        <Subnets>
          <Subnet name="DC-Subnet">
            <AddressPrefix>10.10.10.0/24</AddressPrefix>
          </Subnet>
          <Subnet name="E2K10-Subnet">
            <AddressPrefix>10.10.11.0/24</AddressPrefix>
          </Subnet>
        </Subnets>
      </VirtualNetworkSite>
    </VirtualNetworkSites>
  </VirtualNetworkConfiguration>
</NetworkConfiguration>

The total time to provision the environment was 5 minutes. What else does it take to convince you to move your test environment to the cloud?

More Complex Scenarios

There are a couple of more advanced scenarios where Windows Azure could be used

  • Configuring a DAG: I didn’t test this scenario, creating an Exchange DAG in Windows Azure. From a technical perspective, although there are some limitations at the network level, it might work. I’ll probably test it in my next article, where I’ll cover this very same topic, but with Exchange Server 2013. Stay tuned!
  • Disaster Recovery/Hybrid Scenario: imagine that you configure locally an Exchange DAG and would like to have one node on Windows Azure for disaster recovery purposes. Please keep in mind that Exchange is not supported on Windows Azure, but for academic purposes this could be an interesting scenario, as long as the maximum latency between nodes is below the supported threshold. And who knows, if in the future Microsoft supports Exchange on Windows Azure, it may become one of the most popular hybrid scenarios involving Exchange Server.

If you would like to have all your Production Exchange servers in the cloud, even if that was supported, I don’t think it’s a good fit for Windows Azure. Let’s face it, if you are willing to go 100% cloud, then why not migrate to Office 365? Exchange Online has practically all the features of Exchange on-premises, and the Software as a Service (SaaS) model has way more benefits than running Exchange on the IaaS model.

Conclusion

The cloud is here to stay, all the analysts say it and more and more companies are embracing the SaaS, PaaS or the IaaS model. IaaS with Windows Azure can be used (and it’s supported) with several Microsoft server software. Unfortunately, Exchange Server it’s not supported and nobody can tell if it will ever be supported. Nevertheless, for test environments or for academic/training purposes Windows Azure provides that kind of agility, performance and cost savings that make it ideal for running these scenarios.

Related Links

If you would like to read the first part in this article series please go to Installing an Exchange 2010 Test Environment on Windows Azure (Part 1).

About The Author

Leave a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Scroll to Top