CloudService NuGet package structure for .config files

Hi, i’m trying to understand how I should compose my nuget package for Octopus that will include my cspkg file when i want Octopus to run config tranformations.

I currently have multiple roles within my service where each role has its own config files. It does not seem possible to include the transformation files when packing my cloud service, but from reading about the changes in 3.0+ this seems to be possible using Octopus.

Should I include the config files in the root of the package? Is there a naming convetion for dealing with multiple roles or is just 1 role supperted?

Can you shed som light on this for me?

Hi,

Thanks for reaching out. You’re gonna need to put the config files in the root of your cspkg file:

.Nupkg
  |--.cscfg
  |--.cspkg
     |--web.config
     |--web.transform.config 

Once Octopus extracts the nupgk file (which contains the cspkg) it’ll extract the cspkg and run the transformations you’ve configured in your NuGet Deploy step => http://docs.octopusdeploy.com/display/OD/Configuration+files#Configurationfiles-ConfigurationTransforms

Hope that helps!

Dalmiro

  1. First of all how do I actually make the web.transform.config a part of the cspkg file?
  2. From reading about the different formats for cspkg I cannot see that the structure you suggest would work. How does Octopus understand that the web.transformation.config relates to a specific Role?

Hi,

  1. Add the transform file to your Web role inside your solution and set the file’s Right click -> Properties -> Copy Output Directory to “Copy Always”

  2. Before pushing the cspkg to Azure, Octopus will unpack its content on a physical directory which you can resolve using the Octopus variable #{Octopus.Action.Azure.PackageExtractionPath}. In the examples below this variable resolves to *C:\Octopus\Work\20150831133421-5*

I created a test azure service which looks like solution.jpg. When Octopus extracts the cspkg content before pushing it to azure, the config files land on the following location:

  • Web.config - C:\Octopus\Work\20150831133421-5\LocalContent\WebRole1\approot\web.config

  • Web.Debug.Config - C:\Octopus\Work\20150831133421-5\LocalContent\WebRole1\approot\bin\web.debug.config

So If I wanted to use web.debug.config file to transform web.config, I would enable the Configuration Transform feature and on the NuGet deploy step, and set the content of the “Additional Transforms” field to

#{Octopus.Action.Azure.PackageExtractionPath}LocalContent\WebRole1\approot\bin\web.debug.config => #{Octopus.Action.Azure.PackageExtractionPath}\LocalContent\WebRole1\approot\web.config

Check transform.jpg to see how would that field look like once everything is set.

As you can see the config files are under a folder with the same name as your role (in my case “WebRole1”). By adding the full path on the “Additional Transform” field, you are telling Octopus exactly which transform goes with which web.config.

Hope it makes more sense now :slight_smile:

Dalmiro

Pro tip: If you are not sure how the folder structure looks like while Octopus is deploying/extracting your cspkg, add a Script in your package step with the line get-childitem -recurse to your deployment. This will recursively list all the files under #{Octopus.Action.Azure.PackageExtractionPath}. Then check your deployment log to see the result of Get-Childitem and then configure your config transformations based on that folder structure.

Thank you, I just managed to resolve this myself but with a slightly different solution:

I added the transformationfiles into the root of the nuget with a specific folder structure:

Absolutely valid workaround :slight_smile:

Dalmiro, these steps don’t appear to work as proposed.

I created a new AzureCloudService exactly as you have except instead of Web.Debug.Config, I had an additional Web.Azure.config. I then set that to ‘Copy Always’ so it would be copied to the projects bin folder on build.

I packaged the cloud service using Visual Studio’s Package… command. The package command dumps the cloud service package into a bin/Release/app.publish folder, so using a nuspec with

<file src="bin\Release\app.publish\*.*" target="" />

I was able to generate a nuget package from the command line with nuget pack AzureCloudService.nuspec -Version 1.0.0 and upload that package to the Octopus nuget feed.

In Octopus I setup a project to deploy that using the Azure Cloud Service deployment step and enabled the Configuration Transformation feature. As per your suggestion I added an Additional Transform of:

#{Octopus.Action.Azure.PackageExtractionPath}\LocalContent\WebRole1\sitesroot\0\bin\web.Azure.config => #{Octopus.Action.Azure.PackageExtractionPath}\LocalContent\WebRole1\sitesroot\0\web.config

But no transformation takes place.

Note: My sample projects web.config transformation consists of a single appsetting:

	<appSettings>
		<add key="WhereDidIComeFrom" value="DefaultWebConfig" />
...
	</appSettings>

with the config file looking like:

<?xml version="1.0" encoding="utf-8" ?>

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">

	<appSettings>
		<add xdt:Transform="SetAttributes" xdt:Locator="Condition(@key='WhereDidIComeFrom'])" value="AzureConfig" />
	</appSettings>

</configuration>

Even if I put in an invalid path such as

#{Octopus.Action.Azure.PackageExtractionPath}\I_DONT_EXIST\LocalContent\WebRole1\sitesroot\0\bin\web.Azure.config => #{Octopus.Action.Azure.PackageExtractionPath}\LocalContent\WebRole1\sitesroot\0\web.config

Octopus doesn’t complain or show any errors. It simply doesn’t do anything with custom transforms.

Am I doing something wrong here or is there an issue with Octopus transforming config transforms.

I have a similar issue as caseymarcallen. Though in my case, everything BUT web.config is transformed (provided they have a valid tranform file). All transform files are set as “content”, and if i extract the .cspkg file, all transforms are there. It just seems that web.config is ignored. I even tried adding a custom web.staging.config => web.config, but it did nothing.

See (cleaned, i removed the actual transformation info lines) log below,as you can see, the episerverlog.config file is correctly transformed both in the root, and in the package subfolders, but the web.config files in subfolders of the .cspkg file are ignored.

Octopus Server version: 3.2.3+Branch.master.Sha.d5
Using account ID 'SNIP’
Octopus Deploy: Calamari.Azure version 3.1.8+Branch.master.Sha.e4
Deploying package: D:\Octopus Deploy\Data\Packages\Acme.nupkg
Extracting package to: D:\Octopus Deploy\Data\Work\20160113133839-19
Extracted 2842 files
Ensuring cloud-service-package is V20120315 format.
Package is Legacy format. Converting to V20120315 format.
Extracting Cloud Service package: 'D:\Octopus Deploy\Data\Work\20160113133839-19\Acme.cspkg’
Azure Cloud Service Configuration file (*.cscfg) not found: D:\Octopus Deploy\Data\Work\20160113133839-19\ServiceConfiguration.Staging.cscfg
Found Azure Cloud Service Configuration file: D:\Octopus Deploy\Data\Work\20160113133839-19\ServiceConfiguration.Cloud.cscfg
Loading certificate with thumbprint: SNIP
Certificate was found in store
Local instance counts (from ServiceConfiguration.Cloud.cscfg):

Updating configuration settings…
No settings that match provided variables were found.
Transforming ‘D:\Octopus Deploy\Data\Work\20160113133839-19\EPiServerLog.config’ using ‘D:\Octopus Deploy\Data\Work\20160113133839-19\EPiServerLog.Staging.config’.
Transforming ‘D:\Octopus Deploy\Data\Work\20160113133839-19\Web.config’ using ‘D:\Octopus Deploy\Data\Work\20160113133839-19\Web.Staging.config’.
Transforming ‘D:\Octopus Deploy\Data\Work\20160113133839-19\Web.config’ using ‘D:\Octopus Deploy\Data\Work\20160113133839-19\Web.Release.config’.
Transforming ‘D:\Octopus Deploy\Data\Work\20160113133839-19\LocalContent\ACME\approot\EPiServerLog.config’ using ‘D:\Octopus Deploy\Data\Work\20160113133839-19\LocalContent\ACME\approot\EPiServerLog.Staging.config’.
Transforming ‘D:\Octopus Deploy\Data\Work\20160113133839-19\LocalContent\ACME\sitesroot\0\EPiServerLog.config’ using ‘D:\Octopus Deploy\Data\Work\20160113133839-19\LocalContent\ACME\sitesroot\0\EPiServerLog.Staging.config’.

Looking for appSettings and connectionStrings in any .config files

Sorry for the terrible log formatting… This might be readable:

Octopus Server version: 3.2.3+Branch.master.Sha.d5
Using account ID 'SNIP'
Octopus Deploy: Calamari.Azure version 3.1.8+Branch.master.Sha.e4
Deploying package:    D:\Octopus Deploy\Data\Packages\Acme.nupkg
Extracting package to: D:\Octopus Deploy\Data\Work\20160113133839-19
Extracted 2842 files
Ensuring cloud-service-package is V20120315 format.
Package is Legacy format. Converting to V20120315 format.
Extracting Cloud Service package: 'D:\Octopus Deploy\Data\Work\20160113133839-19\Acme.cspkg'
Azure Cloud Service Configuration file (*.cscfg) not found: D:\Octopus Deploy\Data\Work\20160113133839-19\ServiceConfiguration.Staging.cscfg
Found Azure Cloud Service Configuration file: D:\Octopus Deploy\Data\Work\20160113133839-19\ServiceConfiguration.Cloud.cscfg
Loading certificate with thumbprint: SNIP
Certificate was found in store
Local instance counts (from ServiceConfiguration.Cloud.cscfg): 

<SNIP>

Updating configuration settings...
No settings that match provided variables were found.
Transforming 'D:\Octopus Deploy\Data\Work\20160113133839-19\EPiServerLog.config' using 'D:\Octopus Deploy\Data\Work\20160113133839-19\EPiServerLog.Staging.config'.
Transforming 'D:\Octopus Deploy\Data\Work\20160113133839-19\Web.config' using 'D:\Octopus Deploy\Data\Work\20160113133839-19\Web.Staging.config'.
Transforming 'D:\Octopus Deploy\Data\Work\20160113133839-19\Web.config' using 'D:\Octopus Deploy\Data\Work\20160113133839-19\Web.Release.config'.
Transforming 'D:\Octopus Deploy\Data\Work\20160113133839-19\LocalContent\ACME\approot\EPiServerLog.config' using 'D:\Octopus Deploy\Data\Work\20160113133839-19\LocalContent\ACME\approot\EPiServerLog.Staging.config'.
Transforming 'D:\Octopus Deploy\Data\Work\20160113133839-19\LocalContent\ACME\sitesroot\0\EPiServerLog.config' using 'D:\Octopus Deploy\Data\Work\20160113133839-19\LocalContent\ACME\sitesroot\0\EPiServerLog.Staging.config'.
...
Looking for appSettings and connectionStrings in any .config files
....

In my case, after further examination, it seems that the web.config transformation files were indeed not part of the cspkg file.

I added a predeploy script to copy the transforms from the root folder to the approot and sitesroot\0 folders and now they are located by octopus and transforms applied.

Sorry for adding to the confusion here…