azureazure-devopsazure-pipelines-yamlazure-pipelines-tasks

How to parametrize Azure DevOps Deployment YAML Pipelines to deploy to multiple environments


I have an Azure DevOps Deployment YAML Pipeline that creates an Azure App Service and deploys code to it. The actual pipeline is more complex, but I am simplifying it for this question.

Currently my pipeline can successfully deploy to a specific Azure Subscription (Service Connector) with resource names defined in variables.

I need to parametrize the pipeline so that it can deploy to several different environments (means Azure Subscriptions) using multiple Service Connectors. Each environment has a different Azure Resource naming convention.

Is there any way to read the value of pipeline variables from an XML or JSON file? This way I can have multiple config files for each environment and store them as part of my repository.

Is this a right approach for multi-environment deployment pipeline configuration?


Solution

  • You can use variable templates. There is another interesting link: Learn more about variable reuse with templates.

    Here I have this flat folder structure (for the clarity of the sample):

    .
    |  deploy-app.job.yaml
    |  deploy-app.pipeline.yaml
    |  variables.dev.yaml
    |  variables.prod.yaml
    

    So here we're trying to run the reusable job deploy-app.job.yaml with different variable sets.

    I've defined some variables in each variable.{env}.yaml files

    # variables.dev.yaml
    variables:
      vmImage: ubuntu-20.04
      serviceConnection: dev-service-connection
    
    # variables.prod.yaml
    variables:
      vmImage: ubuntu-20.04
      serviceConnection: prod-service-connection
    
    

    The deploy-app.job.yaml file accepts a parameter that allow to inject a variable template:

    # deploy-app.job.yaml
    parameters:
    - name: envVariablesTemplate
      type: string
    
    jobs:
    - deployment: deploy
      variables:
      # Inject the verianle template here
      - template: ${{ parameters.envVariablesTemplate }}
      pool:
        # Use the variable from the template
        vmImage: ${{ variables.vmImage }}
      strategy:
        runOnce:
          deploy:
            steps:
            - task: AzureCLI@2
              displayName: Hello from azure cli
              inputs:
                # Use the variable from the template
                azureSubscription: ${{ variables.serviceConnection }}
                scriptType: pscore
                scriptLocation: inlineScript
                inlineScript: echo 'Hello from azure cli'
    
    

    In the main pipeline, I can create different stages and inject the desired vairables:

    # deploy-app.pipeline..yaml
    stages:
    - stage: dev
      condition: succeeded()
      jobs:
      - template: ./deploy-app.job.yaml
        parameters:
          envVariablesTemplate: ./variables.dev.yaml
    
    - stage: prod
      dependsOn: dev
      condition: succeeded()
      jobs:
      - template: ./deploy-app.job.yaml
        parameters:
          envVariablesTemplate: ./variables.prod.yaml
    

    Based on your needs, you can add multiple variable templates, having a naming convention etc. Really up to you and depends on the complexity of your pipelines.