I got this going, but it took a bit of work.
The first hurdle was getting a list of the variables. Octopus Deploy has a list of ALL the variables in the $OctopusParameters
variable. (And I do mean ALL.) Depending on when in the process you write them out, there can be several hundred. So I had to decide how to filter it down. I opted to put something on each of my variables so I could be sure I got only the ones that I wanted. So, the variables that I plan to be made Environment Variables in my container all start with Env.
(ie Env.AppSettings__Environment
). Variables that came from a variable set got reassigned:
Name Value Scope
Env.VariableNameFromSet #{VariableNameFromSet}
In my Update a Helm Chart
step, I added a pre-deployment script (added via the Configure Features
button). My pre-deployment script looks like this:
$index = 0
# Get all the Octopus variables that start with Env.
$envKeys = $OctopusParameters.Keys | where {$_ -like "Env.*"}
# Iterate over all the matching keys
foreach($envKey in $envKeys)
{
# Store the key (with the "Env." trimmed off) and the value in a yaml compliant key value pair.
$containerEnvironmentVariable = $envKey.TrimStart("Env.") + ': ' + $OctopusParameters[$envKey]
# Get an array style name for the variable
$varName = "ContainerEnvironmentVariables[$index]"
# Save the variable as an Octopus Variable
Set-OctopusVariable -name $varName -value $containerEnvironmentVariable
$index = $index + 1
}
The second main hurdle was getting Octopus to let me have an array of variables. The type of all variable values in Octopus is String
. The trick is in the naming of the variable. We end up calling the variables ContainerEnvironmentVariables[0]
, ContainerEnvironmentVariables[1]
, ContainerEnvironmentVariables[2]
etc.
Using that naming style gets Octopus Deploy to treat the ContainerEnvironmentVariables
variable as an array that can be iterated over (though the values of each of the elements of the array are still strings).
With this in place, now we can get values.yaml
can list out the contents of our ContainerEnvironmentVariables
variable.
But we can’t just use #{ContainerEnvironmentVariables}
directly. We need to control the spacing of the insertion. For that we are going to use Octopus Deploy’s repetition #{each var in vars}
syntax. Here is what that part of my values.yaml
looks like:
env:
#{each envVar in ContainerEnvironmentVariables} #{envVar}
#{/each}
This sets up a loop over all the ContainerEnvironmentVariables
. As it loops over each entry in the array, it inserts two spaces, the array entry variable value, then a return.
It is important to note that if you write this in a more traditional format like this:
env:
#{each envVar in ContainerEnvironmentVariables}
#{envVar}
#{/each}
Then you will get an extra line before each variable (because the template system assumes you want all the newlines between the start and stop of the loop tags).
When run, I get output like this in my values.yaml
file:
Env:
AppSettings__Environment: Dev
AppSettings__LogginUrl: https://MyLoggingUrl.com
(As a side note, the use of the double __ is due to the fact that most Linux systems can’t support the use of colons : in environment variable names.)