Azure DevOps replace part of variable with value from KeyVault

I have a Azure Devops pipeline that tries to replace part of a string variable value with a value from Azure KeyVault.

Given a KeyVault secret kvSecret with value this-is-my-secret, I want another variable foo with value this-is-your-secret.

jobs:
- job: WebApp
  pool:
    vmImage: 'windows-latest'
  variables:
    foo: $[replace(variables['kvSecret'], 'my', 'your')]

  steps:
  - task: AzureKeyVault@2
    inputs:
      azureSubscription: 'foo'
      KeyVaultName: 'myKeyVault'
      RunAsPreJob: true

Since logging is masked, I tested this by writing to a file:

  - task: PowerShell@2
    inputs:
      targetType: 'inline'
      script: |
        New-Item $(build.artifactstagingdirectory)\test.txt
        Set-Content $(build.artifactstagingdirectory)\test.txt '$(foo)'

  - task: PublishBuildArtifacts@1
    inputs:
      pathToPublish: '$(Build.ArtifactStagingDirectory)'

The output is this-is-my-secret though.

Upvotes: 1

Views: 1894

Answers (1)

Kevin Lu-MSFT
Kevin Lu-MSFT

Reputation: 35624

I have tested your YAML definition, the variable foo should be empty.

The reason for this issue is that the replace expression will be expanded at compile time.

And the variable in your Key Vault will be downloaded when the pipeline is running.

Therefore, when the replace operation is performed, the kvSecret variable is empty, and the foo variable is also empty.

In order to solve this issue, you need to add a script to the Agent Job to perform the replace operation.

Here is an example:

jobs:
- job: WebApp
  pool:
    vmImage: 'windows-latest'
    
  steps:
  - task: AzureKeyVault@2
    inputs:
      azureSubscription: 'xx'
      KeyVaultName: 'xx'
      SecretsFilter: '*'
      RunAsPreJob: true

  - task: PowerShell@2
    inputs:
      targetType: 'inline'
      script: |
        $newvalue = "$(kvSecret)" -replace "my", "your"
        echo $newvalue 
        echo "##vso[task.setvariable variable=foo]$newvalue"
        
  - task: PowerShell@2
    inputs:
      targetType: 'inline'
      script: |
        echo "$(foo)"
        New-Item $(build.artifactstagingdirectory)\test.txt
        Set-Content $(build.artifactstagingdirectory)\test.txt -value '$(foo)'
  - task: PublishBuildArtifacts@1
    inputs:
      pathToPublish: '$(Build.ArtifactStagingDirectory)'

Result:

enter image description here

Upvotes: 2

Related Questions