---
title: "Broadcast key updates to Microsoft Teams | Grafana Cloud documentation"
description: "Keep stakeholders informed by sharing every key update on a critical or major incident in a Microsoft Teams channel."
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

# Broadcast key updates to Microsoft Teams

> Note
> 
> Grafana Workflows is currently in [public preview](https://grafana.com/docs/release-life-cycle/). Grafana Labs offers limited support, and breaking changes might occur prior to the feature being made generally available.

Keep stakeholders informed by sharing every key update on a critical or major incident in a Microsoft Teams channel.

This Grafana Workflows blueprint is in the **Incidents** category of the Blueprints library.

## Before you begin

To use this blueprint, you need:

- Grafana IRM set up on your stack.
- The Grafana IRM Microsoft Teams integration. For details, refer to [Microsoft Teams integration for Grafana IRM](https://grafana.com/docs/grafana-cloud/alerting-and-irm/irm/integrations/chat-and-collaboration/ms-teams/).

## Steps

Steps run in order from first to last. A step inside a switch branch runs only when Workflows chooses that branch.

Expand table

| Step                     | ID            | Type                   | Description                                                                                              |
|--------------------------|---------------|------------------------|----------------------------------------------------------------------------------------------------------|
| Build the status line    | `status-line` | `transform`            | Shows the status change when the key update changed it, otherwise the current status. No changes needed. |
| Post the update to Teams | `post-update` | `msteams.message.post` | Posts the key update as an Adaptive Card. Pick the Teams team and stakeholder channel.                   |

For the inputs and outputs of each step type, refer to [Step and trigger types reference](https://grafana.com/docs/grafana-cloud/platform/workflows/reference/step-trigger-types).

Before you turn on the workflow, customize any steps that need input from you, such as a channel ID or a schedule name. Each step’s description says what to set.

## Workflow definition

Save this definition as a YAML file to create the workflow with gcx, the Workflows API, or Terraform, or give it to a coding agent as an example. Replace *FOLDER\_UID* with the UID of the folder for the workflow. Blueprints start disabled, so finish customizing the steps before you set `enabled` to `true`. For details, refer to [Manage workflows as code](https://grafana.com/docs/grafana-cloud/platform/workflows/as-code).

YAML ![Copy code to clipboard](https://grafana.com/media/images/icons/icon-copy-small-2.svg) Copy

```yaml
apiVersion: workflows.ext.grafana.app/v1alpha1
kind: Definition
metadata:
  name: broadcast-key-updates-teams
  annotations:
    grafana.app/folder: <FOLDER_UID>
spec:
  name: Broadcast key updates to Microsoft Teams
  enabled: false
  startWhen:
    matchingRules:
      - eventNameRegex: 'grafana_irm_app\.incident\.updated'
        filter: "inputs.data.eventKind == 'incident_added_key_update' && inputs.data.newSeverity.matches('(?i)^(critical|major)$') && !resources.incident.event.isDrill"
    schedules: []
  steps:
    - id: status-line
      type: transform
      name: Build the status line
      description: Shows the status change when the key update changed it, otherwise the current status. No changes needed.
      inputs:
        template: "${has(inputs.data.previousStatus) ? inputs.data.previousStatus + ' → ' + inputs.data.newStatus : inputs.data.newStatus}"
    - id: post-update
      type: msteams.message.post
      name: Post the update to Teams
      description: Posts the key update as an Adaptive Card. Pick the Teams team and stakeholder channel.
      inputs:
        teamID: ''
        channelID: ''
        messageText: 'Incident update: ${resources.incident.event.title}'
        adaptiveCard: |
          {
            "type": "AdaptiveCard",
            "version": "1.4",
            "body": [
              {
                "type": "TextBlock",
                "text": ${json_stringify('Incident update: ' + resources.incident.event.title)},
                "size": "Medium",
                "weight": "Bolder",
                "wrap": true
              },
              {
                "type": "FactSet",
                "facts": [
                  {
                    "title": "Status",
                    "value": ${json_stringify(steps['status-line'].outputs.result)}
                  },
                  {
                    "title": "Severity",
                    "value": ${json_stringify(inputs.data.newSeverity)}
                  }
                ]
              },
              {
                "type": "TextBlock",
                "text": ${json_stringify(inputs.data.content)},
                "wrap": true
              }
            ],
            "actions": [
              {
                "type": "Action.OpenUrl",
                "title": "Open incident",
                "url": "${resources.incident.event.overviewURL}"
              }
            ]
          }
```

## How it works

This section explains when the workflow runs and how its steps work together.

### When it runs

This blueprint starts on the `grafana_irm_app.incident.updated` event.

Its trigger filter starts a run only when this CEL expression is true:

text ![Copy code to clipboard](https://grafana.com/media/images/icons/icon-copy-small-2.svg) Copy

```text
inputs.data.eventKind == 'incident_added_key_update' && inputs.data.newSeverity.matches('(?i)^(critical|major)$') && !resources.incident.event.isDrill
```

### How the steps fit together

These notes cover how the steps connect and which Workflows behaviors the blueprint relies on.

- Triggers on `eventKind` `incident_added_key_update`.
- The event already contains the update content (Markdown), `newStatus` and `newSeverity`, and `previousStatus` or `previousSeverity` only when the update changed them, so the workflow reads them straight from `inputs.data`.
- `has()` checks whether `previousStatus` is present.
- The trigger filter limits broadcasts to Critical and Major incidents and skips drills.
- A transform step builds the status line once, and the Adaptive Card reuses it.
- Free text (the title, status names, severity, and update content) is inserted into the card JSON with `json_stringify()` so quotes and newlines stay valid JSON.
- The incident URL is system-generated, so it goes inside a quoted string directly.
- Customize the severity filter, the Teams team and channel, and the card layout.

## Next steps

- [Blueprints](https://grafana.com/docs/grafana-cloud/platform/workflows/reference/blueprints)
- [Start from a blueprint](https://grafana.com/docs/grafana-cloud/platform/workflows/build/use-blueprints)
- [Manage workflows as code](https://grafana.com/docs/grafana-cloud/platform/workflows/as-code)
- [Step and trigger types reference](https://grafana.com/docs/grafana-cloud/platform/workflows/reference/step-trigger-types)
