Variable replacement in ServiceDefinitions.csdef

I’ve scoured the help me sections and previous discussion posts regarding the replacement of the VMSize within the servicedefinitions.csdef file and are still stumped I’m afraid. Scrubbed verbose log file attached.
Majority of the posts read appear to be pre version 3 and still refer to using powershell within the predeploy scripts. I am trying to utilize the new ‘Substitute variables in files’ functionality but to no avail. Probably a wood for the trees thing but would appreciate anyone pointing out my folly.

Firstly the deployment runs fine when the variable #{CloudAnalytics.WorkerRole.VMSize} and #{CloudAnalytics.WebRole.VMSize} are not in the definition file. I can confirm they are definitely in the package being used to create a release. I can confirm I have those two variables as project variables (also visible in the attached log).
It just doesn’t appear to be carrying out the substitution for some reason.

Any help gratefully appreciated.

ServerTasks-2783.log.txt (42 KB)

I had this working (replacing-in-files with variables 4 weeks ago -> needed to make host headers generic/replaceable for dev/int/prod envs -> we use TeamCity to build -> so file winds up in ServiceDefinition/ServiceDefinition.csdef in the package, so I target that file for replacement.) Possibly with our recent update to Octopus, this seems to have stopped working (can’t confirm that’s the cause - can’t FULLY guarantee the vars were being replaced before except that there is heavy circumstantial evidence … azure was responding to the host headers properly and bringing up the bound site … this should not have worked if the replacements weren’t happening. Also my guess is that 4 weeks ago I would have peered inside the artifacts to confirm the replacements - I just can’t promise that. Now I’m inspecting the site bindings in IIS in Azure and they are whatever the actual variable name was i.e. “#{}”, rather than the replacement value - which of course no longer works.)

I DO get this in my verbose octopus output … but … they aren’t getting replaced. .

Performing variable substitution on ‘W:\Octopus\Work\20160915133729-348\staging\ServiceDefinition\ServiceDefinition.csdef’

Also looking for solution.

Ah ha… thanks Doug! Perhaps it is not my novice use of the product then!
FYI After posting this yesterday I noticed that 3.4.8 release was available
and tried that, alas still no improvement.

Kind Regards


Hey Gareth –

I don’t THINK it’s your novice use … I unfortunately had a week of vacation and then a week off this project just after it stopped workiing … just at about the time we had upgraded octopus … so that’s why I don’t remember if I actually proved that my host headers had been replaced … but I THINK I had … and the fact that IIS accepted my requests back then with those host-headers says it had to have made it.

If when I figure this out -> will get you an email (and probably update the forum post)

Spot on, thanks Doug!

Hi Gareth,
We have had several other users who have been able to successfully perform csdef transformations in the past after a bit of extra scripting. Check out this other thread for a discussion of what steps the user took to get it working. Have you tried including the Octopus.Action.Azure.LogExtractedCspkg variable to double check that the right csdef file is being replaced? Unfortunately I’m sorry to say that its currently not a 1-step process, but it certainly should work and so far I have not heard of any breakages as a result of any new versions.
Let me know if this extra information helps you to get the deployment working.

Thanks Rob – I’ll try this (these) over next couple days and update. Appreciate it!

Resorting back to editing it via the Predeploy.ps1 as per the link below
has done it for me. All working.

Certainly wasn’t as simple as using the variable substitution functionality
though unfortunately.

Kind Regards


Hi Rob, all sorted thanks using the predeploy script approach. Not sure why
the variable substitution in files functionality didn’t work but hey… its
working so I’m happy.

Thanks for your email.

Kind Regards


Bob –

I used the powershell approach. No luck – valid tactic, but a different problem – it’s not looking at the full csdef contents.

Here’s why.

At the time the script is run, while the csdef has been extracted -> the IIS WEBSITE configuration is NO LONGER in the csdef – essentially the node as been ripped out (presumably in preparation for it to be applied against the azure webrole) …

I tested the script locally against a copy of a csdef and … no problem – great.

And … the script runs when it should (as a custom script) … however, it kept failing, so I included in the script a line to output the contents of the csdef it had actually loaded at deploy time. … and … no site configuration.

I used the test boxes in the octopus step to add the scripting. Would there be any difference in the time it executed if I include ‘predeploy.ps1’ in the actual project?


Hi Doug,
As you can see here in Calamari, there is essentially no real difference between using the PreDeploy step feature or the PreDeploy.ps1 embedded script except that the feature runs just before the packaged one.
As you might have read in the the previously posted thread, the csdef is modified at build time, before Octopus gets it’s hands on the file and has a chance to do anything with it. The user had to manually reconfigure the expected elements in the predeploy script before variable substitution. If you manually open up the package you will probably notice that the csdef is slightly different to the “untouched” csdef in your development environment.
The options appear to currently be either manually ensure that the unadulterated csdef is put back into the package during package creation, or manually tweak the config during deployment to ensure it has the pieces you are after. This second option might make more sense being an in-package PreDeploy.ps1 script so that it can version and live alongside your solution itself.
Hope that helps,

Thanks Rob –

I understood the cleaning that was occurring in the other user’s example – where his VM size was the default, and so it got cleaned out.

But consider this: the section of the and ’s configurations is a much larger section, responsible for the configuration of IIS. If that WHOLE section is missing – does it suggest that Octopus has removed it permanently?

In other words – I think you are suggesting that using the predeploy – I ‘stick it back in there.’ … but I’m just confused as to why it was removed, and if it was removed from the csdef, where is it getting applied at all (It IS getting applied by the way) (The settings DO get applied to IIS -> but the hostheader bindings – which is what I’m trying to replace – remain the literal octopus variable -> rather than what should replace it. So those removed settings are getting applie


Rob –

It looks like all the IIS settings (i.e. things in the node, child of ) get extracted from the WebRole node in the csdef and re put in RoleModel.xml.

Thanks for your note this morning – I hadn’t put it together that the build might also be performing significant changes on the IIS Config (rather than just ‘simplifying’ things like vmsize if they were explicitly set to the defaults … I’m actually surprised I didn’t notice that before when inspecting files … but new at this so not detecting everything.

So … it LOOKS like the build extracts the nodes from the csdef and injects it into the rolemodel.xml file which is not a source controlled file, but a pure build artifact, and is what is applied against IIS in azure to configure the websites/directories/applications/bindings.

I believe I just got it working as follows (only the second line is necessary for the bindings – we are also doing replacement to other portions of the csdef) … the IIS bindings in azure are properly reflecting the replacement.