Skip to content

libre-devops/terraform-msgraph-alerts-and-incidents-utils

Repository files navigation

Terraform MSGraph Alerts and Incidents Utils

Manage Microsoft Defender (unified security, security.microsoft.com) alerts and incidents through the Microsoft Graph security API, using the Microsoft/msgraph provider. Triage existing incidents and alerts, add incident comments, manage custom detection rules, and (experimentally) attempt incident and alert creation, with a v1.0 or beta toggle per operation.

Status: core, untested. This module has not been run against a live tenant yet (it needs a Defender / E5 licence and the security Graph permissions). It is published as the core surface to be validated and released once a licensed tenant is available. CI self-test and release are held until then.

CI Release Terraform Registry License


Why Graph and not the Azure Sentinel API

Microsoft Sentinel now surfaces its incidents and alerts in the Microsoft Defender portal (security.microsoft.com); the workspace is still deployed in Azure, but the incident experience moved. The Graph /security/incidents and /security/alerts_v2 endpoints are that unified Defender surface, whereas the older Microsoft.SecurityInsights (Azure) API is the Azure-portal one. This module targets Graph so the changes land where analysts now work.

What Graph actually supports (important)

  • Update / triage incidents and alerts: documented and stable on v1.0 (PATCH).
  • Comments on incidents: documented (POST /security/incidents/{id}/comments).
  • Custom detection rules (security/rules/detectionRules, beta): the documented way to have custom alerts and incidents generated into the Defender portal. Managed here via security_resources.
  • Creating a manual alert (createManualAlert, POST /security/alerts_v2, beta): documented. This is a real, supported create and the way to raise a custom alert that rolls up into a Defender incident. Managed here via manual_alerts (title, description, severity and category are required).
  • Creating incidents directly: experimental and unverified. Microsoft documents incidents as system-generated and publishes no create operation, but the beta metadata exposes a POST on the collection. The incidents input attempts that POST so it can be tested against a licensed tenant; do not rely on it until you have.

Inputs at a glance

Input Operation Graph resource used
incident_updates PATCH an existing incident msgraph_update_resource (destroy is a no-op)
incident_comments POST a comment msgraph_resource_action
alert_updates PATCH an existing alert msgraph_update_resource
manual_alerts create a manual alert (createManualAlert, documented) msgraph_resource
security_resources full CRUD on any security resource (detection rules, ...) msgraph_resource
incidents experimental incident create (beta, unverified) msgraph_resource

Minimum permissions

All as Microsoft Graph application permissions, admin-consented, on a Defender / E5 tenant:

Feature Minimum permission
Read/update incidents and comments SecurityIncident.ReadWrite.All
Read/update alerts (alerts_v2) SecurityAlert.ReadWrite.All
Custom detection rules CustomDetection.ReadWrite.All

Examples

  • examples/minimal - triage one existing incident.
  • examples/complete - triage an incident and alert, add a comment, create a custom detection rule, and (behind a flag) attempt the experimental incident create.

Requirements

Name Version
terraform >= 1.9.0, < 2.0.0
msgraph >= 0.1.0, < 1.0.0

Providers

Name Version
msgraph >= 0.1.0, < 1.0.0

Modules

No modules.

Resources

Name Type
msgraph_resource.incidents resource
msgraph_resource.manual_alerts resource
msgraph_resource.security_resources resource
msgraph_resource_action.incident_comments resource
msgraph_update_resource.alert_updates resource
msgraph_update_resource.incident_updates resource

Inputs

Name Description Type Default Required
alert_updates Existing alerts (alerts_v2) to update (triage), keyed by a stable logical name. Patches the
alert identified by alert_id. Typed fields cover the common updatable properties; use body for
anything else (merged over the typed fields).
map(object({
alert_id = string
api_version = optional(string)
status = optional(string)
classification = optional(string)
determination = optional(string)
assigned_to = optional(string)
body = optional(any)
response_export_values = optional(map(string))
}))
{} no
default_api_version Default Microsoft Graph API version for operations that do not set their own. One of "v1.0" or
"beta". Update and comment operations are documented on v1.0 (stable) and default to it. The
create operations (incidents, alerts) are only exposed on beta, so they default to beta
regardless of this value unless you pin api_version on the entry.
string "v1.0" no
incident_comments Comments to add to existing incidents, keyed by a stable logical name. Each posts one comment to the incident identified by incident_id. Adding a comment is a one-time action (not removed on destroy).
map(object({
incident_id = string
comment = string
api_version = optional(string)
}))
{} no
incident_updates Existing security incidents to update (triage), keyed by a stable logical name. Patches the
incident identified by incident_id. The typed fields cover the common updatable properties; use
body to set anything else (it is merged over the typed fields).
map(object({
incident_id = string
api_version = optional(string)
status = optional(string)
classification = optional(string)
determination = optional(string)
assigned_to = optional(string)
custom_tags = optional(list(string))
body = optional(any)
response_export_values = optional(map(string))
}))
{} no
incidents Security incidents to create and manage, keyed by a stable logical name. EXPERIMENTAL: creating
incidents through Graph is a beta, undocumented capability; verify it against your tenant. body
is the raw incident object (for example displayName, severity, status, classification,
determination, customTags). api_version defaults to beta because create is beta only.
map(object({
body = any
api_version = optional(string)
update_method = optional(string)
response_export_values = optional(map(string))
}))
{} no
manual_alerts Manual alerts to create via the createManualAlert operation (POST /security/alerts_v2), keyed by
a stable logical name. The module always sends the required @odata.type
(#microsoft.graph.security.manualAlert). title, description, severity, category and
entity_definitions (1 to 100) are required by the API; the rest are optional. Anything else can
be set through body (merged over the typed fields). Creating a manual alert makes Defender open
(or, with link_to_incident, link to) an incident. api_version defaults to beta.
map(object({
title = optional(string)
description = optional(string)
severity = optional(string)
category = optional(string)

# 1 to 100 impacted/related entities. Required by the API (supply via body if you prefer).
entity_definitions = optional(list(object({
entity_type = string # user, ip, device, file, ...
entity_identifier = string # userPrincipalName, address, deviceName, sha256, ...
identifier_value = string
role = optional(string, "impacted") # impacted
related
})), [])

recommended_actions = optional(string)
mitre_techniques = optional(list(string))
sentinel_workspace = optional(string) # route the alert to a Sentinel workspace
link_to_incident = optional(number) # link to an existing incident id instead of a new one
is_excluded_from_correlation = optional(bool)

body = optional(any)
api_version = optional(string)
update_method = optional(string)
response_export_values = optional(map(string))
}))
{}
security_resources Arbitrary Graph security resources to manage with full CRUD, keyed by a stable logical name.
url is the collection URL (for example "security/rules/detectionRules"), body is the resource
object. Use this for endpoints without a first-class input above, notably custom detection
rules, which generate alerts and incidents that surface in the Defender portal.
map(object({
url = string
body = any
api_version = optional(string)
update_method = optional(string)
response_export_values = optional(map(string))
}))
{} no

Outputs

Name Description
alert_update_ids Map of alert-update key to the target alert resource id.
alert_update_outputs Map of alert-update key to its exported response values.
incident_comment_outputs Map of incident-comment key to the action response.
incident_ids Map of incident key to the created incident resource id (only for incidents created via the experimental create path).
incident_update_ids Map of incident-update key to the target incident resource id.
incident_update_outputs Map of incident-update key to its exported response values.
incidents Map of incident key to its resource url and exported response values (create path).
manual_alert_ids Map of manual-alert key to the created alert resource id.
manual_alerts Map of manual-alert key to its resource url and exported response values.
security_resources Map of security-resource key to its resource url and exported response values.

About

🛡️ Terraform module (Microsoft Graph) to triage and manage Microsoft Defender unified security incidents and alerts, comments, and custom detection rules

Topics

Resources

License

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors