Windows Azure Deployment Tips & Tricks

Posted on August 3, 2011

I’ve run into a few gotchas when deploying to Azure.

  • Missing DLLs. Not all “system” libraries are included in the Windows Azure run-time environment.  If you use any of these, make sure to mark them as CopyLocal=true in your project.  The one I always forget is EntityFramework.dll.
  • Folder permissions.  If you add local storage folders to your deployment, you might be surprised to find that when logged in to the deployment machine with Remote Desktop, you won’t have even read permission to files in local storage folders.  Fortunately, you can easily add a startup task to grant permissions.  In my deployments, I use a batch file to launch a PowerShell script to do this.  The batch file (fixPermissions.cmd) looks like this:
    powershell -ExecutionPolicy Unrestricted .\FixFolderAccess.ps1

    The PowerShell script (FixFolderAccess.ps1) looks like this:

    Add-PSSnapin Microsoft.WindowsAzure.ServiceRuntime
    while (!$?)
        echo "Failed, retrying after five seconds..."
        sleep 5
        Add-PSSnapin Microsoft.WindowsAzure.ServiceRuntime
    echo "Added WA snapin."
    $localresource = Get-LocalResource "myLocalStorageFolderName"
    $folder = $localresource.RootPath
    $acl = Get-Acl $folder
    $rule1 = New-Object System.Security.AccessControl.FileSystemAccessRule(
      "None", "Allow")
    $rule2 = New-Object System.Security.AccessControl.FileSystemAccessRule(
      "None", "Allow")
    Set-Acl $folder $acl
    echo "Done changing ACLs."
  • Startup tasks.  When adding a startup task, you need to do two things: first, add the task to the role in your .csdef file.  This will look something like this:
    <WorkerRole name="MyWorkerRole">
        <Import moduleName="Diagnostics" />
        <Import moduleName="RemoteAccess" />
        <Task commandLine="startup.cmd" executionContext="elevated" taskType="background" />

    The execution context can be “elevated” if the command you’re running requires administrative privileges, or “limited” to use the same privileges as the role itself.  The task type can be “simple”, where other tasks (and the role itself) are not started until the task finishes, or “background”, in which other tasks and the role can be started before the task completes.  A third type, “foreground” allows other tasks to start before it is finished, but the role is not started until the task finishes.

    The second part of creating a startup task is to create the batch file that is referenced in the <Task> element above.  In this case, it is startup.cmd.  It is essential that you save this file without a byte order mark.  To do this from Visual Studio, when saving the batch file, use Save As, and select the option Save with Encoding from the Save button dropdown.  Select Unicode (UTF-8 without signature) – Codepage 65001.  If you prefer, you can just create the batch file with Notepad, which will also save it without the offending byte order mark.

    A final note about startup tasks:  If you use PowerShell in a startup task, you need to set your ExecutionPolicy to allow unsigned scripts (as shown in the example above: -ExecutionPolicy Unrestricted).  This is only supported in PowerShell 2.0, which means that you need a Windows Server 2008 R2 run-time environment.  This is not the default in Azure.  To enable this, set the <ServiceConfiguration> tag in your .cscfg file to specify osFamily=”2”.  This requests the Windows Server 2008 R2 environment instead of the default Windows Server 2008 SP2.

  • Custom performance counters.  They are supported in Azure.  You do have to create the performance counter category in an elevated startup task, as the role itself does not have the required permissions.
  • Can a Worker Role handle HTTP requests?  Sure it can.  Just make sure that you add an inbound rule to the Windows Firewall allowing traffic on port 80.  Note that this rule will be deleted if you stop the deployment or reboot

No Replies to "Windows Azure Deployment Tips & Tricks"

    Got something to say?

    Some html is OK