In my last post on zipping IIS log files in Windows Azure, my ServiceDefinition.csdef file included the following code to set an environment variable to the value of a local resource path:

<Task commandLine="Startup\ScheduleLogFileZipAndDeleteTask.cmd" executionContext="elevated" taskType="simple">
  <Environment>
    <Variable name="ZippedLogFilesPath">
      <RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/LocalResources/LocalResource[@name='ZippedLogFiles']/@path" />
    </Variable>
  </Environment>
</Task>

As you can see, an XPath query is used to retrieve the resource path. Someone asked me what this XPath query refers to. I didn’t know, so I looked into it.

There is a page in the Windows Azure documentation which talks about this feature, and gives a whole bunch of examples of values you can pull out using different XPath queries. You can use this to set environment variables either for a specific startup task (specifying it under the <Startup> element), or for the role entry point code (specifying it under the <Runtime> element). However the documentation still doesn’t explain what XML document is being queried, so you can’t tell what other information may be available to you.

After a bit of poking around, I found the mysterious document. It only seems to be created if you include an xpath element somewhere in your ServiceDefinition.csdef file, so you can add a dummy environment variable like this to ensure the file is created:

<Runtime>
  <Environment>
    <Variable name="TestIsEmulated">
      <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated"/>
    </Variable>
  </Environment>
</Runtime>

Now when you deploy the solution (either to Windows Azure or to the local compute emulator), you’ll get a file with a filename similar to DeploymentId.DeploymentId.RoleInstanceName.RoleEnvironment.1.xml. On a real Windows Azure VM, this file is in C:\Config; in the local compute emulator it is more hidden, living at C:\Users\username\AppData\Local\dftmp\Config. (Don’t confuse this file with another one in the same folder that doesn’t end with RoleEnvironment.1, as this file has a different schema and data, and as far as I know can’t be queried in the same way). In both Windows Azure and the emulator, the role environment XML file should have the same format – here’s an example from my IIS log zipping app:

<?xml version="1.0" encoding="utf-8"?>
<RoleEnvironment xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Deployment id="046cfa59b8894be3b0ca5f0c6aaeb237" emulated="false" />
  <CurrentInstance id="WebRole1_IN_0" roleName="WebRole1" faultDomain="0" updateDomain="0">
    <ConfigurationSettings>
      <ConfigurationSetting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" value="DefaultEndpointsProtocol=https;AccountName=xxxx;AccountKey=xxxxx" />
      <ConfigurationSetting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountEncryptedPassword" value="xxxx" />
      <ConfigurationSetting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountExpiration" value="2014-05-08T23:59:59.0000000+10:00" />
      <ConfigurationSetting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.AccountUsername" value="remoteuser" />
      <ConfigurationSetting name="Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled" value="true" />
      <ConfigurationSetting name="Microsoft.WindowsAzure.Plugins.RemoteForwarder.Enabled" value="true" />
    </ConfigurationSettings>
    <LocalResources>
      <LocalResource name="DiagnosticStore" path="C:\Resources\directory\046cfa59b8894be3b0ca5f0c6aaeb237.WebRole1.DiagnosticStore\" sizeInMB="4096" />
      <LocalResource name="ZippedLogFiles" path="C:\Resources\directory\046cfa59b8894be3b0ca5f0c6aaeb237.WebRole1.ZippedLogFiles\" sizeInMB="1000" />
    </LocalResources>
    <Endpoints>
      <Endpoint name="Endpoint1" address="10.78.196.62" port="80" publicPort="80" protocol="http" />
      <Endpoint name="Microsoft.WindowsAzure.Plugins.RemoteAccess.Rdp" address="10.78.196.62" port="3389" publicPort="0" protocol="tcp" />
      <Endpoint name="Microsoft.WindowsAzure.Plugins.RemoteForwarder.RdpInput" address="10.78.196.62" port="20000" publicPort="3389" protocol="tcp" />
    </Endpoints>
  </CurrentInstance>
  <Roles />
</RoleEnvironment>

There’s not a whole lot in there that isn’t alluded to in the documentation, but it’s always nice to know exactly what it is that you’re dealing with.