【问题标题】:Use Azure Key Vault Secrets for Unit Tests in Azure Pipelines在 Azure Pipelines 中使用 Azure Key Vault Secrets 进行单元测试
【发布时间】:2021-10-26 00:20:12
【问题描述】:

我在 .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 步骤,但我无法让它工作。有没有正确的方法来实现这一点?

【问题讨论】:

    标签: azure-pipelines nunit .net-5 azure-keyvault azure-secrets


    【解决方案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'
    

    在您的项目中,您可以按如下方式定义 keyvault 密码:

    var mySecret = Environment.GetEnvironmentVariable("MySecret");
    

    参考:Azure DevOps YAML pipeline : Use Azure KeyVault secret as Environment Variable - DEV Community

    【讨论】:

    • 嗨@RamaraoAdapa-MT。我有个问题。我需要为每个密钥添加 env 吗?我们有很多秘密(超过 20 个),并且经常添加更多,我不知道每次我们更新或向保险库添加更多秘密时编辑 yml 文件是否可行。这是实现这一目标的唯一方法吗?
    • 您可以使用直接从您的 .NET 应用程序访问 keyvault 机密。请参考:codeproject.com/Tips/1430794/…
    • 我知道,并且在应用程序中工作正常,但在单元测试中需要不同的方法。最后我的另一个答案解决了我的问题。
    • 很高兴听到您的问题得到解决
    【解决方案2】:

    我终于成功了。我决定走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 类。 (如果您有多个单元测试类,您可以轻松地将其转换为静态方法)

    [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\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: ***
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-23
      • 2022-01-06
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 2018-04-30
      • 1970-01-01
      • 2019-12-19
      相关资源
      最近更新 更多