Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mitchgollub/ebce195ab188c4f4b9f235229e7866e1 to your computer and use it in GitHub Desktop.
Save mitchgollub/ebce195ab188c4f4b9f235229e7866e1 to your computer and use it in GitHub Desktop.
net-core-appsettings-json-variable-replacement-in-appveyor
Write-Host "Environment Variable Substitution"
$variables = gci $env:$env:APPLICATION_PREFIX* | Select-Object -Property Key, Value
$configPath = "$env:APPLICATION_PATH\$env:CONFIG_FILE"
Write-Output "Loading config file from $configPath"
$appSettings = Get-Content -Raw $configPath | ConvertFrom-Json
foreach($variable in $variables) {
$matchString = $variable.Key.replace($env:APPLICATION_PREFIX, "")
$matchProperties = $matchString.Split(".")
if($matchProperties.Count -gt 1) {
$match = $appSettings.($matchProperties[0]).psobject.properties | where { $_.Name -eq $matchProperties[1] }
if ($match) {
$appSettings.($matchProperties[0]).($matchProperties[1]) = $variable.Value
}
else {
Write-Output "Could not find match for $matchString"
}
}
else {
$match = $appSettings.psobject.properties | where { $_.Name -eq $matchString }
if ($match) {
$appSettings.($matchString) = $variable.Value
}
else {
Write-Output "Could not find match for $matchString"
}
}
}
$appSettings | ConvertTo-Json -depth 100 | Out-File $configPath
@molinch
Copy link

molinch commented Aug 3, 2020

I was having a similar need, in my case it was more that you have a secret coming from a KeyVault and then in the appsettings the connection string where you replace that part.

In the end I wrote a library to perform variable substitution, it substitutes from any configuration source, not just environment variables.
See: https://github.com/molinch/ConfigurationSubstitutor

You just need to register it as another configuration source, this is done by calling .EnableSubstitutions() on the ConfigurationBuilder.

With your example:

  • if in appsettings.json you have: "Application_Path": "%APPLICATION_PREFIX_OptimizerApp%/somepath/bla/bla/bla/"
  • and you have the following environment variable: APPLICATION_PREFIX_OptimizerApp = c:/apps/
  • then you should enable substitutions so:
.EnableSubstitutions("%", "%")

Finally when requesting Application_Path from the configuration you will get: c:/apps/somepath/bla/bla/bla/

@eivindivine
Copy link

How and where can I use this in my AppVeyor project?
Do I add this ps1 file to my netcore project and refer to it in the deployment tab in Appveyor?

@mitchgollub
Copy link
Author

Hi @eivindivine
Thanks for your question! If you came here from the blog post (https://mitchgollub.com/net-core-appsettings-json-variable-replacement-in-appveyor/), the directions and details are all there. You can place this code into the deploy.ps1 file at your project root that AppVeyor uses by default. This will execute the powershell script in the context of the deploy agent.

Thank you!

@eivindivine
Copy link

Thanks for your prompt reply @mitchgollub
Your blog is very thorough, but I think I may be missing som preliminary details.

The output log reports 'invalid variable reference':
image

And lets say I have this appsettings.json file, and I want to replace First.Second variable.
image

From your description, I would assume I need one environment variable for APPLICATION_PREFIX for the prefix tekst. and for the following appsettings replacements, I need to start with the prefix and then the variable values?
image

I'm presumably missing som basic info since this doesn't work, or I may have misunderstood your powershell script.

@eivindivine
Copy link

I got it working. I had to separate $env:$env:APPLICATION_PREFIX* into two lines (amongst a few other things).
All together, this is a much smoother solution than the parameters.xml from .net framework. Thanks for the contribution!

@mitchgollub
Copy link
Author

Hi @eivindivine,
That's great news! I was testing it out a little yesterday and had noticed my actual final version of the code is hard-coded with the application prefix

$variables = gci $env:APPID_* | Select-Object -Property Key, Value

So thats my mistake. If you'd like to share your changes, I'd be happy to update this file and credit you.

Also your assumptions on the variable replacement configuration are correct, but you probably knew that already.

Thanks!

@eivindivine
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment