Neudesic Blogs

Passion for Innovation

Multiple Service Configurations in Windows Azure Tools for Visual Studio (August 2011)

Referring back my previous blog on how to to use XDT transforms to have effective multiple cloud service configurations, Multiple Service Configurations is now a new feature in Windows Azure Tools for Visual Studio 1.4 (August 2011).

When a new Windows Azure project is created, two service configurations are created by default. Service configurations are stored as files in cloud service project (ServiceConfiguration.Cloud.cscfg and ServiceConfiguration.Local.cscfg), and contain properties and settings for the named configurations.

One can create as many different service configurations as required. Current service configuration can be selected in the Windows Azure project's role properties view or in the Publish Windows Azure Application dialog.

The new feature is a great improvement, but leaving a lot to desire: once a new configuration is created, it is independent and shares nothing with other configurations and has to be fully maintained. One could have used multiple Windows Azure projects associated with the same role projects, and different service definition and configuration settings.

Hopefully, Windows Azure tools will soon come with a feature as flexible as XDT transformations, but native to the Windows Azure project.

Posted: Sep 06 2011, 03:51 by Milenko.Djuricin | Comments (0) RSS comment feed

Tags:
Categories: Azure

Visual Studio 2010 and MsBuild Tasks for Azure Deployment

While Windows Azure SDK and Windows Azure Tools for Visual Studio help a lot when developing and deploying Cloud Services, there's still much to be desired, especially with managing application setting and numerous connection strings between development, cloud staging and production, as well as “mixed mode” deployments. Where there's no place for human errors - automation rules, which is where MsBuild can help.

 

Let’s say I have this service configuration

 

 <?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="WindowsAzureProject1" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="1" osVersion="*">
  <Role name="MvcWebRole1">
    <Instances count="1" />
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" 
               value="UseDevelopmentStorage=true" />
      <Setting name="Greeting" value="Hello from Azure (Dev) Web Role!" />
    </ConfigurationSettings>
  </Role>
</ServiceConfiguration>

 

and want to deploy the service to the cloud with:

 


<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="WindowsAzureProject1" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="1" osVersion="*">
  <Role name="MvcWebRole1">
    <Instances count="2"/>
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" 
         value="DefaultEndpointsProtocol=https;AccountName=[cloud account];AccountKey=[account key]"/>
      <Setting name="Greeting" value="Hello from Azure (Published) Web Role!"/>
    </ConfigurationSettings>
  </Role>
</ServiceConfiguration>

 

While it is possible to modify .cscfg via a generic Xslt transformation, it is preferable to use transform file using the http://schemas.microsoft.com/XML-Document-Transform syntax (as used with ASP.NET 4.0 projects). The transform file to use, ServiceConfiguration.Publish.cscfg, could look like:


<?xml version="1.0" encoding="utf-8"?>
<sc:ServiceConfiguration serviceName="WindowsAzureProject1" osFamily="1" osVersion="*"
  xmlns:sc="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration"
  xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <sc:Role name="MvcWebRole1" xdt:Locator="Match(name)">
    <sc:Instances count="2" xdt:Transform="Replace" />
    <sc:ConfigurationSettings>
      <sc:Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" 
          value=" DefaultEndpointsProtocol=https;AccountName=[cloud account];AccountKey=[account key]" 
          xdt:Locator="Match(name)" xdt:Transform="Replace" />
      <sc:Setting name="Greeting" value="Hello from Azure (Published) Web Role!" xdt:Locator="Match(name)" xdt:Transform="Replace" />
    </sc:ConfigurationSettings>
  </sc:Role>
</sc:ServiceConfiguration>

 

This resembles the original configuration file but contains only items that need to be added, modified or removed (notice xdt:Locator and xdt:Tranform attributes).

To make the transformation work, one needs to import and use TransformXml task within a target which executes after the “CorePublish” task.

 

Here is how (as the Cloud Service projects allows for limited actions what can be added using VS UI, the file need to be added and .ccproj file edited manually):

 

1.       Copy the transform file (ServiceConfiguration.Publish.cscfg) to the cloud service folder (in Windows Explorer).

2.       Unload the Cloud Service Project (right-click the project, then select Unload Project).

3.       Open the project file for editing (Right-click the project, then select Edit [project name].ccproj).

4.       Add the following task after the last target in the project file:

 

<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets" />

<ItemGroup>
    <EnvironmentConfiguration Include="ServiceConfiguration.Publish.cscfg">
      <BaseConfiguration>ServiceConfiguration.cscfg</BaseConfiguration>
    </EnvironmentConfiguration>
    <None Include="ServiceConfiguration.Publish.cscfg">
      <DependentUpon>ServiceConfiguration.cscfg</DependentUpon>
    </None>
  </ItemGroup>
  <Target Name="TransformEnvirontmentConfiguration" AfterTargets="CorePublish">
    <MakeDir Directories="$(OutDir)TransformCscfg" />
    <Copy SourceFiles="$(OutDir)Publish\%(EnvironmentConfiguration.BaseConfiguration)" 
        DestinationFiles="$(OutDir)TransformCscfg\%(EnvironmentConfiguration.BaseConfiguration)" />
    <TransformXml Source="$(OutDir)TransformCscfg\%(EnvironmentConfiguration.BaseConfiguration)" 
        Transform="%(EnvironmentConfiguration.Identity)" 
        Destination="$(OutDir)Publish\%(EnvironmentConfiguration.BaseConfiguration)" />
    <Message Importance="high" 
        Text="Transformed %(EnvironmentConfiguration.BaseConfiguration) using %(EnvironmentConfiguration.Identity) into $(OutDir)Publish\%(EnvironmentConfiguration.BaseConfiguration)" />
  </Target>

 

5.       Save and close the file, then reload the project.

 

 

The above fragment imports ASP.NET 4.0 MsBuild targets, includes the transform file into the project fold and defines a new target named "TransformEnvironmentConfiguration" to be executed before "CorePublish" (one of the Cloud Service project tasks). The transform task internally makes a working folder TransforCscfg, where it copies the service configuration file, after which the required transformatino takes place. Note that copying to the working folder is a workaround to the bug in TransformXml which keeps a lock and prevent successful completion of the MsBuild script.

 

Now when the Cloud Service project is published to the cloud or to the intermediary location, the transformation kicks in.

If the project was published locally, it can be executed in "mixed mode", i.e. running in the compute emulator while using cloud storage service and other resources by adding yet another another task to the project: 

 

  <Target Name="RunPublishedServiceConfig">
    <Exec Command="&quot;$(ServiceHostingSDKInstallDir)bin\csrun.exe&quot; /run:$(OutDir)$(ProjectName).csx;$(OutDir)Publish\%(EnvironmentConfiguration.BaseConfiguration) /launchbrowser" />
  </Target>

 

The task can be then invoked as an external tool from Visual Studio as follows:

Command: C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
Arguments: $(ProjectDir)$(ProjectFileName) /T:RunPublishedServiceConfig

This works well for an ideal solution where the roles use RoleEnvironment class to obtain settings and connection strings. In Azure deployments, storing these in web.config and app.config files is very close to "hard coding", as any change requires re-deployment of the service. In a previous project I was able to add similar transforms for each web and worker role .config. What remains is to enable multiple transforms for different deployment targets, such a staging and production. I hope I'll figure it out before the next Azure project.

Posted: Jul 01 2011, 10:11 by Milenko.Djuricin | Comments (1) RSS comment feed

Tags:
Categories: Azure | Custom Application Development

Persistence in WF 4.0

From time to time I would get into problems with persisted workflows, e.g. I could not resume it nor terminate it due to the system being unable to de-serialize workflows. If we change a workflow or any type that is serialized with it – there could be, actually there will be problems with long running and persisted workflows for sure.

WF 4.0 is much easier in this respect, since the new persistence provider serializes only the activities containing active bookmarks and the objects in the current scope. In many cases versioning effort can be limited by focusing on the fields added to the custom types, where .NET serialization attributes, such as [System.Runtime.Serialization.OptionalField] can be of great help.

 

Posted: Aug 31 2010, 11:40 by Milenko.Djuricin | Comments (3) RSS comment feed

Tags:
Categories: Custom Application Development | Workflow Foundation

Down Here and Far Away

What is common between a low level component, such as Virtual Hard Disk (VHD), and high and far away platform such as Windows Azure?

As in ‘high and away’ almost everything is virtualized, VHD fits nicely as a part of cost/performance effective facility (CloudDrive), supporting applications that still use local file system and IO.

EveryPenny uses CloudDrive for content management. Relevant parts of the solution are:

  • IncludeContent custom ASP.NET control, for declarative inclusion of items from the content drive,
  • Content.axd, for handling client requests for content items,
  • ContentUploader, a WPF application enabling users to select a local folder, convert it to a VHD image and upload to the cloud page blob, and
  • CloudDriveMonitor, an object used by web applications to keep with content changes.

Some of the ideas were ‘inspired’ by an excellent blog on everything related to Azure development

Thanks to Marc Kuperstein for forwarding and pursuing these ideas.

Posted: Jul 19 2010, 04:41 by Milenko.Djuricin | Comments (0) RSS comment feed

Tags:
Categories: Azure | Custom Application Development

About Milenko Djuricin


RSS Feed

Tags

Categories

Archive

Blogroll

Neudesic Social Media

Follow Neudesic on Twitter Follow Neudesic on Facebook Neudesic Neudesic