Reusing environment-specific tenant variables across projects

I’ve been following the working with tenant-specific variables documentation but I’m concerned about how to reuse variables across projects. I have a scenario that is less than ideal, but it’s what I have to work with. Basically, I have many tenants, each with multiple environments, say DEV and QA, and they have variable values that are different between DEV and QA. Octopus handles this scenario via project templates – the wrench I am throwing into the machine however, is that I have many different projects which need to reference these variables, and managing them on each project is error-prone and redundant. If this isn’t clear, I’ll attempt to illustrate what I mean with a more detailed example below.

Consider tenant A and tenant B, both of which have a DEV environment running a JBoss application server listening on different ports, say 8080 and 8081 respectively.

I have a project called Project-1 in which I need to reference this JBoss port – that’s easy enough, I add a project template named jboss.http.port to the project. Now when I view the variables for my two tenants, I can set the value appropriately for each of them. This works great and my tenant “variable model” looks like so:

Tenant A
  Project-1
    DEV
      jboss.http.port=8080
Tenant B
  Project-1
    DEV
      jboss.http.port=8081

Now consider a scenario where I need to create a new deployment project, Project-2, that also needs to use the JBoss port. I can do the same exercise as above by creating a project template, but now I have to manage the same variable in 2 places for every tenant – I have to set it for Project-1 and Project-2 for both tenant A and B. Now my tenant model looks like this:

Tenant A
  Project-1
    DEV
      jboss.http.port=8080
  Project-2
    DEV
      jboss.http.port=8080
Tenant B
  Project-1
    DEV
      jboss.http.port=8081
  Project-2
    DEV
      jboss.http.port=8081

What happens when I have 5 projects that need to use the port? When I on-board a new tenant, I’ll have to set that same variable in all 5 projects? I see this quickly turning into a mistake-prone, maintenance nightmare.

So naturally that leads to creating library variable templates – here, I can create my jboss.http.port variable, and include this library template for all 5 of my projects. Now when I on-board a new tenant or need to update the JBoss port, I only need to set the variable in one single place. This is much easier to manage and solves the above problem. Now my tenant model is:

Tenant A
  Common variable set
    jboss.http.port=8080
Tenant B
  Common variable set
    jboss.http.port=8081

* Project-1 and Project-2 both use 'Common variable set' *

However, consider one final scenario (this is the “wrench” I mentioned throwing into the machine). Let’s say my tenant A adds a QA environment, and that JBoss runs on a different port than DEV, say 8082. Now I run into a problem that as far as I can tell, has no solution. Using a library variable template (AKA common variables – this example is shown above) won’t work – the documentation I linked at the beginning of this post states:

Common variables are variable values that remain constant across projects and environments for this tenant

So these common variables templates are shared across environments – meaning I cannot set my jboss.http.port variable individually for DEV and QA – I can only set one value and both DEV and QA share it. This doesn’t work for my tenant A because their DEV and QA JBoss use different ports.

Now we come full circle to the original problem I posed – the way to accomplish what I need to do is to use project-level variable templates, but then I have to manage the same variable in multiple places. Has anyone accomplished what I am trying to do? I might be overlooking something, as tenant-specific variables is a much more complicated deployment scenario.

I realize that our tenant model is not ideal, with specific VMs having differing variables, but that’s just the way it is (for right now) and I have to work with it.

This is one area where tenant variables can be a bit confusing and tricky. Your initial thought in using library variable sets is the approach I’d recommend. There are some tricks you can apply to make them work.

Option 1 - Multiple Common Variables

It seems odd, but you can have multiple common variables, yet a single variable reference. In the library variable set you’d add [VariableName].[EnvironmentName].

image

On the main variable screen (or the library variable screen) you’d then reference those variables and scope them to the appropriate environments.

Option 2 - Tenant Tags

Variables can be scoped to tenant tags. You can access the tenant tags by clicking on the open editor button when selecting the scope:

Which for me brings up:

Then when you are setting up the tenant you can specify the tenant tag you wish to use.

Option 3 - Config file per tenant

This one requires a bit more code changes, but another option is to have a config file per tenant then leverage Octopus to manipulate the main config file to pick which file to load. I’m hesitant to recommend this as I am not a Java expert (I’m a .NET developer at heart), so this could be fraught with dragons and rabbit holes.

I hope that helps!

Thanks for the response Bob, I think I’ll try giving the tenant tags a shot. Are there any plans to introduce new functionality for tenant variables? If there were a way to scope common variables to an environment within a tenant (or some similar mechanism), that would be amazing.

It’s on our list of items to improve, but no idea about the timetable. We have some other big items being worked on that are taking up the majority of the engineering resources. :slight_smile: