Wed, 13 Jul 2011

Using a Local Storage Resource From a Startup Task

You probably already knew that you should always declare local storage via the LocalStorage element in your ServiceDefinition.csdef when you need disk space on your VM in Windows Azure. The common use for this sort of space is as a scratch disk for your application, but it’s also a handy place to do things like install apps or runtimes (like Ruby, Python, and Node.js, as I do in the Smarx Role). You’ll typically do that from a startup task, where it may not be obvious how to discover the local storage path.

You can, of course, simply write your startup task in C# and use the normal RoleEnvironment.GetLocalResource method to get the path, but startup tasks tend to be implemented in batch files and PowerShell. When I need to do this, I use a short PowerShell script to print out the path (getLocalResource.ps1 from Smarx Role):

param($name)
[void]([System.Reflection.Assembly]::LoadWithPartialName("Microsoft.WindowsAzure.ServiceRuntime"))
write-host ([Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment]::GetLocalResource($name)).RootPath.TrimEnd('\\')

and then use it from a batch file like this (installRuby.cmd from Smarx Role):

powershell -c "set-executionpolicy unrestricted"
for /f %%p in ('powershell .\getLocalResource.ps1 Ruby') do set RUBYPATH=%%p

I’ve also, in the past, used a small C# program (Console.WriteLine(RoleEnvironment.GetLocalResource(args[0]).RootPath);) in place of the PowerShell script. (I still use the same for loop in the batch file, just calling GetLocalResource.exe instead.) The PowerShell script just seems scripty-er and thus feels better in a startup task. Otherwise I don’t see a difference between these two approaches.