---
title: Azure DevOps Pipelines with multiple schedules
description: The client wants an Azure DevOps native solution, and everything is deployed by ADO pipelines.
image: https://22238495.fs1.hubspotusercontent-na1.net/hubfs/22238495/pipelines.webp
---

[![Frontier logo with white text](https://22238495.fs1.hubspotusercontent-na1.net/hubfs/22238495/frontier-logo-horizontal-white.svg)](https://frontierhq.com)

- [KUBERNETES](https://frontierhq.com/kubernetes)
- [DATA & AI](https://frontierhq.com/data-ai)
- [CLOUD](https://frontierhq.com/cloud)
- [AUTOMATION](https://frontierhq.com/automation)
- [PRODUCTS](https://frontierhq.com/products)
- ABOUT US
  
    - [PARTNERS](https://frontierhq.com/partners)
    - [WHO WE ARE](https://frontierhq.com/who-we-are)
    - [THOUGHT LEADERSHIP](https://frontierhq.com/blog)

[Let's Chat](https://frontierhq.com/lets-chat)

Technical

# Azure DevOps Pipelines with multiple schedules

The client wants an Azure DevOps native solution, and everything is deployed by ADO pipelines.

[Neil](https://frontierhq.com/blog/author/neil)

 Feb 22, 2023

<http://www.facebook.com/share.php?u=https://frontierhq.com/blog/azure-devops-pipelines-with-multiple-schedules&utm_medium=social&utm_source=facebook> <http://www.linkedin.com/shareArticle?mini=true&url=https://frontierhq.com/blog/azure-devops-pipelines-with-multiple-schedules&utm_medium=social&utm_source=linkedin> <https://twitter.com/intent/tweet?original_referer=https://frontierhq.com/blog/azure-devops-pipelines-with-multiple-schedules&utm_medium=social&utm_source=twitter&url=https://frontierhq.com/blog/azure-devops-pipelines-with-multiple-schedules&utm_medium=social&utm_source=twitter&source=tweetbutton&text=> [mailto:?subject=Check%20out%20https://frontierhq.com/blog/azure-devops-pipelines-with-multiple-schedules&utm_medium=social&utm_source=email%20&body=Check%20out%20https://frontierhq.com/blog/azure-devops-pipelines-with-multiple-schedules&utm_medium=social&utm_source=email](mailto:?subject=Check%20out%20https://frontierhq.com/blog/azure-devops-pipelines-with-multiple-schedules&utm_medium=social&utm_source=email%20&body=Check%20out%20https://frontierhq.com/blog/azure-devops-pipelines-with-multiple-schedules&utm_medium=social&utm_source=email)

---

## Context

A client is aware that significant cost savings could be realised by a scheduled manipulation of some of their deployed resources and services. Their working week leads to predictable hot and cold periods in the utilisation of their build services and pre-production environments in which scaling up and down could take place.

The resources in question don’t have any other suitable means to scale based on demand.

The client wants an Azure DevOps native solution, and everything is deployed by ADO pipelines.

## The goal

I would like to provide a single pipeline, which executes on a defined schedule, and applies some settings appropriate for that time. Sort of like an old programmable thermostat.

Simplistically, it’s likely to be “run a scale up” or “run a scale down”.

ADO provides scheduled triggers, defined using a cron syntax. You can set a pipeline to run whenever you want. You can set multiple cron schedules for a single job.

I’m picturing a pipeline something like this:

```
# Two trigger definitions
schedules:
  - cron: "0 18 * * Mon-Fri"
    displayName: Every weekday at 1800
    branches:
      include:
        - master
    always: true

  - cron: "0 8 * * Mon-Fri"
    displayName: Every weekday at 0800
    branches:
      include:
        - master
    always: true

stages:
  - stage: Run_task
    jobs:
      - job: Task
        pool: hubAgents
        steps:
          - bash: # do different stuff depending on which cron schedule triggered us
```

## ADO Limitations

However, there’s a painful limitation: you cannot - within the YAML schema - set parameters or variables per trigger. Moreover, a running pipeline doesn’t “know” which particular cron schedule triggered it.

ADO exposes many [built in variables](https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml#agent-variables-devops-services), but it strangely seems that inspecting the trigger is one of them.

You could create multiple pipelines - one for each schedule - with some hardcoded set of arguments to pass to your pipeline payload template, but that creates duplication, and will get unmanageable quickly. I am also working in a [Frontier Digital](https://frontierdigital.net/) ADO framework where GitOps rules all, and there’s automation both upstream and downstream creating and consuming the config - even *this* pipeline will be programmatically created!

## REST API to the rescue

There is however the trusty ADO REST API. It has all the trigger information - what we need is for our pipeline to query the API for information about itself as it’s running.

We can see in [the docs](https://learn.microsoft.com/en-us/rest/api/azure/devops/build/builds/get?view=azure-devops-rest-6.1#build) that the `builds/build` endpoint returns an object containing what we need:

Here’s an example of the API response from the endpoints that we’re interested in

```
{
  // ...
  "triggerInfo": {
    "scheduleName": "Every weekday at 1800"
  },
  // ...
}
```

Where `scheduleName` contains the `displayName` for the triggering schedule.

This can be done with a relatively simple `bash` task using `curl`, piping the returned JSON into `jq` to allow us to pull out what we’re after and set a variable.

This task is completely portable with no parameters needed as all settings can be pulled from built in variables!

### The task

```
steps:
  - bash: |
      set -euo pipefail
      schedule_name=$( \
        curl \
          -H "Content-Type: application/json" \
          -s \
          -u ":$(System.AccessToken)" `# authenticate with Access Token` \
          "$(System.CollectionUri)/$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)?api-version=7.0" |
        jq --raw-output '.triggerInfo.scheduleName' \
      )
      echo "##vso[task.setvariable variable=scheduleName]$schedule_name"
      echo "##vso[task.setvariable variable=scheduleName;isOutput=true]$schedule_name"      
    name: getScheduleName
```

#### Building up the API endpoint

- `System.CollectionUri`: `https://dev.azure.com/my-org/`
- `System.TeamProject`: `my-project`
- `Build.BuildId`: The Id for *this* running pipeline

#### jq options

- `--raw-output`: removes quotes around the returned value

The task sets a variable `$schedule_name` (and an output variable too, for multi stage goodness), which can be passed on to whatever the main payload of the pipeline is.

In my situation, I use it to filter a configuration file. The payload itself doesn’t need to know if it’s scaling up or down, it’s just applying whatever the filtered configuration is!

Unfortunately this variable is obviously only available at run time, so can’t be used as a template variable for ADO native template conditions etc. You have to make some switching within your main payload.

### Non-scheduled pipeline runs

Manual runs of the pipeline won’t have a `scheduleName` set. The returned object looks like this:

```
{
  // ...
  "triggerInfo": {},
  // ...
}
```

In this instance, our task returns a string with the literal value `null`. We can handle this special case in our code.

## Summary

It would be great if ADO just exposed this information for us, but at least this way we can work around it and have one scheduled pipeline that handles all the cases.

[Technical](https://frontierhq.com/blog/tag/technical)

## Similar posts

<https://frontierhq.com/blog/autoscaling-kubernetes-workloads-with-custom-schedules>

Technical

### [Autoscaling Kubernetes workloads with custom schedules](https://frontierhq.com/blog/autoscaling-kubernetes-workloads-with-custom-schedules)

Would you like to know how we cut annual cloud costs by over 45% for one of our major financial services clients? Read on!

 Anthony  Aug 3, 2023

<https://frontierhq.com/blog/operating-a-terraform-module-service-catalog-part-1>

Technical

### [Operating a Terraform module service catalog (Part 1)](https://frontierhq.com/blog/operating-a-terraform-module-service-catalog-part-1)

First in a series of posts showing how we operate a service catalog for Terraform modules - infrastructure as code components - on GitHub.

 Fraser  Sep 9, 2024

<https://frontierhq.com/blog/integrating-a-custom-web-app-with-the-elastic-elk-stack-using-saml>

Technical

### [Integrating a custom web app with the Elastic (ELK) stack using SAML](https://frontierhq.com/blog/integrating-a-custom-web-app-with-the-elastic-elk-stack-using-saml)

In this post I'll show how we integrated a custom web app with Elasticsearch using SAML in Elastic Cloud, and improved the user experience in the...

 Fraser  Oct 22, 2024

[![Frontier logo with white text](https://22238495.fs1.hubspotusercontent-na1.net/hubfs/22238495/frontier-logo-horizontal-white.svg)](https://frontierhq.com)

Centrum House  
38 Queen Street  
Glasgow G1 3DX

### Products

- [Sheriff](https://frontierhq.com/products/sheriff)
- [Governor](https://frontierhq.com/products)
- [Wrangler](https://frontierhq.com/products)
- [Ranger](https://frontierhq.com/products)

### Solutions

- [Cloud landing zones](https://frontierhq.com/solutions)
- [Container platforms](https://frontierhq.com/solutions)
- [Deployment automation](https://frontierhq.com/solutions)
- [Security automation](https://frontierhq.com/solutions)

### Company

- [Who we are](https://frontierhq.com/who-we-are)
- [Thought leadership](https://frontierhq.com/blog)
- [Contact us](https://frontierhq.com/lets-chat)
- [Terms](https://frontierhq.com/terms-and-conditions)

![Microsoft Partner logo](https://22238495.fs1.hubspotusercontent-na1.net/hub/22238495/hubfs/SolutionsPartner-png-1.png?width=163&height=100&name=SolutionsPartner-png-1.png) ![Kubernetes Certified Service Provider logo](https://22238495.fs1.hubspotusercontent-na1.net/hubfs/22238495/kubernetes-kcsp-color-1.svg) ![Elastic Partner logo](https://22238495.fs1.hubspotusercontent-na1.net/hub/22238495/hubfs/partner-badge.png?width=100&height=100&name=partner-badge.png)![SUSE Emerald Partner logo](https://22238495.fs1.hubspotusercontent-na1.net/hub/22238495/hubfs/Sell%20Emerald%20Partner.png?width=100&height=100&name=Sell%20Emerald%20Partner.png)![Cyber Essentials logo](https://22238495.fs1.hubspotusercontent-na1.net/hub/22238495/hubfs/Cyber-Essentials-Logo-v2.png?width=84&height=100&name=Cyber-Essentials-Logo-v2.png) ![Living Wage Employer logo](https://22238495.fs1.hubspotusercontent-na1.net/hub/22238495/hubfs/living-wage-employer-logo.png?width=127&height=100&name=living-wage-employer-logo.png) ![Great Place To Work logo](https://22238495.fs1.hubspotusercontent-na1.net/hubfs/22238495/great-place-to-work-logo.svg)

© 2026 Frontier

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Neil",
    "url" : "https://frontierhq.com/blog/author/neil"
  },
  "dateModified" : "2024-12-04T18:15:16.947Z",
  "datePublished" : "2023-02-22T11:47:00.000Z",
  "headline" : "Azure DevOps Pipelines with multiple schedules",
  "image" : [ "https://22238495.fs1.hubspotusercontent-na1.net/hubfs/22238495/pipelines.webp" ],
  "mainEntityOfPage" : {
    "@id" : "https://frontierhq.com/blog/azure-devops-pipelines-with-multiple-schedules",
    "@type" : "WebPage"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://22238495.fs1.hubspotusercontent-na1.net/hubfs/22238495/RGB_Frontier_Logo_Colour+Grey.png"
    },
    "name" : "Frontier"
  }
}
```