Menu
Grafana Cloud

Schedules as code

This topic explains how to manage on-call schedules in Grafana Incident Response Management (IRM) using Infrastructure as Code (IaC).

Overview

Managing on-call schedules using Infrastructure as Code enables you to:

  • Automate schedule creation and updates
  • Maintain consistency across environments
  • Track changes with version control
  • Integrate schedule management into your CI/CD pipeline
  • Scale schedule management across multiple teams and services

Grafana IRM supports two primary methods for managing schedules as code:

  1. Using Terraform with the Grafana provider
  2. Using the Grafana IRM API directly

Manage on-call schedules with Terraform

Terraform allows you to define on-call schedules as code, ensuring reproducibility and version control. Using the Grafana Terraform provider, you can create and manage on-call schedules within Grafana IRM.

Before you begin

You need:

  • A Grafana Cloud account using IRM
  • A Grafana Service Account token with appropriate permissions (preferred, otherwise a Grafana IRM OnCall API token works too)
  • Terraform installed ( Install Terraform)
  • Grafana provider configured ( Terraform Provider Documentation)

For initial setup, refer to Infrastructure as Code.

Example: Creating an on-call schedule with Terraform

The following example shows a basic on-call schedule configuration:

terraform
provider "grafana" {
  alias = "oncall"

  url        = "<Stack-URL>"
  auth       = "<Service-account-token>"
  oncall_url = "<OnCall-URL>"
}

resource "grafana_oncall_schedule" "example_schedule" {
  provider = grafana.oncall

  name      = "Primary On-Call Schedule"
  type      = "calendar"
  time_zone = "UTC"
}

Set up an on-call rotation via Terraform

The following example demonstrates how to set up a weekly rotation where two users alternate on-call duties.

Define users

First, reference the users who will participate in the rotation:

terraform
data "grafana_oncall_user" "user_one" {
  provider = grafana.oncall
  username = "user_one"
}

data "grafana_oncall_user" "user_two" {
  provider = grafana.oncall
  username = "user_two"
}

Create an on-call shift

Next, define the shift pattern:

terraform
resource "grafana_oncall_on_call_shift" "week_shift" {
  provider   = grafana.oncall
  name       = "Week shift"
  type       = "rolling_users"
  start      = "2025-03-01T00:00:00"
  duration   = 60 * 60 * 24  # 24 hours in seconds
  frequency  = "weekly"
  by_day     = ["MO", "TU", "WE", "TH", "FR", "SA", "SU"]
  week_start = "MO"
  rolling_users = [
    [data.grafana_oncall_user.user_one.id],
    [data.grafana_oncall_user.user_two.id]
  ]
  time_zone = "UTC"
}

For all available parameters, refer to the Grafana Terraform provider reference.

Connect the shift to a schedule

Create a schedule and associate it with the shift:

terraform
resource "grafana_oncall_schedule" "primary" {
  provider  = grafana.oncall

  name      = "Primary"
  type      = "calendar"
  time_zone = "UTC"
  shifts    = [
    grafana_oncall_on_call_shift.week_shift.id
  ]
}

Add the schedule to an escalation chain

Finally, add the schedule to an escalation chain to use it for incident notifications:

terraform
resource "grafana_oncall_escalation" "notify_schedule" {
  provider                     = grafana.oncall
  escalation_chain_id          = grafana_oncall_escalation_chain.default.id
  type                         = "notify_on_call_from_schedule"
  notify_on_call_from_schedule = grafana_oncall_schedule.primary.id
  position                     = 0
}

After applying your configuration with terraform apply, you can view your schedule in Grafana IRM under the Schedules tab or export it as an iCal link.

Manage on-call schedules with the API

The Grafana IRM API provides granular control over on-call schedules, enabling dynamic updates and integrations with other systems.

API endpoints

The On-Call Schedules API supports the following operations:

  • List schedules: GET /api/v1/schedules/
  • Create a schedule: POST /api/v1/schedules/
  • Update a schedule: PUT /api/v1/schedules/{schedule_id}
  • Delete a schedule: DELETE /api/v1/schedules/{schedule_id}

For complete API documentation, refer to the Grafana IRM API Reference: Schedules.

Example: Creating an on-call schedule via API

The following example shows how to create a schedule using a curl command:

bash
curl -X POST "https://<OnCall-API-URL>/api/v1/schedules/" \
-H "Authorization: Bearer $GRAFANA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "name": "Primary On-Call Schedule",
  "team_id": "your-team-id",
  "type": "calendar",
  "time_zone": "UTC"
}'

Time zone considerations

When working with schedules as code, time zones are a critical consideration:

  • Always specify the time zone for each rotation to avoid scheduling confusion
  • Use consistent time zone formats across your configuration
  • Consider the global distribution of your team when setting up rotations
  • Test schedules across time zone boundaries to ensure proper handoffs
  • Be aware of daylight saving time transitions when scheduling long-term rotations

Best practices for schedules as code

Follow these best practices when managing your on-call schedules as code:

  • Use source control: Store Terraform configurations and API scripts in a Git repository to track changes
  • Automate deployments: Use CI/CD tools like GitHub Actions or Terraform Cloud for managing schedules across environments
  • Apply role-based access control (RBAC): Restrict who can modify schedules via API keys and IAM policies to prevent unauthorized changes
  • Test before applying: Use terraform plan or API dry-runs to validate configurations before deploying to production
  • Document your approach: Maintain documentation about your schedule structure and rotation patterns
  • Implement monitoring: Set up alerts for schedule configuration changes or failures
  • Use variables and modules: Leverage Terraform variables and modules to create reusable schedule patterns

Additional resources