Azure Devops Pipeline - pass secrets as variables to another job - azure-devops

I am trying to get secret from keyvault using one agent pool in one job and pass them to second job.
- job: 'keyvault'
pool: pool1
steps:
- task: AzureKeyVault#2
inputs:
azureSubscription: connection1
KeyVaultName: keyvault1
SecretsFilter: '*'
- powershell: |
$ID='$(app--id)'
$secret_var = '$(app--id)'
echo '##vso[task.setvariable variable=secret_var;isOutput=true;]$ID'
name: secrets
- job: 'job2'
pool: pool2
dependsOn: keyvault
variables:
secret_var: $[ dependencies.keyvault.outputs['secrets.secret_var'] ]
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
echo $(secret_var)
However it does not work. Any idea why? How to?

Can you explain what actually doesn't work?
I tested this with simples case:
jobs:
- job: 'keyvault'
steps:
- powershell: |
echo '##vso[task.setvariable variable=secret_var;isOutput=true;isSecret=true;]siema'
name: secrets
- job: 'job2'
dependsOn: keyvault
variables:
secret_var: $[ dependencies.keyvault.outputs['secrets.secret_var'] ]
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
echo $(secret_var)
And it seems to be wroking:

Related

Variable in stage not set

my goal is to define a variable in the parent script in Azure DevOps for my pipeline, that I can read it within the template script.
I tried this:
stages:
- stage: Download_Suppliers_Artifacts
variables:
buildVersion2: test2
jobs:
- template: /Pipelines/Templates/download-components-hcp5.yml
Within my script I tried to access it but it is empty:
It is not showed here:
- task: Bash#3
inputs:
targetType: 'inline'
script: 'env | sort'
Nor here:
- task: Bash#3
inputs:
targetType: 'inline'
script: '{{ variables.buildVersion2}}'
This is related to the Runtime expression syntax for variables: https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#runtime-expression-syntax
In your case, you could directly use macro syntax $(var) instead of template expression ${{ variables.var }}
Test sample (Parent script)
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- none
pool:
vmImage: windows-latest
stages:
- stage: test
variables:
buildVersion2: test2
jobs:
- template: download-components-hcp5.yml
- job:
steps:
- script: echo $(buildVersion2)
Template:
# download-components-hcp5.yml
jobs:
- job: job1
steps:
- script: env | sort
- powershell: echo $(buildVersion2)

How can I use powershell creating different name webjob for different location?

My question is specific but I guess simple who knows PowerShell more than I.
Let me explain my question :
I need 6 different webjobs under 1 web service. my webjob will be the SonicMQ listener we developed can only listens to a single queue.
My locations [istanbul,berlin, hamburg.....]
I am trying to create 6 different webjobs with "-istanbul","-berlin","-hamburg" . . . suffix by using for loop in a task via Powershell.
below task should work like that : (psode code)
var listoflocations = [istanbul,berlin.hamburg, . . ]
foreach location in listoflocations
powershell -create mywebjob-location
my yaml file (small part): how can I use powershell below ?
For this purpose I spend my time with some changes Thanks to your advice.
When I run below yaml I am getting this error:
- stage: Deploy_Test
displayName: 'Deploy test'
dependsOn: Test
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
pool:
name: 'bmersgtsteuw-app-eurotracs-pool'
jobs:
- deployment: yyyOrderShipmentJob
displayName: 'Deploy Order Shipment Job'
environment: 'xxx-CF-Test'
strategy:
runOnce:
deploy:
steps:
- download: current
artifact: drop
- task: "HOW CAN I USE POWERSHELL HERE WITH FOREACH LOOP ? [istanbul,berlin.hamburg, . . ]"
inputs:
ConnectionType: AzureRM
azureSubscription: 'ARM-Con-xxx-yyy-TST-EUW-APP'
appType: 'webApp'
WebAppName: 'bmeapptsteuw-app-eurotracs'
package: '$(Pipeline.Workspace)/drop/xxx.yyy.OrderShipmentJob-$(Build.BuildNumber).zip'
removeAdditionalFilesFlag: true
My FINAL pipeline yaml :
trigger:
- main
pool:
vmImage: ubuntu-latest
parameters:
- name: locations
type: object
default: [Berlin,Hamburg,Südwestfalen,Weser-Ems,Ostfalen,Westfalen]
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script'
- ${{ each location in parameters.locations }}:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: 'Write-Host ${{ location }}'
- script: |
echo Add other tasks to build, test, and deploy your project.
echo See https://aka.ms/yaml
displayName: 'Run a multi-line script'
- task: DotNetCoreCLI#2
inputs:
command: 'publish'
publishWebProjects: false
projects: '**/MyWebJob.csproj'
arguments: '--configuration $(buildConfiguration) --output $(build.artifactStagingDirectory)\App_Data\jobs\continuous\MyWebJob-${{ location }}'
zipAfterPublish: false
modifyOutputPath: false
- task: PublishBuildArtifacts#1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'
MY DESIRE RESULT :
In Azure DevOps Pipeline, you can define all location values in Object type Parameters. And then you can loop the parameter to get each value one by one via parameter expression(- ${{ each location in parameters.locations }}:).
Here is an example:
parameters:
- name: locations
type: object
default: [istanbul,berlin.hamburg,xx,xxx,xxxx]
jobs:
- deployment: test
displayName: 'Deploy Order Shipment Job'
environment: 'xxx-CF-Test'
strategy:
runOnce:
deploy:
steps:
- ${{ each location in parameters.locations }}:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: 'Write-Host ${{ location }}'
For more detailed info, you can refer to this doc: Parameters
Update:
pool:
vmImage: ubuntu-latest
parameters:
- name: locations
type: object
default: [Berlin,Hamburg,Südwestfalen,Weser-Ems,Ostfalen,Westfalen]
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script'
- ${{ each location in parameters.locations }}:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: 'Write-Host ${{ location }}'
- task: DotNetCoreCLI#2
inputs:
command: 'publish'
publishWebProjects: false
projects: '**/MyWebJob.csproj'
arguments: '--configuration $(buildConfiguration) --output $(build.artifactStagingDirectory)\App_Data\jobs\continuous\MyWebJob-${{ location }}'
zipAfterPublish: false
modifyOutputPath: false
- task: PublishBuildArtifacts#1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'

Pass value through jobs in Azure DevOps pipeline

I try to pass value through my jobs in Azure DevOps pipeline and I use for it this code:
trigger: none
pool:
vmImage: 'windows-2019'
stages:
- stage: Processing
jobs:
- job: A
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
$someValue = 1234
Write-Host ("##vso[task.setvariable variable=someValue; isOutput=true;]$someValue")
- job: B
dependsOn: ['A']
variables:
someValue: $[ dependencies.A.outputs['setVariable.someValue'] ]
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
Write-host "Hello there"
echo $(someValue)
As a result I get this:
What do I wrong? What code do I need for passing value?
Test your YAML sample and reproduce the same issue.
From your YAML code, it has the following issues.
1.When you set the variable in Powershell task, the command has an extra space character in the command.
Refer to the following sample to set variable:
Write-Host "##vso[task.setvariable variable=someValue;isOutput=true;]$someValue"
2.You need to define the name of the PowerShell task which is used to set the variable. Then you can use the name in next job to get the variable. name: taskname
Here is an full example:
pool:
vmImage: 'windows-2019'
stages:
- stage: Processing
jobs:
- job: A
steps:
- task: PowerShell#2
name: taskname
inputs:
targetType: 'inline'
script: |
$someValue = 1234
Write-Host "##vso[task.setvariable variable=someValue;isOutput=true;]$someValue"
- job: B
dependsOn: A
variables:
someValue: $[ dependencies.A.outputs['taskname.someValue'] ]
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
Write-host "Hello there"
echo $(someValue)
For more detailed info, you can refer to this doc: Share variables across pipelines

Pass keyvault variable to stage template azure devops pipeline

If I do the same thing but don't use a template so passing variables between 2 stages then it works and I can echo "$(varFromStageA)" but when I implement the same using a template the variable is blank.
azure-pipeline.yaml
stages:
- stage: A
jobs:
- job: JA
steps:
- task: AzureKeyVault#1
displayName: 'Get Secret'
inputs:
azureSubscription: "***********"
KeyVaultName: "*****"
SecretsFilter: '*'
RunAsPreJob: true
- script: |
echo "This is job Foo."
echo "##vso[task.setvariable variable=doThing;isOutput=true]$(MySecret)"
name: DetermineResult
- script: echo $(DetermineResult.doThing)
name: echovar
my-pipeline-template.yaml
parameters:
#source
sourceAccountEndpoint: '******'
sourceDatabaseName: '*****'
sourceAccount: '****'
sourceEnvironment: '******'
- stage: DownloadScript
displayName: migrata data
dependsOn: A
jobs:
- job: Pull
variables:
varFromStageA: $[stageDependencies.A.DetermineResult.outputs['DetermineResult.doThing'] ]
pool:
vmImage: windows-latest
displayName: migrate
steps:
- checkout: self
- task: Powershell#2
inputs:
targetType: 'inline'
script: |
echo "$(varFromStageA)"
Refer to this doc: Jobs can access output variables from previous stages
The format of referencing variables between stages is as follows:
stageDependencies.stageName.jobName.outputs['stepName.variableName']
From your YAML Sample, stageName: A, JobName : JA.
So you need to define the variable in template with the following format:
varFromStageA: $[stageDependencies.A.JA.outputs['DetermineResult.doThing']
Then the value of the variable can be passed.
Template example:
stages:
- stage: DownloadScript
displayName: migrata data
dependsOn: A
jobs:
- job: Pull
variables:
varFromStageA: $[stageDependencies.A.JA.outputs['DetermineResult.doThing'] ]
pool:
vmImage: windows-latest
displayName: migrate
steps:
- checkout: self
- task: Powershell#2
inputs:
targetType: 'inline'
script: |
echo "$(varFromStageA)"
Have a look at this:
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch
There's some documented examples - it might help. However, why not just set a global variable in the yaml file (i.e. above the stages)? It's not clear from your question why you can't do this.
If you can, something like this:
variables:
var1: newitem
stages:
- stage: one
etc
If that won't work, try these approaches:
https://arunksingh16.medium.com/azure-devops-share-variable-across-stages-9bca85abfe8a
https://stefanstranger.github.io/2019/06/26/PassingVariablesfromStagetoStage/

Azure DevOps Passing Variables

we are trying to create a DevOps pipeline where we generate a string in the first stage and we would like to store into a variable which can be used in subsequent stages, or in subsequent tasks within the same stage, is there a way to do this? For clarity the string is generated by querying an external api which returns a string value.
Hope that makes sense 🥳
Thanks in advance
Yes, you shoudl use logging command and mark is as output. Here you have an example
## azure-pipelines.yml
stages:
- stage: one
jobs:
- job: A
steps:
- task: Bash#3
inputs:
filePath: 'script-a.sh'
name: setvar
- bash: |
echo "##vso[task.setvariable variable=skipsubsequent;isOutput=true]true"
name: skipstep
- stage: two
jobs:
- job: B
variables:
- name: StageSauce
value: $[ stageDependencies.one.A.outputs['setvar.sauce'] ]
- name: skipMe
value: $[ stageDependencies.one.A.outputs['skipstep.skipsubsequent'] ]
steps:
- task: Bash#3
inputs:
filePath: 'script-b.sh'
name: fileversion
env:
StageSauce: $(StageSauce) # predefined in variables section
skipMe: $(skipMe) # predefined in variables section
- task: Bash#3
inputs:
targetType: 'inline'
script: |
echo 'Hello inline version'
echo $(skipMe)
echo $(StageSauce)