Windows #Azure configuration transformations

Hi,

I needed to update the transformation today to support different csdef files for UAT/Test etc. I found myself forgetting the process, so i thought it would be a good idea to log the entries needed.

What I wanted was a way to disable New Relic in our performance environment, since we do not have a license key.

Since we use the Azure Tasks to run batch jobs before the worker role starts, it made sense that I create a TASK Environment variable that my batch script can check and see if it should install New relic, e.g.

if "%MYSTORYENV%" == "PERF" goto :EOF

So, in the above, my batch file startup.cmd will skip installing new relic if the environment variable is PERF. However we need to set this value in the csdef file.

So we go to the BASE servicedefinition.csdef file and have this entry for it.

<sd:Startup>
      <sd:Task commandLine="Startup.cmd" executionContext="elevated" taskType="background">
        <sd:Environment>
          <sd:Variable name="EMULATED">
            <sd:RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
          </sd:Variable>
          <sd:Variable name="MYSTORYENV" value="DEV" />
        </sd:Environment>
      </sd:Task>
    </sd:Startup>

Notice, that I have qualified all my csdef entries, this is important for transformations to occur (sd:)

Ok, the next step is that we create a transformation file

https://gist.github.com/1777060

Now, that we have this transform, we will need to edit the CSPROJ file. Please see below the parts added

Item Groups

<ItemGroup>
<ServiceDefinition Include="ServiceDefinition.csdef" />
<ServiceConfiguration Include="ServiceConfiguration.cscfg" />
</ItemGroup>
<ItemGroup>
<EnvironmentDefinition Include="ServiceDefinition.uat.csdef">
<BaseConfiguration>ServiceDefinition.csdef</BaseConfiguration>
</EnvironmentDefinition>
<EnvironmentDefinition Include="ServiceDefinition.perf.csdef">
<BaseConfiguration>ServiceDefinition.csdef</BaseConfiguration>
</EnvironmentDefinition>
<EnvironmentConfiguration Include="ServiceConfiguration.uat.cscfg">
<BaseConfiguration>ServiceConfiguration.cscfg</BaseConfiguration>
</EnvironmentConfiguration>
<EnvironmentConfiguration Include="ServiceConfiguration.perf.cscfg">
<BaseConfiguration>ServiceConfiguration.cscfg</BaseConfiguration>
</EnvironmentConfiguration>
<None Include="@(EnvironmentConfiguration)" />
<None Include="@(EnvironmentDefinition)" />
</ItemGroup>

Notice I have the include at the bottom, so I can see these in Visual Studio. I also have transformations for cscfg files, hence the reason why you see them here Smile

Targets Validation

<Target Name="ValidateServiceFiles"
		Inputs="@(EnvironmentConfiguration);@(EnvironmentConfiguration->'%(BaseConfiguration)');@(EnvironmentDefinition);@(EnvironmentDefinition->'%(BaseConfiguration)')"
		Outputs="@(EnvironmentConfiguration->'%(Identity).transformed.cscfg');@(EnvironmentDefinition->'%(Identity).transformed.csdef')">

	<Message Text="ValidateServiceFiles: Transforming %(EnvironmentConfiguration.BaseConfiguration) to %(EnvironmentConfiguration.Identity).tmp via %(EnvironmentConfiguration.Identity)" />
	<TransformXml Source="%(EnvironmentConfiguration.BaseConfiguration)" Transform="%(EnvironmentConfiguration.Identity)" Destination="%(EnvironmentConfiguration.Identity).tmp" />
	<Message Text="ValidateServiceFiles: Transformation complete; starting validation" />

	<Message Text="ValidateServiceFiles: Transforming %(EnvironmentDefinition.BaseConfiguration) to %(EnvironmentDefinition.Identity).tmp via %(EnvironmentDefinition.Identity)" />
	<TransformXml Source="%(EnvironmentDefinition.BaseConfiguration)" Transform="%(EnvironmentDefinition.Identity)" Destination="%(EnvironmentDefinition.Identity).tmp" />
	<Message Text="ValidateServiceFiles: Transformation complete; starting validation" />

	<ValidateServiceFiles ServiceDefinitionFile="@(ServiceDefinition)" ServiceConfigurationFile="%(EnvironmentConfiguration.Identity).tmp" />
	<ValidateServiceFiles ServiceDefinitionFile="%(EnvironmentDefinition.Identity).tmp" ServiceConfigurationFile="@(ServiceConfiguration)" />
	<Message Text="ValidateServiceFiles: Validation complete; renaming temporary file" />

	<Move SourceFiles="%(EnvironmentConfiguration.Identity).tmp" DestinationFiles="%(EnvironmentConfiguration.Identity).transformed.cscfg" />
	<Move SourceFiles="%(EnvironmentDefinition.Identity).tmp" DestinationFiles="%(EnvironmentDefinition.Identity).transformed.csdef" />
</Target>

Notice above I have them for BOTH CSCFG and CSDEF files!

Move transforms to the app.publish folder for azure packaging

<Target Name="MoveTransformedEnvironmentConfigurationXml" AfterTargets="AfterPackageComputeService" Inputs="@(EnvironmentConfiguration->'%(Identity).transformed.cscfg')" Outputs="@(EnvironmentConfiguration->'$(OutDir)app.publish\%(filename).cscfg')">
<Move SourceFiles="@(EnvironmentConfiguration->'%(Identity).transformed.cscfg')" DestinationFiles="@(EnvironmentConfiguration->'$(OutDir)app.publish\%(filename).cscfg')" />
<Move SourceFiles="@(EnvironmentDefinition->'%(Identity).transformed.csdef')" DestinationFiles="@(EnvironmentDefinition->'$(OutDir)app.publish\%(filename).csdef')" />
</Target>

Summary

So there you have it, you will now have csdef and cscfg files for different environments.

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s