How do you Inject Configurations into Microsoft Azure Cloud Service Startup Tasks?

March 19, 2014 — 2 Comments

In a previous post I used a Startup Task to isolate incompatible code bases, unfortunately this brought about some challenges. One of which might also affect whoever is looking at implementing this sort of solution.

How do you manage configurations for Microsoft Azure Cloud Service Startup Tasks?

At first glance, this situation looks a bit odd and we might feel the need to implement something exotic. But hold off on that thought for a second. Think about how easy and fun it is to be able to change configurations through the Azure Management Portal. There has to be a way to pull in those configurations right?

Fortunately there is, and it’s been around since version 1.5 of the Azure SDK. Using XPath we can pass configuration values from the Cloud Service configurations to Environment Variables that can then be used as parameters for the Startup Task executable.

pulling configurations from the Cloud Service Configurations

The following example will take you through the steps needed to build and user Cloud Service configurations to configure your custom Startup Tasks.

Use the following “Hello World” console application as a starting point for your own tests. It will receive a string as its first argument and print it back out to Console.

using System;

namespace StartupTask
{
    class Program
    {
        static void Main(string[] args)
        {
            var message = args[0];
            Console.WriteLine("Message |> " + message);
            Console.ReadLine();
        }
    }
}

Build and add the Console’s EXE to the root of a Cloud Service Role project. Then add a startup.cmd to this same project. Be sure to add the following command so that it starts the Startup Task and passes the message Environment Variable.

start StartupTask.exe "%STARTUP_MESSAGE%"

Be sure to save the contents of startup.cmd by setting its encoding to ANSI.

Don’t worry about the Environment Variable for now because it will be defined in the Startup Task’s configuration.

At this time the Cloud Service Role project should contain the startup.cmd and StartupTask.exe files.

Configuration

Be sure that these files are copied to the output directory of the Cloud Service Role by setting the Build Action to “Content” and the Copy to Output Directory property to “Copy always”.

Copy Always

Now that we have most of the pieces in place, let’s configure a startup message through the Cloud Service configurations. You can access the configuration settings by Right clicking on the Role located in the Cloud Service project.

Cloud Service Properties

Then navigate to the Settings section and add a new setting as shown below.

cloud service settings

We’re now ready to configure the Startup Task. Open the ServiceDefinition.csdef located at the root of the Cloud Service project. The XML should look something like the following Worker Role definition. Add a Startup tag under its root element. At this time Visual Studio’s IntelliSense should kick in and help you enter valid configuration values.

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="WindowsAzure3"
                                     xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"
                                     schemaVersion="2013-10.2.2">
    <WorkerRole name="WorkerRoleOne" vmsize="Small">
        <Startup>
            <!– place Tasks here–>
        </Startup>
        <Imports>
            <Import moduleName="Diagnostics" />
        </Imports>
        <ConfigurationSettings>
            <Setting name="StartupMessage" />
        </ConfigurationSettings>
    </WorkerRole>
</ServiceDefinition>

To make it easier to concentrate on what we’re really after I re-scoped the XML to the Startup tag.

<Startup>
    <Task commandLine="startup.cmd" executionContext="limited" taskType="background">
        <Environment>
            <Variable name="STARTUP_MESSAGE">
                <RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/ConfigurationSettings/ConfigurationSetting[@name='StartupMessage']/@value" />
            </Variable>
        </Environment>
    </Task>
</Startup>

We then need to define the Task as we did in my previous post. This time because we’re only testing this out, I decided to use a limited execution context and to run the Console application as a background task.

We can now setup the Environment Variables by defining them as children of the Task’s definition. We define the variable’s name and its value as shown above. In this specific instance we are interested in the XPath expression used to retrieve the configuration values from the Cloud Service configurations. The resulting value will set to the Environment Variable.

Remember, changing a configuration through the Azure Management Portal after a Startup Task has been initiated will not propagate the new configurations. The Role will need to be restarted for the new configurations to be taken into consideration. Achieving live configuration updates will require more creativity.

At this point, you can try to start the Cloud Service using the local Azure Emulator. If the starts align, the Console will pop up showing the message that was entered in the Cloud Service configurations earlier in this post.

Background Startup Task

2 responses to How do you Inject Configurations into Microsoft Azure Cloud Service Startup Tasks?

  1. 

    Every now and then you find an article that perfectly describes what you need. Thanks man. Saved me from a likely too clever hack.

    Like

Trackbacks and Pingbacks:

  1. Reading Notes 2014-03-24 | Matricis - March 24, 2014

    […] How do you Inject Configurations into Windows Azure Cloud Service Startup Tasks? – A great tutorial indeed! It shows how to have dynamic configuration in our startup tasks, and who doen't? […]

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.