Best Practices for Startup Tasks
Updated: November 13, 2013
Startup Tasks Set Global Attributes
Because startup tasks are run before IIS is fully started and configured, startup tasks are not suited for configuring site, role, or instance attributes. Startup tasks are more suited to configuring global attributes.
Site, role, and instance specific attributes should be set in the Microsoft.WindowsAzure.ServiceRuntime.RoleEntryPoint.OnStart method.
Always Log Startup Activities
Visual Studio does not provide a debugger to step through batch files, so it's good to get as much data on the operation of batch files as possible. Logging the output of batch files, both stdout and stderr, can give you important information when trying to debug and fix batch files. To log both stdout and stderr to the StartupLog.txt file in the directory pointed to by the TEMP environment variable, add the text
>> "%TEMP%\StartupLog.txt" 2>&1 to the end of specific lines you want to log. For example, to execute setup.exe in the %PathToApp1Install% directory:
If you want to log all output from the startup task without adding
>> "%TEMP%\StartupLog.txt" 2>&1to the end of each line, two startup batch files are needed. The first batch file will call the second batch file with redirection to log all of the activities of the second batch file. This is necessary for proper redirection to occur.
The following shows how to redirect all output from a startup batch file. In this example, the ServerDefinition.csdef file creates a startup task that calls Startup1.cmd. Startup1.cmd calls Startup2.cmd, redirecting all output to %TEMP%\StartupLog.txt.
<Startup> <Task commandLine="Startup1.cmd" executionContext="limited" taskType="simple" /> </Startup>
REM Startup1.cmd calls the main startup batch file, Startup2.cmd, redirecting all output REM to the StartupLog.txt log file. REM Log the startup date and time. ECHO Startup1.cmd: >> "%TEMP%\StartupLog.txt" 2>&1 ECHO Current date and time: >> "%TEMP%\StartupLog.txt" 2>&1 DATE /T >> "%TEMP%\StartupLog.txt" 2>&1 TIME /T >> "%TEMP%\StartupLog.txt" 2>&1 ECHO Starting up Startup2.cmd. >> "%TEMP%\StartupLog.txt" 2>&1 REM Call the Startup2.cmd batch file, redirecting all output to the StartupLog.txt log file. START /B /WAIT Startup2.cmd >> "%TEMP%\StartupLog.txt" 2>&1 REM Log the completion of Startup1.cmd. ECHO Returned to Startup1.cmd. >> "%TEMP%\StartupLog.txt" 2>&1 IF ERRORLEVEL EQU 0 ( REM No errors occurred. Exit Startup1.cmd normally. EXIT /B 0 ) ELSE ( REM Log the error. ECHO An error occurred. The ERRORLEVEL = %ERRORLEVEL%. >> "%TEMP%\StartupLog.txt" 2>&1 EXIT %ERRORLEVEL% )
REM This is the batch file where the startup steps should be performed. Because of the REM way Startup2.cmd was called, all commands and their outputs will be stored in the REM StartupLog.txt file in the directory pointed to by the TEMP environment variable. REM If an error occurs, the following command will pass the ERRORLEVEL back to the REM calling batch file. EXIT /B %ERRORLEVEL%
Set executionContext Appropriately for Startup Tasks
Set privileges appropriately for the startup task. Sometimes startup tasks must run at elevated privileges while roles run at normal privileges.
The executionContext attribute sets the privilege level of the startup task. Using executionContext="limited" means the startup task will have the same privilege level as the role. Using executionContext="elevated" means the startup task will have administrator privileges, which allows the startup task to perform administrator tasks without giving administrator privileges to your role.
An example of a startup task that requires elevated privileges is a startup task that uses AppCmd.exe to configure IIS. AppCmd.exe requires executionContext="elevated" in the Task element.
The following example sets elevated privileges for the startup task ConfigureIISSettings.cmd:
Use the appropriate taskType
The taskType attribute determines the way the startup task will be executed. There are three taskType values: simple, background, and foreground. The background and foreground tasks are started asynchronously, and then the simple tasks are executed synchronously one at a time.
With simple startup tasks, you can set the order in which the tasks will occur by the order in which the tasks are listed in the ServiceDefinition.csdef file. If a simple task ends with a non-zero exit code, then the startup procedure will stop and the role will not start.
The difference between background startup tasks and foreground startup tasks is that foreground tasks will keep the role running until the foreground task ends. This also means that if the foreground task hangs or crashes, the role will not recycle until the foreground task is forced closed. For this reason, background tasks are recommended for asynchronous startup tasks unless you need that feature of the foreground task.
End batch files with EXIT /B 0
The role will only start if the errorlevel from each of your simple startup task is zero. Not all programs set the errorlevel (exit code) correctly, so the batch file must end with an
EXIT /B 0 command.
EXIT /B 0 at the end of a startup batch file is a common cause of roles that do not start.
Expect startup tasks to run more than once
Not all role recycles include a reboot, but all role recycles include running all startup tasks. This means that startup tasks must be able to run multiple times between reboots. This is discussed in detail in Strategies for Writing Startup Tasks that can run Multiple Times.
Use local storage to store files that must be accessed in the role
If you want to copy or create a file during your startup task that is then accessible to your role, then that file must be placed in local storage. For detailed instructions on how to create and use local storage for your startup task and role, see the article Use Local Storage to Store Files During Startup.
ConceptsRun Startup Tasks in Windows Azure