How to specify dynamic value as environment name for virtual machine resource in yaml pipelines - azure-devops

We are planning to move our release pipelines to yaml and we are ready with it.
I have multiple environments like dev, test and prod where I'm trying to use same deployment job templates for all environments.
jobs:
- deployment: deploy
displayName: Deploy
environment:
name: dev # This should be replaced with environment specific variable
resourceType: VirtualMachine
tags: WEB01
In above code, my intension is to provide name as environment specific variable. Could someone pls help?
Thank you!

You can do this with parameters, but you need to use the expression syntax which is evaluated when the pipeline is compiled
parameters:
- name: environment
type: string
default: dev
values:
- dev
- test
- preprod
- prod
jobs:
- deployment: deploy
displayName: Deploy
environment:
name: ${{ parameters.environment }}
resourceType: VirtualMachine
tags: WEB01

You might like my answer in another post. it does stages per environment with approvals.
https://stackoverflow.com/a/74159554/4485260

Related

Show deployed application versions in Environments tab

I have a deployment pipeline in azure-devops and it takes artifacts from other pipelines and deploy it to different environments. Yml looks like this:
...
resources:
repositories:
- repository: self
trigger:
branches:
include:
- develop
- release
- master
pipelines:
- pipeline: pipeline-1
source: different-repo-pipeline-1
- pipeline: pipeline-2
source: different-repo-pipeline-2
...
jobs:
- deployment: some-name
environment: develop
strategy:
runOnce:
deploy:
steps:
- download: pipeline-1
- download: pipeline-2
# Do real deployment
After deployment on target environment tab I saw:
There is no clue on it about deployed versions. I know this version inside deployment steps, or at least can use variables from pipelines (resources.pipeline.pipeline-1.runName). But I don't see any options to add this info to Environment deployment tab. Can it be done in some ways?
No, this is not possible. We don't have any way to control what is displayed on environment tab.

Why can't I use a variable to define the environment property in the Azure Pipeline YAML config file?

I'm trying to create a deploy pipeline YAML template for all environments/stages. I've set up the Environments on Azure DevOps so that I can add checks and approvals on the Test and Prod environments before they get deployed. I've set up a library group for each stage and each one of them has a variable called 'env' which defines the current stage running in the pipeline. For some reason, the environment property under the deployment job (see code snippet below) doesn't read that variable.
Has anyone faced this issue before, or is there a reason why the variable won't be read for that specific property?
Note: I've tested the variables and they do work, for example, the stage property outputs as 'deploy-dev/test/prod' (depending on the environment)
- stage: deploy-$(env)
jobs:
- deployment: DeployWeb
displayName: deploy Web App
pool:
vmImage: 'Ubuntu-latest'
# creates an environment if it doesn't exist
environment: 'smarthotel-$(env)'
strategy:
runOnce:
deploy:
steps:
- script: echo Hello world
You can't do this because it have to be know at compilation phase.
But you can try this (lets name this file deploy.yml):
parameters:
- name: env
type: string
default: 'dev'
stages:
- stage: deploy-${{ parameters.env }}
jobs:
- deployment: DeployWeb
displayName: deploy Web App
pool:
vmImage: 'Ubuntu-latest'
# creates an environment if it doesn't exist
environment: 'smarthotel-${{ parameters.env }}'
strategy:
runOnce:
deploy:
steps:
- script: echo Hello world
and then you need to run as follows (in build.yml file):
stages:
- template: deploy.yml
parameters:
env: dev
- template: deploy.yml
parameters:
env: qa
- template: deploy.yml
parameters:
env: prod

How to pass in environment variables when deploying to AKS from Azure DevOps

I want to deploy a custom SQL Server image, which needs 4 environment variables passed in to AKS using the following pipeline definition:
jobs:
- deployment: Deploy
condition: and(succeeded(), not(startsWith(variables['Build.SourceBranch'], 'refs/pull/')))
displayName: Deploy
pool:
vmImage: $(vmImageName)
environment: 'xxxx.default'
strategy:
runOnce:
deploy:
steps:
- task: KubernetesManifest#0
displayName: Create imagePullSecret
inputs:
action: createSecret
namespace: $(k8sNamespace)
secretName: $(imagePullSecret)
dockerRegistryEndpoint: $(dockerRegistryServiceConnection)
- task: KubernetesManifest#0
displayName: Deploy to Kubernetes cluster
inputs:
action: deploy
namespace: $(k8sNamespace)
manifests: |
$(Pipeline.Workspace)/manifests/deployment.yml
$(Pipeline.Workspace)/manifests/service.yml
imagePullSecrets: |
$(imagePullSecret)
containers: |
$(containerRegistry)/$(imageRepository):$(tag)
The manifest files are created by Azure DevOps in this instance, so how would I go along, if I wanted to inject the SA_Password / inistial user configuration for this container?
https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/kubernetes-manifest?view=azure-devops#deploy-action
kubernetes-manifest deploy action doesn't have the option to add extra environment variables. Feel free to open a feature request at https://github.com/microsoft/azure-pipelines-tasks/issues
You can do two options, write a script with yq (https://github.com/mikefarah/yq) to update the manifest files before deployment
Or use the KubernetesManifest patch option (https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/kubernetes-manifest?view=azure-devops#patch-action), for example
steps:
- task: KubernetesManifest#0
displayName: Patch
inputs:
action: patch
kind: pod
name: demo-5fbc4d6cd9-pgxn4
mergeStrategy: strategic
patch: '{"spec":{"template":{"spec":{"containers":[{"env":[{"name":"SA_Password","value":"1234"}]}]}}}}'
kubernetesServiceConnection: someK8sSC
namespace: default
My contribution to Tummala comment is that if you have control over how the docker image is built, I suggest adding env variables from there instead. So if you have a docker build that is triggered when commiting on the develop branch, you can just pass that env to that docker image.
I have a dedicated post talking about CI/CD in Azure DevOps, in case you're interested in: Building CI/CD pipelines for Kubernetes with Azure DevOps and GitFlow.

AzureDevOps - YML - How to use deployment job output variable with VM resource

I have a environment with two VMs, tagges with "SQL" and "APP", I would like to have deployment job targeting SQL vm and having step, creating a output variable, another deployment job targeting "APP" VM should able to consume it in its step
Reference doc
Job consuming the variable should use syntax like -
$[dependencies.<job-name>.outputs['<lifecycle-hookname>_<resource-name>.<step-name>.<variable-name>']]
Consider a scenario you have environment with name "env-vm"
env-vm has two vms registered with it, vm1 with tag SQL and vm2 with tag APP. refer below sample for how to produce and consume the output variable from deployment job
jobs:
- deployment: producer
environment:
name: env-vm
resourceType: VirtualMachine
tags: SQL
strategy:
runOnce:
deploy:
steps:
- script: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the deployment variable value"
name: setvarStep
- script: echo $(setvarStep.myOutputVar)
name: echovar
- deployment: consumer_deploy
dependsOn: producer
variables:
myVarFromDeploymentJob: $[ coalesce(dependencies.producer.outputs['deploy_Vm1.setvarStep.myOutputVar'], 'fubar') ]
environment:
name: env-vm
resourceType: VirtualMachine
tags: APP
strategy:
runOnce:
deploy:
steps:
- script: "echo $(myVarFromDeploymentJob)"
name: echovar

Azure DevOps Pipeline define variable in deployment and reuse in subsequent job

I'm using an Azure DevOps pipeline to deploy my code and now I'm in need of passing a variable value from a deployment job to a subsequent job that depends on it. I've read up on this example but it does not seem to work at all.
What I'm trying to do is run an Azure ARM Deployment that provisions a Key Vault. The name of the key vault is outputted from the ARM deployment job and I'm then trying to pass that name to another job which needs to add specific secrets. Access control is taken care of, but I still need to pass the name.
I've boiled the problem down to the basics of passing a variable from a deployment to a job. Here is my complete test pipeline (almost entirely copied from here):
trigger: none
stages:
- stage: X
jobs:
- deployment: A
pool:
vmImage: "ubuntu-16.04"
environment: test
strategy:
runOnce:
deploy:
steps:
- script: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the deployment variable value"
name: setvarStep
- script: echo $(setvarStep.myOutputVar)
name: echovar
- job: B
dependsOn: A
pool:
vmImage: "ubuntu-16.04"
variables:
myVarFromDeploymentJob: $[ dependencies.A.outputs['deploy.setvarStep.myOutputVar'] ]
steps:
- script: "echo $(myVarFromDeploymentJob)"
name: echovar
Once I run this the echoed value is blank in job B, but defined in deployment A. Why is this? And is there a way to dum everything in dependencies.A.outputs so that I can see what I have to work with?
How can I pass a variable from a runOnce deployment job to a regular job?
I've solved it. The problem is that the documentation here specifies this schema for fetching the variable for a runOnce deployment:
$[dependencies.<job-name>.outputs['<lifecycle-hookname>.<step-name>.<variable-name>']]
This is in fact WRONG. The <lifecycle-hookname> parameter should be replaced with the name of the deployment like this:
$[dependencies.<job-name>.outputs['<job-name>.<step-name>.<variable-name>']]
The example from this documentation (scroll down a bit) is correct.
A full example pipeline that I've tested and works:
trigger: none
stages:
- stage: X
jobs:
- deployment: A # This name is important
pool:
vmImage: 'ubuntu-16.04'
environment: staging
strategy:
runOnce:
deploy:
steps:
- script: echo "##vso[task.setvariable variable=myOutputVar;isOutput=true]this is the deployment variable value"
name: setvarStep # This name is also important
- script: echo $(setvarStep.myOutputVar)
name: echovar
- job: B
dependsOn: A
pool:
vmImage: 'ubuntu-16.04'
variables:
myVarFromDeploymentJob: $[ dependencies.A.outputs['A.setvarStep.myOutputVar'] ]
steps:
- script: "echo $(myVarFromDeploymentJob)"
name: echovar