带有Vault机密的Azure DevOps文件转换

时间:2020-09-25 13:37:56

标签: azure-devops azure-web-app-service

我需要通过azure devops部署linux azure应用服务。我的配置存储在appsettings文件中,我需要将配置值替换为存储在Azure Vault中的值。

所以我在工件中创建了变量组,将其链接到管道中的变量,并使用FileTransform @ 2替代了appsettings值。

但是它替代了空值。如果我通过分配一些字符串值在管道中显式定义变量值,则可以正常工作。

我也不能将AzureRmWebAppDeployment @ 4与JSONFiles一起使用,它不适用于Linux部署

解决这个问题的方法是什么?

这是管道代码:

trigger:
  branches:
    include:
    - master
    - develop
    - release/*
  paths:
    include:
    - src/ConsumerBackEnd/*
    - src/ConsumerShared/*

variables:
  - name: poolName
    value: 'Private-Windows10'
  - name: azureRegisteredApp
    value: 'portal-devops'
  - name: workingDirectory
    value: '$(System.DefaultWorkingDirectory)/src/ConsumerBackEnd'
  - name: solutionDirectory
    value: '$(System.DefaultWorkingDirectory)/src'

stages:
- stage: Build
  displayName: Build stage

  jobs:
  - job: Build
    displayName: Build
    pool:
      name: $(poolName)
    
    variables:
    - group: ConsumerDevVariableGroup
    - name: 'Graph.GraphAppTenantId'
      value: '**************' #works fine
    - name: 'Graph.GraphAppClientId'
      value: '$[variables.GraphAppClientId]' #should take value from vault but injects null
    
    - task: FileTransform@2
      inputs:
        folderPath: '$(workingDirectory)'
        xmlTransformationRules: 
        jsonTargetFiles: '**/appsettings.json'

    - task: DotNetCoreCLI@2
      displayName: Nuget Restore
      inputs:
        command: 'restore'
        projects: '$(workingDirectory)/*.csproj'
        feedsToUse: 'config'
        nugetConfigPath: '$(solutionDirectory)/NuGet.config'
    
    - task: DotNetCoreCLI@2
      displayName: Build
      inputs:
        command: 'build'
        projects: |
          $(workingDirectory)/ConsumerBackEnd.csproj
        arguments: --output $(System.DefaultWorkingDirectory)/output

    - task: DotNetCoreCLI@2
      displayName: Publish
      inputs:
        command: 'publish'
        publishWebProjects: false
        projects: '$(workingDirectory)/ConsumerBackEnd.csproj'
        arguments: '-c Release -r linux-x64 --self-contained true --output $(System.DefaultWorkingDirectory)/publish_output'
        

#requires approval on pipeline
- stage: DeployDev
  displayName: DeployDev
  dependsOn: Build
  condition: succeeded()
  
  jobs:
    - deployment: DeployConsumerBackendAPIDev
      displayName: DeployConsumerBackendAPIDev
      environment: ConsumerBackendAPIDev
      pool:
        name: $(poolName)

      strategy:
        runOnce:
          deploy:
            steps:
            - task: AzureRmWebAppDeployment@4
              inputs:
                ConnectionType: 'AzureRM'
                azureSubscription: '$(azureRegisteredApp)'
                appType: 'webAppLinux'
                WebAppName: 'my-backend-dev'
                packageForLinux: '$(System.DefaultWorkingDirectory)/publish_output/**/*.zip'
                RuntimeStack: 'DOTNETCORE|LTS --configuration Release'

2 个答案:

答案 0 :(得分:1)

具有Vault秘密的Azure DevOps文件转换

要实现此目的,可以使用任务Replace Tokens使用Azure Vault机密更新密钥的值。

作为测试,我在Azure门户中使用测试值 LeoVar1创建了保管库密钥123456

enter image description here

然后将Azure密钥保管库连接到azure devops管道中。

现在,我使用替换令牌将webpages:Version文件中的密钥web.config的值替换为Azure保管库#{LeoVar1}#中的保管库密钥:

我的测试web.config文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
    <add name="DefaultConnection"
         connectionString="Data Source=(LocalDb)\\MSDB;DbFilename=aspcore-local.mdf;" />
  </connectionStrings>
  <appSettings>
    <add key="webpages:Version" value="#{LeoVar1}#" />
    <add key="webpages:Enabled" value="false" />
  </appSettings>
  <system.web>
    <authentication mode="None" />
    <compilation targetFramework="4.5" debug="true" />
  </system.web>
</configuration>

此任务结束后,您将看到替换成功完成:

enter image description here

您可以查看此文档Store the app secrets in Azure Key Vault and use during Azure Pipelines以获得一些详细信息。

更新

我只是在徘徊为什么FileTransform @ 2不能与机密一起使用

要使其正常工作,请确保以下几点:

  • appsettings.json的路径正确。确保将其保存在文件夹$(workingDirectory)下。
  • 重要的是确保保管库密钥的名称属性名称及其父节点的组合。

例如,如果我们想要将以下json文件中的DebugModeenabled更改为disable

{
  "Data": {
    "DefaultConnection": {
      "ConnectionString": "Data Source=(LocalDb)\\MSDB;AttachDbFilename=aspcore-local.mdf;"
    },
    "DebugMode": "enabled",
    "DBAccess": {
      "Administrators": ["Admin-1", "Admin-2"],
      "Users": ["Vendor-1", "vendor-3"]
    },
    "FeatureFlags": {
      "Preview": [
        {
          "newUI": "AllAccounts"
        },
        {
          "NewWelcomeMessage": "Newusers"
        }
      ]
    }
  }
}

我们需要将文件库机密的名称定义为 Data.DebugMode ,而不是DebugMode

但是,文件库机密不支持点.,它将给出错误:

请提供有效的秘密名称。 秘密名称只能包含 字母数字字符和破折号

enter image description here

如果我们在管道中使用“变量”对其进行测试,则它可以正常工作而不会出现任何错误:

enter image description here

由于库秘密不支持点.,所以我们不能用父节点替换属性。那就是我建议您首先使用替换令牌任务的原因。

答案 1 :(得分:1)

似乎使用运行时表达式引用组变量不适用于文件转换任务,但是宏语法可以正常工作

Microsoft documentation不能很好地描述

所以这是应该如何定义:

variables:
  #secrets
  - group: ConsumerDevVariableGroup
  - name: Graph.GraphAppTenantId
    value: $(GraphAppTenantId) #works fine
  - name: 'Graph.GraphAppClientId'
    value: '$[variables.GraphAppClientId]' #does not work