When creating a Worker Role on Windows Azure, due to the nature of the worker role, we need to be fully auto-consistent: each time the role is deployed (or re-imaged) into the Azure infrastructure a brand new virtual machine is created to host the role thus if the role needs, in order to work, some OS customization we need to do those customizations at role startup.

Startup tasks are provided exactly to achieve that.

In order to setup RavenDB, when using Windows Authentication, you need at least 2 users:

  • An administrator to perform administrative tasks, such as backups or system level operations;
  • A standard user in order to connect and operate on a database;

Each time the role is deployed users must be created on the newly deployed virtual machine.

A startup task is a separate process that can be launched at role startup, the task definition is created in the “ServiceDefinition.csdef” file:

<Startup>
<Task commandLine="Startup\CreateWindowsUser.exe" executionContext="elevated" taskType="simple">
<Environment>
<Variable name="emulated">
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
</Variable>
<Variable name="username">
<RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/ConfigurationSettings/ConfigurationSetting[@name='RavenUserUsername']/@value" />
</Variable>
<Variable name="password">
<RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/ConfigurationSettings/ConfigurationSetting[@name='RavenUserPassword']/@value" />
</Variable>
<Variable name="admin" value="False" />
</Environment>
</Task>
</Startup>

As you can see we are calling an external process, with elevation, and we’ll wait for the process to complete before moving on (simple taskType); if we need to pass information, defined in the role settings, to the external task the only way, as far as I know, is to use a shared environment variable. In this sample we are passing to the external task the username and password of the user we need to create, a flag that indicates if the user should be an administrator or not, and a flag that tells to the external process if we are running in the Azure emulator or not.

We can launch as many tasks as we want, and in the real scenario we are launching the above task 2 times, with different parameters, in order to create the 2 required users.

The external process does nothing special, it just creates a user, using the provided info, via the System.DirectoryServices.AccountManagement namespace classes.

.m