Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 217 additions & 0 deletions quickstart/101-health-model/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
# Create a random suffix for the resource names.
resource "random_pet" "name" {
length = 2
}

# Create a resource group for the health model.
resource "azurerm_resource_group" "example" {
name = "${var.resource_group_name_prefix}-${random_pet.name.id}"
location = var.resource_group_location
}

data "azurerm_client_config" "current" {}

# Create the resources represented in the health model.
resource "azurerm_storage_account" "example" {
name = "st${replace(random_pet.name.id, "-", "")}"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
account_tier = "Standard"
account_replication_type = "LRS"
}

resource "azurerm_key_vault" "example" {
name = "kv-${random_pet.name.id}"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
rbac_authorization_enabled = true
soft_delete_retention_days = 7
}

# Create a health model with a system-assigned managed identity.
resource "azapi_resource" "health_model" {
type = "Microsoft.CloudHealth/healthmodels@2026-05-01-preview"
name = "${var.health_model_name_prefix}-${random_pet.name.id}"
parent_id = azurerm_resource_group.example.id
location = azurerm_resource_group.example.location

identity {
type = "SystemAssigned"
}

body = {
properties = {}
}
}

# Allow the health model to read metrics from resources in the resource group.
resource "azurerm_role_assignment" "reader" {
scope = azurerm_resource_group.example.id
role_definition_name = "Reader"
principal_id = azapi_resource.health_model.identity[0].principal_id
principal_type = "ServicePrincipal"
}

resource "azapi_resource" "authentication_setting" {
type = "Microsoft.CloudHealth/healthmodels/authenticationsettings@2026-05-01-preview"
name = "monitoring-identity"
parent_id = azapi_resource.health_model.id

body = {
properties = {
displayName = "Monitoring identity"
authenticationKind = "ManagedIdentity"
managedIdentityName = "SystemAssigned"
}
}
}

resource "azapi_resource" "application_entity" {
type = "Microsoft.CloudHealth/healthmodels/entities@2026-05-01-preview"
name = "application"
parent_id = azapi_resource.health_model.id

body = {
properties = {
displayName = "Application"
canvasPosition = {
x = 175
y = 200
}
}
}
}

resource "azapi_resource" "storage_entity" {
type = "Microsoft.CloudHealth/healthmodels/entities@2026-05-01-preview"
name = "storage"
parent_id = azapi_resource.health_model.id

body = {
properties = {
displayName = "Storage account"
canvasPosition = {
x = 0
y = 400
}
signalGroups = {
azureResource = {
authenticationSetting = azapi_resource.authentication_setting.name
azureResourceId = azurerm_storage_account.example.id
azureResourceKind = "StorageV2"
signals = [
{
name = "availability"
displayName = "Storage availability (%)"
signalKind = "AzureResourceMetric"
refreshInterval = "PT5M"
dataUnit = "Percent"
metricNamespace = "Microsoft.Storage/storageAccounts"
metricName = "Availability"
timeGrain = "PT5M"
aggregationType = "Average"
evaluationRules = {
degradedRule = {
operator = "LessThan"
threshold = 100
}
unhealthyRule = {
operator = "LessThan"
threshold = 99
}
}
}
]
}
}
}
}
}

resource "azapi_resource" "key_vault_entity" {
type = "Microsoft.CloudHealth/healthmodels/entities@2026-05-01-preview"
name = "key-vault"
parent_id = azapi_resource.health_model.id

body = {
properties = {
displayName = "Key Vault"
impact = "Limited"
canvasPosition = {
x = 350
y = 400
}
signalGroups = {
azureResource = {
authenticationSetting = azapi_resource.authentication_setting.name
azureResourceId = azurerm_key_vault.example.id
azureResourceKind = ""
signals = [
{
name = "availability"
displayName = "Key Vault availability (%)"
signalKind = "AzureResourceMetric"
refreshInterval = "PT5M"
dataUnit = "Percent"
metricNamespace = "Microsoft.KeyVault/vaults"
metricName = "Availability"
timeGrain = "PT5M"
aggregationType = "Average"
evaluationRules = {
degradedRule = {
operator = "LessThan"
threshold = 100
}
unhealthyRule = {
operator = "LessThan"
threshold = 99
}
}
}
]
}
}
}
}
}

resource "azapi_resource" "root_to_application" {
type = "Microsoft.CloudHealth/healthmodels/relationships@2026-05-01-preview"
name = "root-to-application"
parent_id = azapi_resource.health_model.id

body = {
properties = {
parentEntityName = azapi_resource.health_model.name
childEntityName = azapi_resource.application_entity.name
}
}
}

resource "azapi_resource" "application_to_storage" {
type = "Microsoft.CloudHealth/healthmodels/relationships@2026-05-01-preview"
name = "application-to-storage"
parent_id = azapi_resource.health_model.id

body = {
properties = {
parentEntityName = azapi_resource.application_entity.name
childEntityName = azapi_resource.storage_entity.name
}
}
}

resource "azapi_resource" "application_to_key_vault" {
type = "Microsoft.CloudHealth/healthmodels/relationships@2026-05-01-preview"
name = "application-to-key-vault"
parent_id = azapi_resource.health_model.id

body = {
properties = {
parentEntityName = azapi_resource.application_entity.name
childEntityName = azapi_resource.key_vault_entity.name
}
}
}
29 changes: 29 additions & 0 deletions quickstart/101-health-model/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
output "resource_group_name" {
description = "Name of the resource group that contains the health model."
value = azurerm_resource_group.example.name
}

output "health_model_name" {
description = "Name of the health model."
value = azapi_resource.health_model.name
}

output "health_model_id" {
description = "Resource ID of the health model."
value = azapi_resource.health_model.id
}

output "health_model_location" {
description = "Azure region where the health model is deployed."
value = azapi_resource.health_model.location
}

output "storage_account_name" {
description = "Name of the storage account represented in the health model."
value = azurerm_storage_account.example.name
}

output "key_vault_name" {
description = "Name of the Key Vault represented in the health model."
value = azurerm_key_vault.example.name
}
24 changes: 24 additions & 0 deletions quickstart/101-health-model/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
terraform {
required_version = ">= 1.6.0"

required_providers {
azapi = {
source = "Azure/azapi"
version = "~> 2.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.0"
}
}
}

provider "azapi" {}

provider "azurerm" {
features {}
}
30 changes: 30 additions & 0 deletions quickstart/101-health-model/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Azure Monitor health model (AzAPI provider)

This template demonstrates how to deploy an Azure Monitor health model with a system-assigned managed identity into a resource group with a random name beginning with `rg-health-model`. The model represents a Storage account and Key Vault as resource entities beneath an abstract application entity. Availability signals report the health of both resources.

The health model is declared with the AzAPI provider's [`azapi_resource`](https://registry.terraform.io/providers/Azure/azapi/latest/docs/resources/resource) and the `Microsoft.CloudHealth/healthmodels@2026-05-01-preview` API. The AzureRM provider doesn't currently expose a native Health Models resource.

## Terraform resource types

- [random_pet](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet)
- [azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group)
- [azurerm_storage_account](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account)
- [azurerm_key_vault](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault)
- [azurerm_role_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment)
- [azapi_resource](https://registry.terraform.io/providers/Azure/azapi/latest/docs/resources/resource)

## Variables

| Name | Description | Default |
|-|-|-|
| `resource_group_location` | Location of the resource group and health model. | swedencentral |
| `resource_group_name_prefix` | Prefix of the resource group name that's combined with a random ID. | rg-health-model |
| `health_model_name_prefix` | Prefix of the health model name that's combined with a random ID. | health-model |

## Example

```console
terraform init -upgrade
terraform plan -out main.tfplan
terraform apply main.tfplan
```
17 changes: 17 additions & 0 deletions quickstart/101-health-model/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
variable "resource_group_location" {
type = string
default = "swedencentral"
description = "Location of the resource group and health model."
}

variable "resource_group_name_prefix" {
type = string
default = "rg-health-model"
description = "Prefix of the resource group name that's combined with a random ID so the name is unique in your Azure subscription."
}

variable "health_model_name_prefix" {
type = string
default = "health-model"
description = "Prefix of the health model name that's combined with a random ID so the name is unique in your Azure subscription."
}
Loading