Getting started with variables

You can manage the variables for your projects, by navigating to your project in the Project tab of the Octopus Web Portal and selecting Project Variables:

Project variables in Octopus Deploy

Creating hello world variables

In this example, we’ll add a variable to a Hello World project that runs a script to say hello. The project uses the variable to vary the message it displays based on the environment the script is deployed to.

  1. To add a variable to your project, navigate to the Project’s Overview page, and click Variables to access the variable editor.
  2. Give the variable a name, for instance, Greeting.
  3. Enter the first value for the variable, for instance, Hello, Test, in the value field.
  4. Define the scope for the value, for instance, by selecting the Test environment.
  5. Click ADD ANOTHER VALUE and enter the second value for the variable, for instance, Hello, Production.
  6. Define the scope for this value, for instance, by selecting the Production environment.

Adding a project variable in Octopus Deploy

  1. Save the variable by clicking SAVE.
  2. In this example, we’ll reference this variable from a Run a Script step.
  3. Define your step (Click Process ➜ ADD STEP ➜ Run A Script) and in the Script Content section, enter the following PowerShell script into the script editor:
Write-Host
  1. Select the variable Greeting from the insert variable tool (#) next to the script editor, and click SAVE.

Using a variable in a Hello World script in Octopus Deploy

When a release of the project is deployed, the script step will run with the string Hello, Test on the Test environment, and with the string Hello, Production, on the Production environment.

Scoping variables

The variables that you define for your projects in Octopus can be scoped in the following ways:

  • Environments (most common)
  • Deployment targets
  • Target tags
  • Deployment steps
  • Channels
  • Tenants
  • Deployment Process or Runbook Process

Scoping the values of your variables lets you determine which values will be used in which situations. For example, suppose this variable exists:

NameValueEnvironment scope
LogLevelInfo
LogLevelWarnProduction, Staging

During deployment, Octopus will try to select the most specifically scoped variable that applies. For example, when deploying to Production and Staging, the LogLevel value will be Warn, but to any other environment, it will fall back to the less-specific variable and have a value of Info instead.

Assigning scopes

You can set the scope of a variable values when you are creating or editing your variables, either from the Project Variable section of the project, or in the Variable Sets section of the Library. However, when you assign scope to variables that are part of a library variable set, the variables cannot be scoped to deployment steps or channels.

Library variables in Octopus Deploy

Using multiple scopes

You can scope the values of your variables in multiple ways. For instance, you might scope a value to both the Dev and Test Environments, and to a step within your process.

When the process runs, Octopus will use the scoped value for the Dev OR Test environments, AND the steps the value was scoped to.

VariableValueScope
MyVariableScopedEnvironment: Dev, Test; Steps: Step 1
MyVariableunscoped

With the above MyVariable variable, the scoped and unscoped values will be implemented as follows:

Step 1Step 2
Dev EnvironmentScopedUnscoped
Test EnvironmentScopedUnscoped
Stage EnvironmentUnscopedUnscoped

Scope specificity

Imagine you have one variable scoped to an environment (Production), and another scoped to a machine within the environment. Which value should Octopus choose?

Since variables can be scoped in many different ways, there needs to be a predictable, deterministic order in which they’re resolved. The list below is the priority in which variable scopes take precedence. The top items are higher priority than the bottom ones:

  1. The current step/action (most specific).
  2. The current machine.
  3. Target tags associated with the current machine and targeted by the current step.
  4. Target tags associated with the current machine.
  5. The target tenant (if tenant-features are enabled).
  6. The target tenant-tag (if tenant-features are enabled).
  7. The target environment.
  8. The target channel (if channels are enabled).
  9. The current deployment process or runbook process.
  10. The project.
  11. No scope (least specific).

For example, a LogLevel variable with a value scoped to to a target tag is considered by Octopus to be more specific than a value scoped to an environment. So when two possible values for a variable exist, Octopus will choose the “more specific” scope value over the less specific one.

Variable scoping also works like CSS rules; a value scoped twice is more specific than a value scoped once. For example, a variable scoped to an environment and a target tag is more specific than a variable scoped to just a target tag.

If two variables are scoped equally, Octopus will choose project-defined variables ahead of library-defined ones. If this still doesn’t resolve the conflict, the result is non-deterministic and you should not depend on a specific value being used. Instead, you should take care when scoping variables so they’re unlikely to conflict.

Mutually exclusive scopes

You can think of scopes of the same type as a grouping of logical OR expressions. Scopes of different types are evaluated as AND expressions between the groups of scopes.

As an example, a variable scoped to the Development environment, Production environment, and the Default channel would evaluate as (Development OR Production) AND (Default). This example results in a specific scope that requires a channel for the variable to evaluate. This means the variable won’t be usable in the context of a runbook as channels don’t apply in this context.

There are two distinct scoping scenarios we need to call out, one of which we mentioned above. These are:

  • Scoping to both a channel and a runbook process
  • Scoping a deployment process action and a runbook process

Generally, you can avoid mutually exclusive scopes by duplicating variable values and scoping appropriately for each value if needed.

Scoping variables to target tags

Variables can also be scoped to specific target tags. This means the variable will take the specified value only when it’s used on a deployment step that runs on a deployment target with the specified tag. This feature is useful when you want to use the same variable name multiple times and change their values depending on the target they’re running on.

Let’s say you have the following targets with their respective tags:

TargetTag
Target 1app-server
Target 2web-server

You want to deploy the same package on each server but the deployment path will be different between servers. In this case you can set the same variable (we’ll call it DeployPath) with a different value for each tag:

Using variables to control the deployment path in Octopus Deploy

Then, on your deployment step, you can set the Custom Install Directory to #{DeployPath}.

Using the DeployPath variable in Octopus Deploy

Variables and permissions

When applying permissions on variables via scopes, the only options that are checked against permissions are environments, targets, and tenants.

Variable casing

It’s important to understand how Octopus treats variables with regard to case sensitivity:

  • Variable names are case insensitive.
  • Variable contents are by default case insensitive. You can alter this behavior by using either the ToLower or ToUpper variable filters.

If you are using the Structured configuration variables feature, variable names are matched in a case insensitive way.

Variable Recommendations

Group variables into Variable Sets

Variables sometimes naturally fit into groups, and often you’ll find multiple applications will use these groups. Octopus has Variable Sets; allowing you to group variables into a reusable set so that they can be used by other projects.

Namespace variables

We recommend namespacing your variables to make identifying their use clearer. Examples of how this can work are:

  • A project-level variable that holds the value for a SQL Server user’s password could be Project.SQL.Password. Then you can have Project.SQL.Username. This adds clarity to the variable’s value and has the added advantage that the variables will show next to each other in the list of variables.
  • If you are using Variable Sets, use the set name as the first part of the variable name. A variable that holds an RSS feed URL in the set Global can be named Global.RSSFeed.Url.

Keep variable numbers low

If you have many configuration settings for your application and are using a variable for each value, it’s possible that Octopus may not be the best place for those values. Consider:

  • Are most settings relatively static?
  • Are the settings safe to be stored in clear text as they don’t hold a sensitive value?

If the answer to either question is yes, consider an external store for your variables. This might be a source control repository, a configuration management system, or a database.

Learn more

Help us continuously improve

Please let us know if you have any feedback about this page.

Send feedback

Page updated on Wednesday, March 6, 2024