在 Azure Pipelines 中使用 Azure Key Vault 机密进行单元测试
Use Azure Key Vault Secrets for Unit Tests in Azure Pipelines
我在 .NET 5 中有一个解决方案,其中包含 NUnit 中的一些单元测试,需要一些秘密才能正常工作。在 Visual Studio 中使用本地用户机密进行测试工作正常,但现在我想尝试使用 Azure Key Vault 和 运行 管道内的单元测试进行集成。
我添加了任务 AzureKeyVault@2
,根据日志,秘密已 下载 很好,但在接下来的步骤中,单元测试失败,因为它没有尝试从 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
任务传递密钥和值,或者我是否需要额外的步骤?。我读到您可以使用空的 appsettings.json
来玩 FileTransform@1 步骤,但我无法让它工作。有没有正确的方法可以做到这一点?
在管道中使用以下 Keyvault 任务来获取您的 Keyvault 中的机密:
- task: AzureKeyVault@2
displayName: 'Configure Key Vault'
inputs:
azureSubscription: '**-etc-**'
KeyVaultName: '**key-vault-name**'
SecretsFilter: '*'
RunAsPreJob: false
现在,在 DotNetCoreCLI@2 任务中,添加环境变量来定义 keyvault 机密,以便您可以在项目中使用这些环境变量:
- task: DotNetCoreCLI@2
displayName: ''
env:
MySecret: $(key-vault-secret-name)
inputs:
command: ''
projects: 'project-name'
在您的项目中,您可以按如下方式定义密钥库机密:
var mySecret = Environment.GetEnvironmentVariable("MySecret");
参考:Azure DevOps YAML pipeline : Use Azure KeyVault secret as Environment Variable - DEV Community
我终于成功了。我决定去appsettings.json
的路线。与文件转换任务。我会自己回答,以防万一其他人觉得这有用。
您需要在您的单元测试项目中有一个 appsettings.json
,并添加您在单元测试中需要的所有必需键,但没有值,只有 ""
,例如
{
"secret-key-1": "",
"secret-key-2": "",
"secret-key-3": "",
}
如果你想在本地测试,你可以使用 Visual Studio 中的本地用户密码选项,并像在你的 appsettings.json
文件中一样添加所有密钥,但使用实际值(你将是无论如何只有一个查看值)
{
"secret-key-1": "some-secret-value",
"secret-key-2": "some-secret-value",
"secret-key-3": "some-secret-value",
}
然后,在您的 SetUp
方法中,您可以按如下方式初始化 IConfiguration
class。 (如果您有多个单元测试 classes,您可以轻松地将其转换为静态方法)
[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
之后添加 FileTransform@1
任务。
- 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\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: ***
我在 .NET 5 中有一个解决方案,其中包含 NUnit 中的一些单元测试,需要一些秘密才能正常工作。在 Visual Studio 中使用本地用户机密进行测试工作正常,但现在我想尝试使用 Azure Key Vault 和 运行 管道内的单元测试进行集成。
我添加了任务 AzureKeyVault@2
,根据日志,秘密已 下载 很好,但在接下来的步骤中,单元测试失败,因为它没有尝试从 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
任务传递密钥和值,或者我是否需要额外的步骤?。我读到您可以使用空的 appsettings.json
来玩 FileTransform@1 步骤,但我无法让它工作。有没有正确的方法可以做到这一点?
在管道中使用以下 Keyvault 任务来获取您的 Keyvault 中的机密:
- task: AzureKeyVault@2
displayName: 'Configure Key Vault'
inputs:
azureSubscription: '**-etc-**'
KeyVaultName: '**key-vault-name**'
SecretsFilter: '*'
RunAsPreJob: false
现在,在 DotNetCoreCLI@2 任务中,添加环境变量来定义 keyvault 机密,以便您可以在项目中使用这些环境变量:
- task: DotNetCoreCLI@2
displayName: ''
env:
MySecret: $(key-vault-secret-name)
inputs:
command: ''
projects: 'project-name'
在您的项目中,您可以按如下方式定义密钥库机密:
var mySecret = Environment.GetEnvironmentVariable("MySecret");
参考:Azure DevOps YAML pipeline : Use Azure KeyVault secret as Environment Variable - DEV Community
我终于成功了。我决定去appsettings.json
的路线。与文件转换任务。我会自己回答,以防万一其他人觉得这有用。
您需要在您的单元测试项目中有一个 appsettings.json
,并添加您在单元测试中需要的所有必需键,但没有值,只有 ""
,例如
{
"secret-key-1": "",
"secret-key-2": "",
"secret-key-3": "",
}
如果你想在本地测试,你可以使用 Visual Studio 中的本地用户密码选项,并像在你的 appsettings.json
文件中一样添加所有密钥,但使用实际值(你将是无论如何只有一个查看值)
{
"secret-key-1": "some-secret-value",
"secret-key-2": "some-secret-value",
"secret-key-3": "some-secret-value",
}
然后,在您的 SetUp
方法中,您可以按如下方式初始化 IConfiguration
class。 (如果您有多个单元测试 classes,您可以轻松地将其转换为静态方法)
[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
之后添加 FileTransform@1
任务。
- 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\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: ***