Update/Create Library Variable Sets

Hi,

I’m currently looking at how we can update a LibraryVariableSet With a list or IPs after a Terraform script is run to be used by different projects.

So far I have managed to get the Variables updating with theses IPs within the same project using a slightly modified script from: https://github.com/OctopusDeploy/OctopusDeploy-Api/blob/master/REST/PowerShell/Variables/ModifyOrAddVariableToProject.ps1

#Slightly modified from https://github.com/OctopusDeploy/OctopusDeploy-Api/blob/master/REST/PowerShell/Variables/ModifyOrAddVariableToProject.ps1
function Set-OctopusVariable {
    param(
        $octopusURL = "", # Octopus Server URL
        $octopusAPIKey = "",               # API key goes here
        $projectName = "",                        # Replace with your project name
        $spaceName = "SpaceName",                   # Replace with the name of the space you are working in
        $environment = "",                     # Replace with the name of the environment you want to scope the variables to
        $varName = "",                            # Replace with the name of the variable
        $varValue = ""                            # Replace with the value of the variable
    )

    # Defines header for API call
    $header = @{ "X-Octopus-ApiKey" = $octopusAPIKey }

    # Get space
    $space = (Invoke-RestMethod -Method Get -Uri "$octopusURL/api/spaces/all" -Headers $header) | Where-Object {$_.Name -eq $spaceName}

    # Get project
    $project = (Invoke-RestMethod -Method Get -Uri "$octopusURL/api/$($space.Id)/projects/all" -Headers $header) | Where-Object {$_.Name -eq $projectName}

    # Get project variables
    $projectVariables = Invoke-RestMethod -Method Get -Uri "$octopusURL/api/$($space.Id)/variables/$($project.VariableSetId)" -Headers $header

    # Get environment to scope to
    $environmentObj = $projectVariables.ScopeValues.Environments | Where { $_.Name -eq $environment } | Select -First 1

    # Define values for variable
    $variable = @{
        Name = $varName  # Replace with a variable name
        Value = $varValue # Replace with a value
        Type = "String"
        IsSensitive = $false
        Scope = @{
            Environment = @(
                $environmentObj.Id
                )
            }
    }

    # Check to see if variable is already present. If so, removing old version(s).
    $variablesWithSameName = $projectVariables.Variables | Where-Object {$_.Name -eq $variable.Name}

    if ($environmentObj -eq $null){
        # The variable is not scoped to an environment
        $unscopedVariablesWithSameName = $variablesWithSameName | Where-Object { $_.Scope -like $null}
        $projectVariables.Variables = $projectVariables.Variables | Where-Object { $_.id -notin @($unscopedVariablesWithSameName.id)}
    }

    if (@($variablesWithSameName.Scope.Environment) -contains $variable.Scope.Environment){
        # At least one of the existing variables with the same name is scoped to the same environment, removing all matches
        $variablesWithMatchingNameAndScope = $variablesWithSameName | Where-Object { $_.Scope.Environment -like $variable.Scope.Environment}
        $projectVariables.Variables = $projectVariables.Variables | Where-Object { $_.id -notin @($variablesWithMatchingNameAndScope.id)}
    }

    # Adding the new value
    $projectVariables.Variables += $variable

    # Update the collection
    Invoke-RestMethod -Method Put -Uri "$octopusURL/api/$($space.Id)/variables/$($project.VariableSetId)" -Headers $header -Body ($projectVariables | ConvertTo-Json -Depth 10)
}
$OctopusUrl = "https://octopusurl/"
$octopusAPIKey = "#{PWSH_SCRIPT_APIKEY}"
$projectName = "project-name"
$varName = $args[0]                            # Replace with the name of the variable
$varValue = $args[1]                            # Replace with the value of the variable
$environment = $args[2]                     # Replace with the name of the environment you want to scope the variables to
Set-OctopusVariable -octopusURL $OctopusUrl -octopusAPIKey $octopusAPIKey -projectName $projectName -varName $varName -varValue $varValue -environment $environment

I was hoping that I would be able to pass in LibrarySetName in place of projectName.

I have also looked at:
https://octopus.com/docs/octopus-rest-api/examples/variables/update-variable-set-variable-value

But using this I am only able to update existing variables and not create new ones.

Any help on this would be massively appreciated,
Thanks.

Hey @matt.barber,

Thanks for reaching out! Welcome to the Octopus forums!

There were a few lines that needed to be changed so I changed the lines and added a new function with a different parameter (varsetname rather than projectname). You should be able to add this function to your existing script and call that function instead when modifying variable sets rather than projects. As always, please read the script thoroughly and test in a test environment as it’s not guaranteed to work in all scenarios.

function Set-OctopusVariableVariableSet {
    param(
        $octopusURL = "", # Octopus Server URL
        $octopusAPIKey = "",               # API key goes here
        $varSetName = "",                        # Replace with your project name
        $spaceName = "",                   # Replace with the name of the space you are working in
        $environment = "",                     # Replace with the name of the environment you want to scope the variables to
        $varName = "",                            # Replace with the name of the variable
        $varValue = ""                            # Replace with the value of the variable
    )

    # Defines header for API call
    $header = @{ "X-Octopus-ApiKey" = $octopusAPIKey }

    # Get space
    $space = (Invoke-RestMethod -Method Get -Uri "$octopusURL/api/spaces/all" -Headers $header) | Where-Object {$_.Name -eq $spaceName}

    # Get variable set ID
    $variableSetId = ((Invoke-RestMethod -Method Get -Uri "$octopusURL/api/$($space.Id)/libraryvariablesets/all" -Headers $header) | Where-Object {$_.Name -eq $varSetName}).Links.Variables

    # Get variableset variables
    $variableSetVariables = Invoke-RestMethod -Method Get -Uri "$octopusURL/$($variableSetId)" -Headers $header

    # Get environment to scope to
    $environmentObj = $variableSetVariables.ScopeValues.Environments | Where { $_.Name -eq $environment } | Select -First 1

    # Define values for variable
    $variable = @{
        Name = $varName  # Replace with a variable name
        Value = $varValue # Replace with a value
        Type = "String"
        IsSensitive = $false
        Scope = @{
            Environment = @(
                $environmentObj.Id
                )
            }
    }

    # Check to see if variable is already present. If so, removing old version(s).
    $variablesWithSameName = $variableSetVariables.Variables | Where-Object {$_.Name -eq $variable.Name}

    if ($environmentObj -eq $null){
        # The variable is not scoped to an environment
        $unscopedVariablesWithSameName = $variablesWithSameName | Where-Object { $_.Scope -like $null}
        $variableSetVariables.Variables = $variableSetVariables.Variables | Where-Object { $_.id -notin @($unscopedVariablesWithSameName.id)}
    }

    if (@($variablesWithSameName.Scope.Environment) -contains $variable.Scope.Environment){
        # At least one of the existing variables with the same name is scoped to the same environment, removing all matches
        $variablesWithMatchingNameAndScope = $variablesWithSameName | Where-Object { $_.Scope.Environment -like $variable.Scope.Environment}
        $variableSetVariables.Variables = $variableSetVariables.Variables | Where-Object { $_.id -notin @($variablesWithMatchingNameAndScope.id)}
    }

    # Adding the new value
    $variableSetVariables.Variables += $variable

    # Update the collection
    Invoke-RestMethod -Method Put -Uri "$octopusURL/$($variableSetId)" -Headers $header -Body ($variableSetVariables | ConvertTo-Json -Depth 10)
}
$OctopusUrl = ""
$octopusAPIKey = ""
$varSetName = ""
$environment = ""
$spacename = ""
$varName = ""                            # Replace with the name of the variable
$varValue = ""                            # Replace with the value of the variable
Set-OctopusVariableVariableSet -octopusURL $OctopusUrl -octopusAPIKey $octopusAPIKey -varSetName $varSetName -varName $varName -varValue $varValue -environment $environment -spaceName $spacename

Please let me know how it goes for you.

Best,
Jeremy

Hi Jeremy,

I have just been giving it a quick test and all looking good so far!
Thank you for taking the time to look at it.

Matt.

1 Like

Hey Matt,

You’re very welcome! Thank you for letting me know it worked for you.

Please let us know whenever you run into any snags.

I hope you have a great rest of your week.

Best,
Jeremy

1 Like