When the number of YAML pipelines you work with in Azure DevOps increases, you might find the need for centralizing some parts of the configuration variables for your pipeline(s). Maybe some configuration that is shared between multiple application components or even some values that are shared between multiple teams or managed by a central team.
To make this happen, you might be tempted to do either one of the following:
- Copy the configuration variables to every individual pipeline. The disadvantage of this is that you are now copying these values around and if one of them changes, this gives a lot of work and the risk of missing one or more of the necessary updates
- Use variable groups that you know from the Classic Build and Release definitions to manage central configuration. But if you do this, you loose some of the benefits of pipelines-as-code again.
Luckily there is now an alternative available, by combining some of the new YAML Pipelines features, namely variable templates and repository resources. In this post I want to share how I built a solution where configuration variables were centralized in one repository and used them from YAML pipelines in other repositories.
Let’s start by assuming that you have a number of pipelines, that all look somewhat like this:
pool: name: 'Azure Pipelines' vmImage: windows-latest variables: - allCompanyVariable: someValue - allComponentsVariable: someValue steps: - script: | echo $(allCompanyVariable) echo $(allComponentsVariable)
Of course the repetition is in these two variables and we want to centralize them out into some kind of configuration. To do this, I created a new repository named Shared-Configuration. In this repository I added a directory configuration with two files all-company.yml and my-department.yml, containing configuration values that need to be shared with multiple pipelines across multiple repositories.
These files are very straight forward and look like this:
variables: allCompanyVariable: someCompanyWideThingy foo: bar
resources: repositories: - repository: sharedConfigurationRepository type: git name: Shared-Configuration
variables: - template: configuration/all-company.yml@sharedConfigurationRepository - template: configuration/my-department.yml@sharedConfigurationRepository
Here we again declare variables, but instead of specifying key/value pairs we are now pulling in all variables from the referenced files. To do this, the full path to the file has to be specified along with a the identifier of the repository that holds this file. If the @-sign and the identifier are omitted, the path is assumed to be in the same repository as the pipeline definition.
Putting all of this together, the following syntax can be used for pulling variables defined in other, shared repositories into your YAML pipeline:
pool: name: 'Azure Pipelines' vmImage: windows-latest resources: repositories: - repository: sharedConfigurationRepository type: git name: Shared-Configuration variables: - template: configuration/all-company.yml@sharedConfigurationRepository - template: configuration/my-department.yml@sharedConfigurationRepository steps: - script: | echo $(allCompanyVariable) echo foo value is $(foo)