A deep dive into Azure RemoteApp

Azure RemoteApp is a service from Microsoft which brings scale and agility to your business applications. This service provides global access to your corporate applications from anywhere and at any time. On 11th of December RemoteApp became general available so it is time to give an overview and some hands-on experience on this new azure service.

RemoteApp is designed based on the already existing service Remote Desktop Services (RDS) which you can add to a Windows Server 2012 installation. RemoteApp still requires some of the RDS components to actually run and to provide access to Windows applications in the cloud. I will come back on this details later on in this blog.

Scalability and cost-effectiveness are the main advances of RemoteApp as a part of the Azure Cloud Platform. It is scalable because you can scale up very quickly to provide access to a new group of users without adding extra infrastructure servers (horizontal scaling). This scalability also brings cost-effectiveness because you can dynamically scale up and down based on a Pay-per-Use model.

In this Pay-per-Use model, the service is offered in two tiers and the usage is billed per user. The exact details can found here. These different tiers are known as the basic and standard tier. Where the basic tier is intended for lighter, task-worker uses cases such as a single productivity application or a web browser, the standard tier is more suited for the productivity applications like Office or client-server applications. In this case the starting price for the basic tier is € 7,447 and the usage is capped on € 13 per user/month. The standard tier‘s starting price is € 11,18 and is capped on € 18 per user/month. This starting price includes 40 hours of use per user/month. When a user exceeds these 40 hours an hourly overage rate is triggered which provides another 40-45 hours of usage on a Pay-per-Use model. When the user also exceeds the use of these hours, the financial cap is reached but the users are still able to make use of the service. Bottom line you are only billed for the cap price per user/month on different tiers.

When I had a first look on this prices, I considered it to be very expensive. But you have to take into account there is no need for RDS servers (maintenance) or RDS licenses (CALs). You now simply pay for the actual use, scale up or down when needed and you can access the service from any device. This all together makes it worth an actual consideration to bring RemoteApp into production.

From a technical point of view, RemoteApp also provides some nice features like:

  • Cloud and Hybrid deployments.
  • 50 GB storage per user.
  • Various (self-created) app collections.
  • Access from any device. (Windows, Windows Phone, iOS, Mac OS X and Android)

The cloud and hybrid deployment does require an explanation.

Cloud deployment

The Cloud deployment model is used to publish some standard Microsoft applications for example: Office 2013  or your own custom image. This deployment does not have a integration with the local network. Optionally you can use Azure AD Sync to synchronise your local identities to Azure AD so your users can make use of their local credentials to login to their RemoteApp applications. You can also use Microsoft ID’s to provide access to the RemoteApp collection.

20-1-2015 13-04-33

Hybrid deployment

The Hybrid deployment model is used to publish corporate apps. This means this deployment does have a direct integration with your local network using a VPN. In this way you can publish corporate apps and access resources which exists in your local network. For accessing these applications it is required to use local identities by using Azure AD Sync.

20-1-2015 13-12-59

 

So now you have a bit of an understanding on what RemoteApp is and which various types are available. In the rest of this blog I will do a Deep Dive into the technical steps to provision a Hybrid Azure RemoteApp deployment. At this point in time multiple steps are required to achieve this. To gain a bit of an overview I have defined the following list of steps:

  • Prepare your environment.
  • Prepare your Custom Image for the RemoteApp Deployment within Azure.
  • Create a RemoteApp collection.
  • Link the RemoteApp collection to an existing VNET.
  • Copy your Custom Image created within Azure to the RemoteApp template store.
  • Publish Apps and Configure User Access.

This all seems to be a lot of steps, so we better get starting!

Prepare your environment

Before you can start with the official RemoteApp deployment steps, it is a best practice to setup an environment using this list of prerequisites:

  • Azure VNET.*
  • Virtual Dynamic Gateway or a VPN device.
  • Local Active Directory.
  • Azure Active Directory tenant.
  • Setup Azure AD Sync with your on-premises or Azure environment.
  • Set Azure AD as the Default Directory for your Azure Subscription.

*Only required when you have your local Active Directory within Azure.

Prepare your Custom Image

We will prepare our Custom Image within Azure itself to save us some time when transferring the image to the RemoteApp template store. First of all create a Virtual Machine, in Azure, using the Windows 2012 R2 image.

After the Virtual Machine is created, you perform the following actions to prepare the image:

First of all add the Remote Desktop Session Host role and the Desktop Experience feature to the machine.

8-1-2015 14-35-30 24-1-2015 13-04-14

 

 

 

 

After the installation is completed, reboot your machine.

The next step is to install all your applications you want to publish by using RemoteApp on the Virtual Machine. In this example I have installed SQL Management Studio 2014 and Foxit PDF reader. At this point you can also add management clients to the machine. A good example might be the SCCM agent. Finally you must make sure your Windows Updates are up to date and KB2984006 is installed (this includes KB2977219). Afterwards you can reboot your machine.

Finally we have to do some last steps to complete the image. We start by disabling the Encrypting File System. Run the following command in elevated command prompt:

Fsutil behavior set disableencryption 1

8-1-2015 15-13-34

Next we change the unattend.xml file name to unattend.old to make sure the script is able to upload the image to the RemoteApp template store:

8-1-2015 15-17-48
And finally we Sysprep the image so we are we are able to use it for the RemoteApp collection. We do this by running the following command in an elevated command prompt:

C:\Windows\System32\sysprep\sysprep.exe /generalize /oobe /shutdown

8-1-2015 16-03-18
After the Sysprep process has completed, the Virtual Machine will shut down. In the mean while we will create the RemoteApp collection.

Create a RemoteApp collection

Log in to the Azure Management portal and create a new RemoteApp collection:

24-1-2015 13-27-31

Select the RemoteApp -> Create With VPN -> give the collection a name and select the Basic plan.

It will take some time to provision the collection. After the collection is being deployed you can now start with the first step:

Link the RemoteApp collection to an existing VNET

As mentioned before, for a hybrid deployment a VPN connection is required between the RemoteApp VNET and the on-premises network or Azure VNET. In this scenario a connection will be created between the 2 Virtual Neworks.

Start the wizard by clicking on the link a remoteapp VNET button and select create a new RemoteApp VNET.

8-1-2015 12-16-01

In the next step provide an Address Space for the RemoteApp VNET and define the local network, which is the address space of the Azure VNET you want to setup a connection with.

8-1-2015 12-25-55

It will take some time to complete this step. Now open up the Azure VNET page and download the NetworkConfig.xml. Add the RemoteApp VNET address space as a new Local Site to the configuration file:

8-1-2015 12-54-40

 

 

 

Save the configuration file using a new name and import the configuration file back to Azure:

24-1-2015 13-46-39

Now open the Azure VNET Configuration page and click the Connect to the local network checkbox and select the just added RemoteApp-VNET local network:

8-1-2015 13-49-24

Now open up the Azure VNET dashboard to create Virtual Dynamic Gateway:

8-1-2015 13-50-33

 

 

This action will assign a public IP address to your VPN endpoint (gateway). After the provisioning of the RemoteApp VNET is completed extra details will be available which you can use to actually setup the connection:

8-1-2015 15-43-15
Make note of these settings and open up the Local Networks within Azure. Select the local network pointing to the RemoteAPP VNET address space and edit its settings:

8-1-2015 15-42-29

Change the 1.1.1.1 address to the actual RemoteApp Gateway address noted in the previous step.

Save the configuration and open up Powershell in an elevated mode. Now run the following cmdlet using the following variables:

Set-AzureVNetGatewayKey -VNetName VNetIB -LocalNetworkSiteName RemoteApp-VNET -SharedKey

8-1-2015 15-57-55

VnetName: This is the name of the Azure VNET.
LocalNetworkSiteName: This is the name of the RemoteApp VNET. (local network)
SharedKey: This is the key you noted in an earlier step.

After a few minutes the VPN connection will be established:

8-1-2015 15-59-25

Finally we have to setup the configuration to domain join the RemoteApp collection by default. Fill in the account credentials of an account with domain join permissions:

8-1-2015 16-33-55

 

Copy your Custom Image to the RemoteApp template store

In this step we will use a script to copy the prepared image. First of all we check if the machine is in a shutdown state. If this is the case we run the following script:

### Source Parameters ###
$srcStorageAccount = “myAccount” # myAccount.blob.core.windows.net
$srcStorageKey     = “myKEY”     # get this from the Storage Account under Manage ACLs
$srcContainer     = “vhds”
$srcFilename       = “RemoteApp-myApp-2014-09-14.vhd” #Name of the file.
$srcContainerUri   = [String]::Format(“https://{0}.blob.core.windows.net/{1}”, $srcStorageAccount, $srcContainer)

### Destination  Parameters###
$dstStorageAccount = “cdveu142457994rdcm”   # myDest.blob.core.windows.net
$dstStorageSAS     = “?sv=2012-02-12&sr=b&si=c0dda1df-0f9e-45f4-64f9-2f89ca4b265g&sig=ob0j2e0CsA32j2gWn9MT4Qr9oiZI%2BN3fpgQOpuES%2F28%3D”
$dstContainer     = “goldimages”
$dstFilename       = “c0dda1df-0f9e-45f4-64f9-2f89ca4b265g.vhd”
$dstUri           = [String]::Format(“https://{0}.blob.core.windows.net/{1}/{2}”, $dstStorageAccount, $dstContainer, $dstFilename)

### Upload ###
$srcCredentials = New-Object  Microsoft.WindowsAzure.Storage.Auth.StorageCredentials($srcStorageAccount, $srcStorageKey)
$srcContainer = New-Object Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer($srcContainerUri, $srcCredentials)
$srcBlob = $srcContainer.GetBlobReferenceFromServer($srcFilename)
$srcStream = $srcBlob.OpenRead()
$dstCredentials = New-Object Microsoft.WindowsAzure.Storage.Auth.StorageCredentials($dstStorageSAS)
$dstBlob = New-Object Microsoft.WindowsAzure.Storage.Blob.CloudPageBlob($dstUri, $dstCredentials)
$dstBlob.UploadFromStream($srcStream)
$srcStream.Close()
$dstBlob.Metadata[“Status”] = “UploadComplete”
$dstBlob.SetMetadata()

In the script you need to change the source parameters and the destination parameters. The values of the destination storage account can be retrieved from the RemoteApp wizard. You can check the status of the upload on the RemoteApp Collection overview page. When the status becomes active you can start publishing apps and assigning users.

Publish Apps and Configure User Access

After the RemoteApp collection is active you can select the Apps you want to publish to your users. You can publish these apps on the Publishing page and by selecting Publish:

24-1-2015 14-45-59

As you can see, I am able to publish my own application SQL Management Studio 2014.

The final step is to add users to your RemoteApp collection. You can do this on the User Access page. All users in the list will be provided by the published apps in this collection.

For Hybrid deployments it is a prerequisite to set you Azure AD as the default directory for the Azure subscription where your RemoteApp collection exists.

The configuration of the RemoteApp collection is now completed! So now download the RemoteApp client and log in to check your published applications.

24-1-2015 14-56-49

Because we use a Hybrid Deployment you can setup connections between your RemoteApp client and your resources in your private network! For example databases by using SQL Management Studio.

Deploying a RemoteApp Cloud Deployment would have been much faster but less complex. A Cloud Deployment does not require a Custom image or a VPN to the local network. On the other hand you can only use the standard images provided by Microsoft at the moment. At the end of this blog I just want mention it takes a way too much steps to deploy a RemoteApp Hybrid Deployment. It would be more efficient if you can deploy RemoteApp in your own VNET and make use of the same storage accounts. This takes away the need of a VPN and transferring the image. So far I know, both these features are on the Microsoft calendar. So I cannot wait until they release the new stuff!

Thanks again for reading!!

  • TexasRedbud

    Thanks for this article, it looks like you put a lot of effort into it. I do have a question about the fee structure. You mention there was an initial payment of € 7,447 and then there are usage fees on top of that. Isn’t the initial payment a usage prepay for the life of an agreement? And the usage fees are subtracted from that initial payment? In your text it seems you are saying that a customer pays the one large fee, then pays the additional usage fees. Can you clarify? Thanks

    • JurgenvdBroek

      For the Basic tier license you have to pay € 7,447 initial costs per user a month. Unfortunately this isn’t just one time payment for the life time of your agreement. This includes 40 hours of usage. When a user uses the RemoteApp instance for more than this 40 hours, a Pay-per-Use model (€0.1304/hr) is being used until a the cap of € 13 has been reached. So the maximum costs per user a month is for the Basic tier: € 13. See the Azure Pricing details: http://azure.microsoft.com/en-us/pricing/details/remoteapp/

  • leonmeijer

    Please note the typo in the Powershell command: Set-AzureVNetGateway should be Set-AzureVNetGatewayKey

    Excellent guide! Thanks

    • JurgenvdBroek

      Thanks! I will edit the post.

  • Eric Orman [ericor@MSFT]

    Nice blog, two points, never alter the image upload script, we have purposely added checks to ensure that when we provision the service it completes successfully, the checks are there for you. Second, Cloud deployments do support custom images

    • JurgenvdBroek

      Thanks for you feedback! I had to use a custom script because i created my image in Azure. If i wanted to use the generated upload script I had to download the vhd from Azure and upload back again using the script. In my opinion a waste of time.

      I will add your second point to the blog!

  • Adam Lavery

    Still trying to get my head around Azure VNETs and RemoteApp. It all seems to have been overly complicated. If we boil it down there are two types of VNET in Azure:

    Cloud VNET: a network entirely within Azure; no connection to on-premise network..
    Hybrid VNET: a cloud network that is in effect an extension of an on-premise network.

    What you describe is how to connect a RemoteApp Collection (which in real terms is an RD Session Host server) to a Hybrid VNET. As it stands now, technically it should be “…with Hybrid VNET” and not just “…with VNET”.

    So what about connecting a RemoteApp Collection to a Cloud VNET? There doesn’t appear to be a way to do this. My backend SQL server is a VM in a Cloud VNET. I created and tested my RemoteApp image on an RD Sessions Host template that was also in the Cloud VNET, but then there’s no way to specify my RemoteApp server goes into the Cloud VNET.

    So how can my published LOB app connect to my SQL Server VM?

    If you use the Quick Create option there’s no way to link with a VNET of any sort. If you use “…with VNET” then the VNET is assumed to be a Hybrid VNET and the RemoteApp Collection (or RDSH server) must be joined to the domain as a pre-requisite of configuring it,
    So how can a Cloud Only solution work?

    Azure would make a lot more sense and be simpler to configure/manage if everything was based around VNETs instead of the dislocated collection of resources presented now. So you create a VNET (Cloud only or Hybrid) and then you add resources to the VNET. After all, that exactly how we do it in the real physical world. Then your Azure network looks and feels much more like a real network, which beneath the cloud marketing hype, is exactly what it is.

    • Oliver Sch

      Hi Adam. Same situation/needs here. Do you found a solution for your szenario descibed above? Greeting Oliver

      • Adam Lavery

        Hi Oliver. This will apparently be addressed later this year. For now this is not possible. The only solution I came up with is to not use Azure Remote App but instead create an RDSH VM and publish as a RemoteApp from that using standard non-Azure RemoteApp facilities. Although for now not doing that and simply using a Remote Desktop to run the LOB app.
        Depending on users, that approach is probably more cost-effective given the 20 minimum on Azure Remote App. Then cost is the VM and one-off RD CALs instead of per-user monthly subscriptions.
        Brgds, Adam

  • Bruno Carvalho

    Great article. Is there any chance of getting the visio diagrams?

    Thanks