Использование секретов хранилища ключей Azure для модульных тестов в Azure Pipelines
У меня есть решение в .NET 5 с некоторыми модульными тестами в NUnit, которые требуют некоторых секретов для правильной работы. Тестирование в Visual Studio с использованием секретов локального пользователя работает нормально, но теперь я хочу попытаться выполнить интеграцию с помощью Azure Key Vault и запустить модульные тесты внутри конвейера.
Я добавил задачу, и, согласно журналу, секреты загружаются нормально, но на следующих шагах модульные тесты терпят неудачу, потому что они не находят некоторые ключи при попытке доступа из
IConfiguration
.
Это мой
azure-pipelines.yml
(только соответствующие части).
- job: Init
displayName: Unit Testing
variables:
solutionToBuild: 'Solution.sln'
unitTestsProject: 'UnitTests\UnitTests.csproj'
buildConfiguration: 'Release'
steps:
- task: DotNetCoreCLI@2
displayName: 'Restore Packages'
inputs:
command: 'restore'
projects: '$(solutionToBuild)'
verbosityRestore: minimal
feedsToUse: 'select'
- task: DotNetCoreCLI@2
displayName: 'Build Solution'
inputs:
command: 'build'
projects: '$(solutionToBuild)'
arguments: '-c $(buildConfiguration)'
- task: AzureKeyVault@2
displayName: 'Configure Key Vault'
inputs:
azureSubscription: '**-etc-**'
KeyVaultName: '**key-vault-name**'
- task: DotNetCoreCLI@2
displayName: 'Run Unit Tests'
inputs:
command: 'test'
projects: '$(unitTestsProject)'
arguments: '-c $(buildConfiguration) --collect:"XPlat Code Coverage"'
publishTestResults: true
Я создал эти базовые тесты, которые в настоящее время не работают в конвейере. Я использую
Host.CreateDefaultBuilder()
метод для инициализации всех модульных тестов.
[Test]
[TestCase("secret-key-1")]
[TestCase("secret-key-1")]
public void TestSecrets(string key)
{
Assert.NotNull(_config[key]);
Assert.IsNotEmpty(_config[key]);
}
Есть ли
AzureKeyVault@2
передать секретные ключи и значения для
DotNetCoreCLI@2
задача или мне нужен дополнительный шаг ?. Я читал, что вы можете поиграть с шагом FileTransform @ 1, используя пустой
appsettings.json
но я не мог заставить его работать. Есть ли правильный метод для этого?
2 ответа
Наконец-то я заставил это работать. Решил пойти по маршруту. с задачей преобразования файлов. Я отвечу сам на всякий случай, если кому-то это пригодится.
Вам необходимо иметь в своем проекте модульного теста и добавить все необходимые ключи, которые вам понадобятся в модульных тестах, но без значений, только
""
, например
{
"secret-key-1": "",
"secret-key-2": "",
"secret-key-3": "",
}
Если вы хотите протестировать локально, вы можете использовать опцию local user-secrets в Visual Studio и добавить все ключи, как в вашем
appsettings.json
файл, но с фактическими значениями (вы все равно будете видеть значения)
{
"secret-key-1": "some-secret-value",
"secret-key-2": "some-secret-value",
"secret-key-3": "some-secret-value",
}
Затем в вашем
SetUp
метод, вы можете инициализировать
IConfiguration
класс следующим образом. (Вы можете легко преобразовать это в статический метод, если у вас есть несколько классов модульных тестов)
[TestFixture]
public class MyUnitTest
private IConfiguration Config;
[SetUp]
public void Setup()
{
Config = new ConfigurationBuilder()
.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", optional: true)
.AddUserSecrets(Assembly.GetExecutingAssembly())
.Build();
}
[Test]
[TestCase("secret-key-1")
[TestCase("secret-key-2")
public void TestKeys(string key)
{
Assert.NotNull(config[key]);
Assert.IsNotEmpty(config[key]);
}
}
Наконец, в
azure-pipelines.yml
вы добавляете задачу после
AzureKeyVault@2
.
- task: AzureKeyVault@2
displayName: 'Configure Key Vault'
inputs:
azureSubscription: '**-etc-**'
KeyVaultName: '**key-vault-name**'
- task: FileTransform@1
displayName: 'Set Unit Tests Settings'
inputs:
folderPath: '$(projectsDirectory)'
fileType: 'json'
targetFiles: '**/appsettings.json'
- task: DotNetCoreCLI@2
displayName: 'Run Unit Tests'
inputs:
command: 'test'
projects: '$(unitTestsProject)'
arguments: '-c $(buildConfiguration) --collect:"XPlat Code Coverage"'
publishTestResults: true
И все, после этого в журнале конвейера вы увидите что-то подобное в
FileTransform@1
задача
Applying JSON variable substitution for **/appsettings.json
Applying JSON variable substitution for D:\a\1\s\UnitTests\appsettings.json
Substituting value on key secret-key-1 with (string) value: ***
Substituting value on key secret-key-2 with (string) value: ***
Substituting value on key secret-key-3 with (string) value: ***
Используйте приведенную ниже задачу Keyvault в конвейере, чтобы получить секреты в вашем хранилище ключей:
- task: AzureKeyVault@2
displayName: 'Configure Key Vault'
inputs:
azureSubscription: '**-etc-**'
KeyVaultName: '**key-vault-name**'
SecretsFilter: '*'
RunAsPreJob: false
Теперь в задаче DotNetCoreCLI@2 добавьте переменные среды для определения секретов хранилища ключей, чтобы вы могли использовать эти переменные среды внутри своего проекта:
- task: DotNetCoreCLI@2
displayName: ''
env:
MySecret: $(key-vault-secret-name)
inputs:
command: ''
projects: 'project-name'
Внутри вашего проекта вы можете определить секрет keyvault следующим образом:
var mySecret = Environment.GetEnvironmentVariable("MySecret");