Sunday, 13 November 2011

Windows Azure Startup Tasks


Azure platform provides a fresh Operating System with Windows Server 2008 R2, .NET runtime and security patches in each Windows Azure Guest OS for uploading the application code. To know more about what are the security patches installed in each OS, look at the Windows Azure Guest OS Releases and SDK Compatibility Matrix.

As the Azure Guest OS contains only .NET runtime for the applications to run, it works fine with applications developed with .NET framework. But if the application required any extra installation or configuration to be done before running the application, how to do it? For example consider any of the following jobs –

  1. The application required some redistributable components to be installed, such as Crystal Report redistributable runtime.
  2. The application required to gather some information about the operating system such as computer name, network IP Address and store in the system somewhere for application usage.
  3. The application required to change some registry settings in the server.
  4. The application required some third part components installed in the server. So before running the application, the component must be downloaded from the internet (or get it from blob) and install in the server.

To achieve this requirement we can have any of the following solution:

  1. We can have VM Role. It can be done by creating Windows Server 2008 R2 as Virtual Machine in on-premise and install required components, configuration settings in the VM. Once the VM is ready, the VHD file can be uploaded (using csupload command) to the blob and mount as VM role. So the application can run perfectly as the role have required components, configurations and settings already.
  2. By using Windows Azure Startup Task, install the required components, settings, configurations in the server.

VM role is somewhat expensive solution (compare to Startup task), because the user required to pay for VHD storage in blob service and for a simple change in the server - it required to create differential disk (or recreate the full vhd) and upload to Azure. This will be useful solution when the installation takes much time, very complex and required some human interaction.

Startup task can be used for running command line (and Power Shell) scripts when starting the role. So, it will be easy for doing the necessary job using those scripts. But important to consider the time it takes for completing the script (if the installation takes much time).

Steps for implementing Startup task with Azure Roles

Step 1: Create an Azure Project with Web or Worker Role. (Note: Startup task is not supported in VM Role)

Step 2: Create a command line script file (with extention as .cmd) using any character based editor such as Notepad and save the file.

Step 3: Add the file into the project and change the Copy to output Directory property to Copy always.

Step 4: (Optional) if you do any change in the script file using Visual Studio after it's been added, the Visual Studio saves the file in byte code. But the azure Startup Task required the script file in Unicode (UTF-8 without signature) format. So open the cmd file and select File -> Advanced Save Options… menu. Select Unicode (UTF-8 without signature) option from the Advanced Save Options popup window and click OK and save the file.

Step 4: To add Startup Task in to the Azure project, open the ServiceDefinition.csdef file and add <startup> node with requited <task> node.

As the <task> node is the child node for <startup> node and can be repeated more than one. So, it is easy to link more than one command script files if required.

The <task> node contains three attributes.

  1. commandLine – is for defining script file with the relative path. The files must be under the bin folder of application path. (For ex: commandLine=”startup.cmd”).
  2. executionContext – is for defining level of permission for executing the script file. There can be two different types of permission levels.
    • limited – executes the script file at the same level what the role runs at.
    • elevated – executes the script file at Administrative privileges.
  3. taskType – is for defining the way how the script process should runs.
    • Simple – is the default type. When the task is Simple type, the role instance will be blocked until the script file completes. In other words, the application will not available to the end user until the script file completed.

      This type will be more useful when the application is entirely depends on the completion of the Startup Task. For Ex: there is a basic configuration in the registry required in the system which is referred by the application in each page – then taskType must be set as Simple.

      There are some important points to keep in mind when using this type
      • The application will be blocked until the script completes. So, if the script takes much time than it will be an availability issue.
      • If the script is error-prone or has any issue (such as downloading a file when the file is not exist in the location and waiting for the file) or the script running an infinitive loop then the application will not be available to the end user.

    • Background – the Startup task runs in the background when the role runs as usual. So the task will complete asynchronously and will not block the application anyway.

      This type will be more useful when any process required to be completed at initial stage of the role in the server and not depends by the application at anyway. If the script fails executing the script or takes long-running also no issue.

    • Foreground – the script runs in the foreground asynchronously with role (as Background) and the role available to the end user. It is same as Background, but the role instance can’t be recycled until the script execution completes.

      This type of task may not be used more, but it can be used in situation when the task starts and must complete fully. For Ex: The startup task calls an exe file which required the completion fully as it updating some external application data.
Step 5: Deploy the application in Azure environment and see the output.

Skipping Startup Task when running in the Emulator

Startup Task is used for making the fresh Azure OS capable for running the application by installing some components and configuring settings in the server at initial startup and once the task completed it is not required any more. But considering the local development environment, the developer already installed all the necessary components and configuration settings in the development system. So running the Startup task at emulator is not required for every time the application starts. It may even cause some issue, some are:
  1. The Startup Task written to download huge file from internet and install in the server. So running with the Startup Task in the emulator may take much time for running the application.
  2. Installing the component again and again in the development environment may put system in mess.
  3. The Azure environment has 64 bit OS (Windows Server 2008 R2 64 bit), but the development environment may be in 32 bit version. So installing the 64 bit setup may impact the development system and is not meaningful also.
  4. The Startup Task may change some registry settings which may affect the development environment.
  5. The Startup Task is required to be executed at starting stage of the application, but the development work required to be in running stage.
  6. The production configuration and development configuration will be normally different. So making configuration change at Startup Task in the development environment may impact production environments.

So how to skip the Startup Task in the Emulator?

The Azure SDK v1.5 introduces a new static property IsEmulated which is used for determining whether the role runs with local Emulator or Azure. So by using RoleEnvironmenet.IsEmulated property, we can assign the value to an environment variable and use it in script file. The script file should have a logic to verify the environment variable and skip the execution if it runs on emulator.

Step 1: So to do this, the <Task> node will be changed to have an environment variable and get the value from RoleInstanceValue. The ServiceDefinition.csdef file will be as below

Step 2: In the script file, add an if statement to verify the environment variable and skip the file if true. The script file will looks like

Now, if we run the application in development system (emulator), the script will not after the if statement execute and will not produce the ServerIP.txt file.

Executing PowerShell script with Windows Azure Startup Task

Refer the page Executing PowerShell script with Windows Azure Startup Task for the detailed steps.

0 Responses to “Windows Azure Startup Tasks”

Post a Comment