Use variable substitutions for generic configurations in Octopus deploy

Snir Balgaly
Cloud Mind
Published in
4 min readFeb 10, 2022

The problem:

In many tenanted deployments we need to take care of some configuration values that are all parts of the same kind, but for different services.

For example, each service in the project has a LogEntries token, and although those variables all have the same job, they should be different in each and every service.

The obvious solution:

You can just create a different variable template for each service.

In this solution, we just act as if each token is a different variable for each and every service.

Before each new deployment, you will have to fill in each variable just like any other template variable.

The generic solution:

One could say that those variables are actually the same variable, and the fact that they should be different in each step means that they should be handled in the project variable section using scopes.

Let me try to explain.

Project templates variables and common template variables are the way to handle variables to the project, but if you need a little more specification (e.g a variable that should be different only on one step, or LogEntries token that are different for any service within the project) you can use the Project Variables section like this:

In here, you populate the same variable with different values for each role.

This solution is good, but I, personally, think that using the Project Variables section should only be used in very specific cases, and not as a common solution.

This solution has an amazing advantage and it’s the fact that all of those variables are the same in the package configuration and the actual code can be re-used easily no matter which service’s log settings we are creating.

The 2 disadvantages with this solution are:

  1. Harder variable management. When you have some variables to be populated in the tenant configuration and some in this section, you will probably get your team members confused with how to populate the variables.
  2. If you have lots of services and specifications, it will just get ugly and messy.

The best solution:

Variable substitutions.

What are Variable substitutions?

According to the Octopus Documentation, Variable substitutions are a flexible way to adjust configuration based on your variables and the context of your deployment. You can often tame the number and complexity of your variables by breaking them down into simple variables and combining them together using expressions.

In other words, we can use the value of a variable to help us construct another variable.

In this case, we can still keep using the Project Template variables, but still, have the same variable re-used on every settings’ file and changed based on the context of your deployment.

Let’s have a look.

As you can see here, it pretty much looks like the first solution but set in a different way where the variable contains two parts. The mutual part (LogEntries-token), and the service specification.

The fun part comes now.

While trying to be as generic as possible, we should put inside the square brackets the role name of the relevant step.

Then we can just use the #{Octopus.Action.TargetRoles} variable, and voilà. We can use the same variable in all configurations, YAMLs or whatever: #{logentries-token[#{Octopus.Action.TargetRoles}]}.

Let’s sum it up real fast.

NameValuelogentries-token[trendsgenerator]eab2fb1e-c310-1944-dbda-2e1f7e643588logentries-token[trendspublisher]dcb5aa2c-c654-4587-caab-4e1f7e879524Octopus.Action.TargetRoles~Returns role name~

#{logentries-token[#{Octopus.Action.TargetRoles}]} would evaluate to the relevant token according to the step it’s in.

I used the Variable Substitution article from the Octopus documentation, Check it out for some more idea for variable manipulations.

--

--