Azure@home Part 13: Remote Desktop Configuration

This post is part of a series diving into the implementation of the @home With Windows Azure project, which formed the basis of a webcast series by Developer Evangelists Brian Hitney and Jim O’Neil. Be sure to read the introductory post for the context of this and subsequent articles in the series.

As you likely know by now, the web and worker roles deployed as part of Azure@home, or as part of any Azure application for that matter, are ultimately hosted in a virtual machine (VM) running somewhere in the Azure data center that you selected for your application.  Until recently though, that was about all you knew.  The VMs are managed by the Azure fabric running through the data center - from the point you deploy your code, through upgrades, hardware failures, and operating system updates.  Sometimes though it would be great to take a look at your running application for monitoring, troubleshooting, or simply curiosity!

In this post, I’ll cover how to set up the deployment of an Azure application, specifically Azure@home, for remote desktop access, and in a follow-up post, I’ll take some time to poke around at live instances of the WebRole and WorkerRole within Azure@home.

Configuring the Application for Remote Desktop

Visual Studio Tooling Support

The easiest way to set up an application for Remote Desktop access is when you publish the Azure cloud service project from Visual Studio.  A link on the Deploy Windows Azure project dialog brings up a second dialog through which you can enable and configure Remote Desktop access.

Remote Desktop Configuration

Remote Desktop configuration requires installing a certificate in Windows Azure that will be associated with the hosted service (namely your deployed Azure application).  You can browse the certificates (in your Personal certificate store) via the dropdown list on the Remote Desktop Configuration dialog and select one, or just create a new one.

Certificates for Remote Desktop access require a KeySpec of AT_EXCHANGE versus AT_SIGNATURE.  If you are using the makecert utility, specify the –sky switch with a value of exchange (or 1).   Exchange keys can be used for signing and encrypted session key exchange, whereas signature keys are only for authentication (digital signing).  certutil is a great resource for peering into your certificate configurations and seems to provide more information than the Certificate Manager tool (certmgr.exe) or MMC plug-in (certmgr.msc).

If you elect to create a new certificate (via the last option in the certificate drop down list), you’ll be prompted for a friendly name.  Next, you specify a user name, password, and expiration date; these are used to set up a temporary account on the remote VM which you will be accessing.

Remote Desktop Configuration

The net effect of these modifications is to add configuration settings in both the ServiceDefinition.csdef and ServiceConfiguration.cscfg files associated with the Windows Azure cloud services project.  You can also make these modifications (detailed next) in the XML editor directly.

ServiceDefinition Modifications

In the definition file, module import directives are associated with each of the roles in the Azure application.  For Azure@home, the updated file looks like the following, with the highlighted lines indicating the additions.  

 <?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="AzureAtHome" upgradeDomainCount="2" xmlns="https://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="WebRole">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="HttpIn" endpointName="HttpIn" />
        </Bindings>
      </Site>
    </Sites>
    <ConfigurationSettings>
      <Setting name="DiagnosticsConnectionString" />
      <Setting name="DataConnectionString" />
    </ConfigurationSettings>
    <Endpoints>
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
    </Endpoints>
    <Imports>
      <Import moduleName="RemoteAccess" />
    </Imports>
  </WebRole>
  <WorkerRole name="WorkerRole">
    <ConfigurationSettings>
      <Setting name="DiagnosticsConnectionString" />
      <Setting name="DataConnectionString" />
      <Setting name="FoldingAtHome_EXE" />
      <Setting name="AzureAtHome_PollingInterval" />
      <Setting name="AzureAtHome_PingServer" />
    </ConfigurationSettings>
    <LocalResources>
      <LocalStorage name="FoldingClientStorage" cleanOnRoleRecycle="false" sizeInMB="1024" />
    </LocalResources>
    <Imports>
      <Import moduleName="RemoteAccess" />
      <Import moduleName="RemoteForwarder" />
    </Imports>
  </WorkerRole>
</ServiceDefinition>

Each role in the project imports a RemoteAccess module, which means every VM hosting an instance of those roles will be eligible for remote access.

Also, exactly one role in the project (here, the WorkerRole) imports the RemoteForwarder module.  The role marked as RemoteForwarder receives all of the Remote Desktop traffic that flows to the application and then routes it to the appropriate role instance.  You can mark an existing role as the RemoteForwarder or use a dedicated role (perhaps deployed on an extra-small instance) to better isolate the Remote Desktop traffic from your own application role instances.

ServiceConfiguration modifications

The ServiceConfiguration.cscfg file is likewise modified to contain specific values relating to the remote desktop access.  Below you can see new ConfigurationSettings corresponding to the remote account user name, password, and expiry.  Also included is a separate Certificates section to indicate the certificate used to exchange the account information via the Remote Desktop session.  Configuration for the WebRole is identical with the exception that there is no markup to enable the RemoteForwarder, since only one role in the Azure project needs to incorporate and enable this module.

   <Role name="WorkerRole">
    <Instances count="5" />
    <ConfigurationSettings>
      <Setting name="DiagnosticsConnectionString" value="DefaultEndpointsProtocol=https;AccountName=azureathome;AccountKey=REDACTED" />
      <Setting name="DataConnectionString" value="DefaultEndpointsProtocol=https;AccountName=azureathome;AccountKey=REDACTED" />
      <Setting name="FoldingAtHome_EXE" value="Folding@home-Win32-x86.exe" />
      <Setting name="AzureAtHome_PollingInterval" value="15" />
      <Setting name="AzureAtHome_PingServer" value="https://distributed.cloudapp.net" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled" value="true" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername" 
              value="jimoneil" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword" 
              value="REDACTED" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration" 
              value="2011-01-27T23:59:59.0000000-05:00" />
      <Setting name="Microsoft.WindowsAzure.Plugins.RemoteForwarder.Enabled" value="true" />
    </ConfigurationSettings>
    <Certificates>
      <Certificate name="Microsoft.WindowsAzure.Plugins.RemoteAccess.PasswordEncryption" 
                   thumbprint="REDACTED" 
                   thumbprintAlgorithm="sha1" />
    </Certificates>
  </Role>

If you only wish to expose one role for remote access, you can do so, but you have to modify the configuration file XML yourself.  In fact, if you change any of the Remote Desktop configuration values generated by Visual Studio (even flipping a value from true to false), when you subsequently click the Configure Remote Desktop connections… link in the Visual Studio publish dialog, you’ll get a message box indicating that the Remote Desktop configuration was not generated by Windows Azure Tools, and you must use the Xml editor to modify the configuration.

Deploy Windows Azure project dialogCreate Service Package

As the final step in Visual Studio, I’m opting to create the service package directly, via the Publish option.  As you might recall, this creates two files on the client machine, a .cspkg file and a copy of the .cscfg file, that you can then upload via the Windows Azure Management Portal into a new hosted service.

Alternatively, you can set up credentials on the client to deploy directly to Azure; however, to do so you must first set up a hosted service in the Azure portal and also install a management certificate to associate with your Windows Azure subscription.

In either case, the Remote Desktop Configuration aspect of the deployment remains the same as what we configured earlier in this article.

Configuring the Azure Service Deployment for Remote Desktop

In the Windows Azure Management portal (I’m using the new portal launched after PDC 10), you can deploy the package and configuration files and install the certificate required for remote desktop access in the same step.

Exporting the Remote Desktop Certificate

First though, you’ll need to export the certificate created above into a PKCS#12 formatted file stored on your local machine.  You can do that easily via the Certificate Export Wizard launched from the certmgr.msc MMC plugin, as shown in the short video clip below
(note: there is no audio).

Get Microsoft Silverlight

 

Deploying the Azure Service (and Certificate)

Now that you have the certificate file, service configuration document, and service package file on your development machine, you’re ready to deploy the service to Azure via the Windows Azure Management Portal.  You can browse to the two service files directly from the Create a new Hosted Service dialog (below) and of course, select the target data center region, service URL, and deployment type (staging or production). 

The Add Certificate button spawns a separate dialog (stylized below) via which you browse for the certificate file exported earlier and also supply the password that secures private key in the .pfx file (this is the same password you specified when exporting the certificate via the wizard in the previous step).

Creating a new service on Azure

Once the service has been deployed, you’ll see something along the lines of the following in the Windows Azure Management Portal.  Note that each of the individual role instances is represented; there are two instances of the Azure@home web role and five instances of the worker role in this deployment.  Also included below the highlighted service is the certificate we uploaded with the cloud application.

Azure@home deployed



Accessing an Instance via Remote Desktop

The Windows Azure Management Portal allows you to modify the Remote Desktop configuration as well as launch a Remote Desktop session.

Modifying Remote Desktop Configuration

When you select a Role node (not an instance node) in a deployment configured for Remote Desktop, the Enable checkbox and Configure option in the upper right of the Windows Azure Management Portal ribbon menu are enabled.  Choosing Configure brings up the dialog below to set the credentials for the Remote Desktop session as well as modify the certificate and expiration date (values we initially supplied in the Remote Desktop Configuration dialog in Visual Studio)

Remote Desktop configuration in the Windows Azure portal

Connecting via Remote Desktop

To connect via Remote Desktop to a specific instance running in the Azure data center, select a node instance, and then press the Connect button in the upper right of the portal’s ribbon menu, as shown below:

Launching Remote Desktop from the Windows Azure portal

You’ll be prompted to access a file with a .rdp extension that’s downloaded on your behalf; press Open, then Allow, and finally Connect if and when prompted; you can elect not to be prompted again on subsequent connection attempts.

Prompt to Open/Save Remote Desktop file      Prompt to allow Remote Desktop access 

 Prompt to confirm trust

Tip: save the .RDP file locally and you can bypass the Windows Azure Management Portal whenever you want to Remote Desktop in to the VM instance again.

Remote Desktop loginWhen you press Connect on this final dialog (which is noting, as we’d expect, that the self-signed certificate provided cannot be verified), the Remote Desktop session starts up, prompting you for your credentials (see right), namely the user name and password you specified in the Visual Studio Remote Desktop Configuration dialog at the outset (or that you perhaps modified via the Windows Azure Management Portal).

Once you have supplied valid credentials, you should be logged in to the VM instance hosting the selected role, like below!  If it’s the first time you’ve accessed this VM, you’ll see that your user account is first configured – as it would be for any new user on a Windows system.  Once that’s done (and presuming the VM has not restarted), on subsequent logins you’ll be able to resume whatever you were doing in your last session.

Remote Desktop session to Azure instance

At this point the VM is yours to explore, and that’s where we’ll pick up things on the next post in this series.