I have several secrets stored in Azure KeyVault. Unfortunately I cannot find a way to pass parameters to my .net Core 2.0 test run via VSTS (Visual Studio Team Services)
Documentation says that Keyvault secrets can only be supplied via VSTS variables - fair enough - but how do I actually do this? All the information I can find on web seems outdated or doesn't work.
For example - consider RunSettings file:
<RunSettings>
<TestRunParameters>
<Parameter name="webAppUrl" value="http://localhost" />
<Parameter name="webAppUserName" />
<Parameter name="webAppPassword" />
</TestRunParameters>
</RunSettings>
I tried passing values for last 2 parameters via cmd line as follow:
vsts.console MyTest.dll /Settings:vsts.runsettings -- -webAppUserName foo
vsts.console MyTest.dll /Settings:vsts.runsettings -- webAppUserName=foo
dotnet test -s vsts.runsettings -- -webAppUserName foo
dotnet test -s vsts.runsettings -- webAppUserName=foo
but this has no effect - the webAppUserName value remains null (I can see a value for webAppUrl, so I know my code is right!)
I've also tried both the VSTS "dotnet test" task as well as the "VsTest" task from my VSTS 2017 build. The VsTest provides a Override test run parameters setting - and as per the tooltip, I tried:
-webAppUserName user -webAppPassword somethingSecret
Again - no effect!
Originally I used xUnit and had exactly the same issue - i.e. coudn't figure out a way to pass parameters via VSTS - so I tried MSTest, but same issue.
Going back to my original issue of injecting KeyVault secrets Locally via VS Studio I was able to just do the following from my test:
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, true)
...
.AddAzureKeyVault(...)
Unfortunately, when run via VSTS, the test runner just hangs (i.e. I had to stop it after several minutes) with no log output for test step if I use either
.AddAzureKeyVault(...) or .AddEnvironmentVariables()
So I tried using VSTS Variable Groups - and linking that to KeyVault. However, keyvault secrets are not accessible via environment variables (using Enviroment.GetEnvironmentVariable(...) directly from C#) - so that's no good. They say you can only pass these to tasks via VSTS variables...hence my problem!
Aside: Even if I could use environment variables, it's not optimal because when using .AddAzureKeyVault() I can supply a custom IKeyVaultSecretManager to, for example, replace a special delimiter with the ':' character - this means that I can nest my json config values - e.g. if I had this in my config file:
{ "A" : { "B" : "somevalue" } }
then using normal configuration builder I can access the above via config["A:B"]. Unfortunately KeyVault doesn't like the ":" character - so you have to replace it with something like "--" and then use a custom IKeyVaultSecretManager to replace "--" with ":" (which works great and ensures that variables are properly overridden based on the order of providers registered in config builder)
Please help! All I wanted for Christmas was not to put my KeyVault secrets into Git... but the VSTS KeyVault grinch is spoiling my fun... surely I'm missing something??
In order to interact with the Azure Key Vault service, you'll need to create an instance of the SecretClient class. You need a vault url, which you may see as "DNS Name" in the portal, and client secret credentials (client id, client secret, tenant id) to instantiate a client object.
Go to the Azure portal and open your Key Vault. Choose Access policies, then Add Access Policy, and choose the account you are logged in with as Principal. In Visual Studio, choose File > Account Settings. Select Add an account from the All account section.
Just an update
I've recently set up a new xUnit .NET Core 2.0 project. For this project I had no issues passing environment variables to Azure DevOps. Basically, all you do is:
ASPNETCORE_ENVIRONMENT
System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")
Given that the above works, .AddEnvironmentVariables()
configuration method should just work fine now aswell.
This mechanism can be used to load a different config files per test environments too.
For me, this is all I needed as I have a nice easy way to pass environment-specific options to integration tests
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With