Updating Octopus Deploy Variables via the REST API with PowerShell

House icon

Published January 18, 2024

Heidi Housten

Welcome to our introductory blog post on using the Octopus Deploy REST API to modify Octopus Deploy variables. Octopus Deploy is a powerful tool for automating deployments, and being able to programmatically update variables removes one more manual step from your deployment processes.

In this article, we'll walk you through how to leverage PowerShell to interact with Octopus Deploy's REST API to change the value of a specific variable, be it a project or a library variable.

Why Modify Variables via the API?

Modifying variables through the API offers several advantages:

  • Automation: You can automate the process of updating variables, reducing manual effort and the risk of human error.
  • Integration: Integration with other tools and pipelines becomes seamless, allowing you to trigger variable updates as part of your deployment workflows.
  • Consistency: Ensure that your variables are always up to date, maintaining consistency across different environments and projects.
  • Efficiency: Make changes to multiple variables across multiple projects, say backend, frontend, and DB simultaneously, saving time and effort.

Getting Started

Before we dive into the PowerShell script, here's what you need:

  1. Octopus API Key: You'll need an Octopus Deploy API key with appropriate permissions to access and modify variables. The API key is used for authentication in API requests.
  2. Octopus Instance URL: Replace "https://yourInstance.octopus.app" with the URL of your Octopus Deploy instance.
  3. Space ID: Octopus Deploy uses spaces to separate different environments or projects. The default space ID is "Spaces-1", so replace it with your space ID if you're working a different space.
  4. Variable Set ID: You should provide the variable set ID of the variable you want to modify. This ID can be found in the Octopus Deploy web interface (see the notes section at the bottom). There is a minor difference between a project variable set name (variableset-Projects-61) and a library set name (variableset-LibraryVariableSets-21) with regards to identifiers the API needs. The script expects the entire name, as shown in the parentheses.
  5. Variable Name and New Value: Specify the name of the variable you want to update ($variableName) and the new value ($newValue) you want to assign to it.

The PowerShell Script

The PowerShell script below demonstrates how to change the value of a variable within Octopus Deploy using the REST API. It retrieves the existing variable set, finds the specified variable by name, updates its value, and then sends the updated variable set back to Octopus Deploy.

Before running the script, ensure you have the necessary permissions and have replaced the placeholders with your actual information.

Understanding the Script

Now, let's take a closer look at the PowerShell script and break it down step by step:


param(
    [Parameter(Mandatory=$true)]
    [string]$octopusAPIKey,
    [string]$octopusBaseUrl = "https://yourInstance.octopus.app",  
    [string]$spaceId = "Spaces-1",  
    [string]$variableSetId = "variableset-Projects-61",
    [string]$variableName = "componentVersion",
    [string]$newValue = "auto"
)
$ErrorActionPreference = "Stop"
$header = @{ "X-Octopus-ApiKey" = $octopusAPIKey }

# Get the variable set from Octopus
$libraryVariableSetVariables = (Invoke-RestMethod -Method Get -Uri "$octopusBaseURL/api/$spaceId/variables/$variableSetId" -Headers $Header) 

# Find the variable
$index = $libraryVariableSetVariables.Variables.name.IndexOf($variableName)

if ($index -ge 0) {
  # If the variable was found, update it.
  $libraryVariableSetVariables.Variables[$index].value = $newValue
  $UpdatedLibraryVariableSet = Invoke-RestMethod -Method Put -Uri "$octopusBaseURL/api/$spaceId/variables/$variableSetId" -Headers $Header -Body ($libraryVariableSetVariables | ConvertTo-Json -Depth 10)   
} else {
  # Otherwise, write out an error
  Write-Output ("Variable name [$variableName] not found. These are the available variable names:[{0}]" -f (($libraryVariableSetVariables.Variables.name) -join(',')))
}

# Write out the response from the update
write-host ($UpdatedLibraryVariableSet | convertto-json)

Let's go through script's steps:

Parameter Input

 param(
     [Parameter(Mandatory=$true)]
     [string]$octopusAPIKey,
     [string]$octopusBaseUrl = "https://yourInstance.octopus.app",  
     [string]$spaceId = "Spaces-1",  
     [string]$variableSetId = "variableset-Projects-61",
     [string]$variableName = "componentVersion",
     [string]$newValue = "auto"
 )

The script takes several parameters, including the Octopus API key, Octopus Base URL, Space ID, Variable Set ID, Variable Name, and New Value. These parameters allow you to customize the script for your specific use case and set your most common values as defaults. In a CI/CD pipeline, you would probably store the API key in a secret variable.

Error Handling

$ErrorActionPreference = "Stop"

The script sets the error action preference to "Stop" to ensure that any errors encountered during execution will stop the script and provide meaningful error messages.

Authentication Header

$header = @{ "X-Octopus-ApiKey" = $octopusAPIKey }

This creates an authentication header using the provided API key.

Retrieve Variable Set

# Get the variable set from Octopus
$libraryVariableSetVariables = (Invoke-RestMethod -Method Get -Uri "$octopusBaseURL/api/$spaceId/variables/$variableSetId" -Headers $Header) 

The script sends an API request to Octopus Deploy to fetch the variable set based on the provided Space ID and Variable Set ID. This variable set contains all the variables you want to modify.

Find the Variable

# Find the variable
$index = $libraryVariableSetVariables.Variables.name.IndexOf($variableName)

It searches for the specified variable by name within the variable set.

Update Variable Value

  # If the variable was found, update it.
  $libraryVariableSetVariables.Variables[$index].value = $newValue

If the variable is found ($index -ge 0), the script updates the variable's value to the specified new value.

API Update Request

  $UpdatedLibraryVariableSet = Invoke-RestMethod -Method Put -Uri "$octopusBaseURL/api/$spaceId/variables/$variableSetId" -Headers $Header -Body ($libraryVariableSetVariables | ConvertTo-Json -Depth 10)   

It sends a PUT request to update the variable set with the modified variable, saving the response in a variable for outputting later.

Error Handling for Variable Not Found

  # Otherwise, write out an error
  Write-Output ("Variable name [$variableName] not found. These are the available variable names:[{0}]" -f (($libraryVariableSetVariables.Variables.name) -join(',')))

If the variable is not found, the script provides an error message listing available variable names.

Response Output

# Write out the response from the update
write-host ($UpdatedLibraryVariableSet | convertto-json)

Finally, the script outputs the response from the update operation, allowing you to verify the changes made to the variable.

Usage

Here is an example of using the script in a powershell terminal assuming the script is stored in UpdateODVariable:

UpdateODVariable.ps1 -octopusAPIKey ODABC12345XYZ -variableSetId variableset-Projects-42 -variableName buildVersion -newValue 2.3.4.123

Notes

  1. If your variable has multiple values, just one of them will get updated.
  2. The id of a global variable set is visible in the browser url box when you browse to it. The identifier should be preceded with "variableset-" like this example api url: $OctopusURL/api/$spaceId/variables/variableset-LibraryVariableSets-21. The script expects everything after the last slash in the variableName parameter.
  3. The API url path for a project variable library looks like $OctopusURL/api/$spaceId/variables/variableset-Projects-61. Everything after the last slash is expected in the variableName parameter. You can find the project id by going to the project variables page, clicking on the three vertical dots to the top right and mousing over the export to json link and note the project id visible in the status bar to the bottom left of your browser.
  4. When including this script in a CI/CD pipeline, it would be good to have some error checking on the result from the invoke-restmethod call.

Conclusion

This script is a starting point for updating Octopus Deploy variables via the REST API, which you can easily change to fit into your pipelines, removing one more error prone manual step from your deployment processes.

When you are ready, come back for our next article going a little deeper into the api by copying variables from one Octopus Deploy Project to another!