Deploy Windows Azure Patches and “Avoid The Wait”
Have you ever successfully deployed a Windows Azure project…and discovered a typo? Maybe you forgot to include a supporting dll or a new image file. I can hear you swearing from here.
These types of mistakes can be frustrating because they’re not programming errors. You left something out of the deployment package, but you don’t want to go through the long deployment process again just for this minor change.
In the past, I’ve used Remote Desktop to perform updates on each web role instance, but that can be very tedious. You can use Web Deploy if you’re only using one instance, but that isn’t practical. I saw one other approach that uses NuGet, which looks interesting, but isn’t quite what I want.
Update: Of course, I wrote this post and then saw the Windows Azure Accelerator. I’ll give it a try and write a follow up post. It looks like a similar solution, but it polls for updates. I’m not a big “Web Deploy” user, so I can’t comment on the degree of deployment control. I think it’s worth reading the rest of this post so you can decide.
I needed something simple to end my frustration, so I wrote PatchAzure. The code allows me to upload a patch to Azure Storage and apply the updates to all Web Roles. Each patch is a simple zip file that unzips into the webroot of each Azure instance.
The patching process is triggered whenever the Azure configuration file is updated and when the instance is started. Each patch is applied only once, unless the instance is rebuilt.
The patching process is triggered whenever the Azure configuration file is updated and when the instance is started.
There are just a few code changes you’ll need to make to your existing Azure Web Role Project.
- Include the PatchAzure.cs file in your project.
- Then update WebRole.cs with the changes in Listing 1. Update the credentials with your storage credentials.
- Add the “patch” setting to your Azure configuration file (Listing 2).
- Deploy the project, and you’re ready for your first patch.
Listing 1
WebRole.cs
...
public override bool OnStart()
{
RoleEnvironment.Changed += RoleEnvironmentChanged;
PatchesApply();
return base.OnStart();
}
private void RoleEnvironmentChanged(object sender, RoleEnvironmentChangedEventArgs e)
{
PatchesApply();
}
private void PatchesApply()
{
try
{
//Get the path to the website
//Using ServerManager since other methods aren't available in WebRole.cs.
//Reference: Microsoft.Web.Administration.dll in %WinDir%\System32\InetSrv (Copy Local=True/Specific Version=True)
//Note: This will not work for testing with the emulator. Hardcode rootdir if needed.
ServerManager server = new ServerManager();
string rootdir = Environment.ExpandEnvironmentVariables(server.Sites[0].Applications[0].VirtualDirectories[0].PhysicalPath);
//*********************************************
//Check for new patches.
//*********************************************
//Blob Storage Account Name
string accountName = "{account name}";
//Blob Storage Key
string key = "{storage key}";
//Blob Container where patches are stored.
string patchContainer = "patches";
//Comma-delimited list of patch names. They must be "zip" files. Do not include the .zip extension.
string patchNames = RoleEnvironment.GetConfigurationSettingValue("patches");
if (patchNames.Length > 0)
{
PatchAzure.Patch(accountName, key, patchContainer, patchNames, rootdir);
}
}
catch (Exception ex)
{
Trace.TraceError(ex.Message);
}
}
...
Listing 2
ServiceDefinition.csdef
ServiceDefinition\Webrole
...
<ConfigurationSettings>
<Setting name="patches" />
</ConfigurationSettings>
...
ServiceConfiguration.csfg
ServiceConfiguration\ConfigurationSettings
... <Setting name="patches" value="" /> ...
Applying a Patch
Once the PatchAzure updates are deployed in your project, creating and applying a patch is easy.
- Create a Zip file and give it a name ({name of patch}.zip).
- Add files to the Zip file using the same directory structure as your web project.
- You can include a batch file if you like and it will be run during the patching process. The name of the batch file must include the patch name and end in .cmd ({name of patch}.cmd).
- Upload the Zip file to your Blob Storage Container. The container was specified in WebRole.cs (default=patches).
- In the Windows Azure Portal, Click on your deployment. Then click Configure and edit your configuration file.
- Locate the “patches” setting and add the patch name to the value attribute. The patch name must match the Zip file name that you uploaded (without the .zip extension).

Example:
<Setting name="patches" value="patch1,patch2,patch3" />
- When you click OK, the configuration file will save. This will trigger the application of the patches.
- The Zip file is downloaded from blob storage to each web instance. The files are extracted to their appropriate locations and then the Zip file is renamed to indicate that the patch is complete.
Could this process be used in production (perhaps even for an xcopy site update)? That’s up to you, but I think it’s possible. One thing that might make this unworthy of production is the lack of feedback. It is difficult to tell if a patch succeeds, so be prepared to use Remote Desktop. The code could be improved to provide more feedback, but much of that may depend on your needs.
I’ve tested this process and it’s been working for me, but I haven’t been using it long. Please let me know if you find any issues or have suggestions. As for me, I’m happy to finally have an easier way to fix my typos.
data-text=”Deploy Windows Azure Patches and “Avoid The Wait” (Shannon Whitley)”
data-count=”vertical”
>Tweet

HI,
What i need to implement in PatchAzure.cs class.
Thanks,
JayaKrishna