Azure DevOps YAML build pipeline : How to use variables?
Tags: azure, devops, yaml
Published: 2020-01-20 09:01:39

---
title: Azure DevOps YAML build pipeline : How to use variables?
published: true
description: 
tags: azure,devops,yaml
cover_image: https://thepracticaldev.s3.amazonaws.com/i/p3vmmj2cga30lo7lu5xd.jpg
---

I use Azure DevOps for long time, and I always use GUI when crafting Build Pipeline so far, though I knew Azure DevOps supports YAML and its benefits.

So this time, I tried YAML instead of GUI and I learnt many things. In this article, I talk about "variables".

# Variables in GUI

Let's start from GUI. There is a place to store variables for pipeline scope.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/wc1y8q89yai2za7cddfm.jpg)

And global scope.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/6ozycpjvqlztoem0q0xa.jpg)

Use $(xxx) format to reference it.

# Variable in YAML

First of all, I can reference variable same as GUI. In addition, I can directly write parameter in YAML.

```yaml
variables:
  myval: 1
```

I can also use all the out-of-box variables as well as my own defined variable groups.

# Secret value

As YAML is simply a text file, I shouldn't store any secret. I can use "Variable" feature of YAML editor to store both non-secure and secure variables.

1. Click "Variables".
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/lku0co2bnnuo8kv6rtu7.jpg)

1. Click "New Variable".
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/f8hrj5nvikrr1fajjaku.jpg)

1. Enter info. Check "Keep this value secret" if it's secret :)
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/4kmk8y7bb78mvy2w8r48.jpg)

1. Keep adding as necessary.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/1h2l0cvrte4a0c9v3uqf.jpg)

But where this variables are stored?

1. Go to triggers first.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/hpiysy9muc96svz5duts.jpg)

1. Then you see variables tab like GUI pipeline.
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/16dq6zxs41328imf3vge.jpg)

It's easy to store, but I needed to know the trick to use it, as I couldn't simply reference it. It was obvious if I read the document carefully, but I didn't :D. Basically, I need to map the variable to environment variable to reference it.

```yaml
steps:

- powershell: |
    # Using an input-macro:
    Write-Host "This works: $(mySecret)"

    # Using the env var directly:
    Write-Host "This does not work: $env:MYSECRET"

    # Using the mapped env var:
    Write-Host "This works: $env:MY_MAPPED_ENV_VAR"    # Recommended
  env:
    MY_MAPPED_ENV_VAR: $(mySecret)
```

# Variable Template

The reason why I use variable group is to grouping variables. Then, I realized that YAML also has similar feature, called variable template.

[Template types & usage](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops)

I just need to create YAML file contains variables I want to group.

```yaml
# File: vars.yml
variables:
  favoriteVeggie: 'brussels sprouts'
```

Then reference it in another YAML.

```yaml
variables:
- template: vars.yml  # Template reference

steps:
- script: echo My favorite vegetable is ${{ variables.favoriteVeggie }}.
```

Templates are not only for variables but for more powerful stuff. I will find sometime later to talk about what I found in template if I can.

# Service Connection as variable

One of the variable I couldn't figure out at first was service connection.
I tried to build and push docker container to Azure Container Registry and refer to the documentation below.

[Build and push to Azure Container Registry](https://docs.microsoft.com/en-us/azure/devops/pipelines/ecosystems/containers/acr-template?view=azure-devops)

Inside the article, there is YAML example.

```yaml
- stage: Build
  displayName: Build and push stage
  jobs:  
  - job: Build
    displayName: Build job
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)
```

I couldn't find where this **dockerRegistryServiceConnection** variable comes in,  and I later realized I simply pass the service connection name as parameter.

When I use template, it gave me GUID but I actually can simply use string name of the service connection. In the example below, I set variable in YAML and use it.

```yaml
trigger:
- master

pool:
  vmImage: 'ubuntu-latest'

variables:
  acrConnection: 'MyAcrServiceConnection'
  imageName: 'sample-image'

steps:
- task: Docker@2
  displayName: BuildAndPushImageToACR
  inputs:
    repository: $(imageName)
    command: 'buildAndPush'
    containerRegistry: $(acrConnection)
    Dockerfile: '**/Dockerfile'
    tags: $(Build.BuildId)
```

# Summary

In this article, I talk about variables in YAML. I am glad to find that it can use all the variables from Library and pipeline scoped ones as GUI does. In addition I can write it to YAML so it's easy to migrate to other DevOps environment.