Simplify cloning variables for new environment
When a new environment is added to a project, it becomes a pain to add all the variable overloads for that environment.
It would be nice to have a way to select all the variables you wish to clone along with the scope you wish to apply to them all. After they are cloned, you could easily update their values and then save.
At the moment, it is a rather cumbersome task of finding a variable, copying its name, pasting it down the bottom, entering the new value, selecting the scope, and repeating one by one for each variable. Since the names are generally the same as existing variables and the scope is generally the same for all the new ones being added, there is no need for so much repetition.


Hi Richard,
There is a shortcut that can help – if you right click on a variable, there’s a Duplicate option. It doesn’t work with multiple selections however, but it should get you part of the way.
Paul
-
Amjad Khoja commented
It will be a good feature to clone Variable set
-
Gautam Heble commented
@Kris Johnson, Thanks a ton for that script you shared, I could use it to clone variable sets for our instance of Octopus!
-
Kris Johnson commented
Hey Guys,
Old comment and a feature that still isnt avail so i have a powershell script that will clone a variable set from one to another creating the new set and copying the scope (or changing to a new scope) .. it also allows to copy all variables or not.. and if you do copy the variables it can't prompt for each..
I'm no octopus expert but this fits nicely for what i needed...... updated what i originally posted so it makes a little more sense :)
cd "path to DLL's"
Add-Type -Path .\Newtonsoft.Json.dll
Add-Type -Path .\Octopus.Client.dll
Add-Type -Path .\Octopus.Platform.dll$OctopusURL = "changeme" #change to url of octopus (note the / is required)
$OctoPrismAPI = "changeme" #change to url of octopus (note the / is not required)
$APIKey = "changeme"$endpoint = new-object Octopus.Client.OctopusServerEndpoint ($OctopusURL, $APIKey)
$c = new-object Octopus.Client.OctopusRepository $endpoint$headers = @{"X-Octopus-ApiKey"="$APIKey";}
$copyfrom = read-host "Please enter the Variable set you want to clone from"
$copyto = read-host "Please enter the Variable set you want to clone to"
$scope = read-host "Please enter the scope you wish to use for this variable set , if the same leave blank"
$copyvalues = read-host "Would you like to copy the values over to the new set ? Y/N"# find the scope ID for use later
$environmentid = ($c.Environments.FindAll() | ?{$_.name -eq "$scope"}).id# create the variable set to copy to
$libraryVariableSet = New-Object Octopus.Client.Model.LibraryVariableSetResource
$libraryVariableSet.Name = "$copyto"
$libraryVariableSet = $c.LibraryVariableSets.Create($libraryVariableSet);# find the variable sets
$variablesets = $c.LibraryVariableSets.Findall()# find the api url for the copy from and copy to variable sets
$apicopyto = ((($variablesets | ?{$_.name -eq "$copyto"}).links).values | Select-Object -last 1)
$apicopyfrom = ((($variablesets | ?{$_.name -eq "$copyfrom"}).links).values | Select-Object -last 1)# call the api to get the variable sets json files
$jsoncopyto = Invoke-restmethod ("$OctoPrismAPI/$apicopyto") -Headers $Headers -Method Get
$jsoncopyfrom = Invoke-restmethod ("$OctoPrismAPI/$apicopyfrom") -Headers $Headers -Method Get# set the values to null if not required to be copied or prompt for each variable to be copied or not
if($copyvalues -eq "N")
{
foreach($variable in $jsoncopyfrom.Variables)
{
$variable.value = $null
}
}
else
{
$prompt = Read-Host "would you like to copy (a)ll values or (p)rompt for each ? a/p"
foreach($variable in $jsoncopyfrom.Variables)
{
$name = $variable.name
$value = $variable.Valueif($value -ne $null)
{
if($prompt -eq "p")
{
$answer = Read-Host "Would you like to copy $name with value $value to the new variable set ? Y/N"
if($answer -eq "N")
{
$variable.value = $null
}
}
}
}
}# If we have set a scope for the new variables to be linked to then we change these here
if($scope -ne "")
{
foreach($variable in $jsoncopyfrom.Variables)
{
$variable.scope.Environment = @($environmentid)
}
}# Set the copyto variables to the modified copyfrom variable set
$jsoncopyto.Variables = $jsoncopyfrom.Variables# convert to json
$jsoncopyto = $jsoncopyto | ConvertTo-Json -Depth 50# post back the variables
Invoke-RestMethod ("$OctoPrismAPI/$apicopyto") -Headers $Headers -Method Put -Body $jsoncopyto -
Navid commented
I just made a simple extension to do this using Octopus Rest API. You can get it here:
https://chrome.google.com/webstore/detail/octopus-variable-copier/bcdafjjfijobmknkbfjbkiagajgiibga?hl=en-US&gl=US -
Rob commented
And, now I've figured it out, I'd love to be able to name groups and open or close them.
Say you have a bunch of settings that are related to AWS/S3 - with 5-10 environments, that's a lot of variables. If you could classify/tag them as AWS you could then "fold" the group up so you dont have to put up with 30 variables - mostly the same while trying to change some of the others.
-
Rob commented
This is getting to be a very critical feature. Export to and Import from XML would go a HUGE way to making this work.
To be able to do this with the library would make the library variable sets a whole lot more useful - in fact, how about the ability to select a set of variables and convert to a variable set?
-
JonG commented
Ollie's suggestion of having an Import/Export from/to csv option on a variable set for mass-update is critical, and should probably get its own feature request.
Also, +1 for a dropdown when creating a "new" variable set to clone from an existing.
I would also add an option to multi-select variables within a variable set to scope multiple selections at once.
-
Travis Rosenbaum commented
Here's a LinqPad snippet I made using the Octopus.Client API to copy variables from one Library Variable Set to another, while changing the scope to match the new environment.
// Setup
var server = "http://octopus/";
var apiKey = "API-XXXXXXXXXXXXXXXXXXX";
var sourceLibraryVariableSetId = "LibraryVariableSets-3";
var targetLibraryVariableSetId = "LibraryVariableSets-29";
var targetEnvironmentId = "Environments-20";
// Copy variables from one Library Variable Set to another, while changing scope to a new environment.
try
{
// Connect to Octopus Deploy
var endpoint = new OctopusServerEndpoint(server, apiKey);
var repository = new OctopusRepository(endpoint);
// Get source variable set
var sourceLibraryVariableSet = repository.LibraryVariableSets.Get(sourceLibraryVariableSetId);
var sourceVariableSet = repository.VariableSets.Get(sourceLibraryVariableSet.Links["Variables"]);
// Get target variable set
var targetLibraryVariableSet = repository.LibraryVariableSets.Get(targetLibraryVariableSetId);
var targetVariableSet = repository.VariableSets.Get(targetLibraryVariableSet.Links["Variables"]);
// Copy variables from source to target
foreach (var variable in sourceVariableSet.Variables)
{
targetVariableSet.Variables.Add(new Octopus.Client.Model.VariableResource()
{
Name = variable.Name,
IsSensitive = variable.IsSensitive,
IsEditable = variable.IsEditable,
Prompt = variable.Prompt,
Value = variable.Value,
Scope = new ScopeSpecification()
{
{ ScopeField.Environment, new ScopeValue(targetEnvironmentId) }
//,{ ScopeField.Environment, new ScopeValue("Environments-22") }
//,{ ScopeField.Environment, new ScopeValue("Environments-27") }
}
});
}
//Save VariableSet Changes
repository.VariableSets.Modify(targetVariableSet);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
} -
Darwynn Carter commented
In my opinion, all of Ollie's suggestions are excellent. When using this with projects that have a large amounts of variables, this would be extremely helpful.
-
Callon commented
Hi Paul, I see the duplicate option and this is nice for one or two variables I want to change. This does not work when I have +50 variables per project then then I have 10 environments. 99% of variables specific to one environment are most likely going to be required for every environment except with a different value.
We need more control on provisioning these variables and what we have now just doesn't cut it. I hope we see improvements to this in v3.0.
-
Marius commented
Cloning a whole very much help me, as we have variable sets with 20-30 variables, and duplicating them one at the time is time consuming and prone to mistakes.
Also when duplicating a variable, it doesn't always pop up right above the one you just created, it can appear anywhere in the list. Which makes is a bit confusing.// Marius
-
Michael Peterson commented
As I've looked at implementing this on a project this ends up being a point. For 5 different projects, I have at least 9 variables that need to get updated per environment. Take this times 7 environments. Managing these in the current interface is at best burdensome, at worst easy to miss or chose the wrong something. Especially when you factor in scope and that something might be different in a particular instance of that environment. This probably is partially something I need to sort out with the best way to manage regional environments vs. grouping them all as "Production"... I think the new features in 2.6 will help there.
-
Ollie Chalk commented
Hi there, I'd thought I should update here instead of creating a new idea.
We're now in the process of set up our environments, we use variable sets for different servers to keep it manageable.
I have a few suggestions that could make it a lot easier:
- when creating a variable set, have the option (dropdown?) to copy from another set
- have a copy/duplicate button/context menu option on a variable set to copy to a new one
- have a export/import button/context menu option on a variable set. E.g.: export as XML, so you can easily edit and then import the XML as a new variable set
- have a bulk way of setting scopes in the scope column in a set. E.g.: highlight/checkbox a selection, click scope (which could then say "Press enter to edit selected scopes" instead of "Press enter to edit scope") and updates all scopes
Thanks,
Ollie -
Richard Pickett commented
Hi Paul. I wasn't aware of that option. It sounds like it helps to get half the way there. I still think there needs to be a way to duplicate multiple variables at once and also bulk edit the scope.