diff --git a/Makefile b/Makefile index 8f55041..8f87fc3 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ LCAF_ENV_FILE = .lcafenv # Source repository for repo manifests REPO_MANIFESTS_URL ?= https://github.com/launchbynttdata/launch-common-automation-framework.git # Branch of source repository for repo manifests. Other tags not currently supported. -REPO_BRANCH ?= refs/tags/1.0.0 +REPO_BRANCH ?= refs/tags/1.8.1 # Path to seed manifest in repository referenced in REPO_MANIFESTS_URL REPO_MANIFEST ?= manifests/terraform_modules/seed/manifest.xml diff --git a/README.md b/README.md index 180e162..e324a56 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ If `make check` target is successful, developer is good to commit the code to pr - runs `conftests`. `conftests` make sure `policy` checks are successful. - runs `terratest`. This is integration test suit. - runs `opa` tests - + ## Requirements | Name | Version | @@ -124,6 +124,8 @@ No providers. | [signalr](#module\_signalr) | terraform.registry.launch.nttdata.com/module_primitive/signalr/azurerm | ~> 1.0 | | [log\_analytics\_workspace](#module\_log\_analytics\_workspace) | terraform.registry.launch.nttdata.com/module_primitive/log_analytics_workspace/azurerm | ~> 1.0 | | [diagnostic\_setting](#module\_diagnostic\_setting) | terraform.registry.launch.nttdata.com/module_primitive/monitor_diagnostic_setting/azurerm | ~> 1.0 | +| [monitor\_action\_group](#module\_monitor\_action\_group) | terraform.registry.launch.nttdata.com/module_primitive/monitor_action_group/azurerm | ~> 1.0.0 | +| [monitor\_metric\_alert](#module\_monitor\_metric\_alert) | terraform.registry.launch.nttdata.com/module_primitive/monitor_metric_alert/azurerm | ~> 2.0 | ## Resources @@ -163,6 +165,10 @@ No resources. | [enabled\_log](#input\_enabled\_log) | n/a |
list(object({
category_group = optional(string, "allLogs")
category = optional(string, null)
})) | `null` | no |
| [metric](#input\_metric) | n/a | object({
category = optional(string)
enabled = optional(bool)
}) | `null` | no |
| [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `{}` | no |
+| [action\_group](#input\_action\_group) | An action group object. Set to null to skip creation.object({
name = string
short_name = string
arm_role_receivers = optional(list(object({
name = string
role_id = string
use_common_alert_schema = optional(bool)
})), [])
email_receivers = optional(list(object({
name = string
email_address = string
use_common_alert_schema = optional(bool)
})), [])
}) | `null` | no |
+| [action\_group\_ids](#input\_action\_group\_ids) | Explicit list of existing action group IDs (strings) which will be included in alerts. | `list(string)` | `[]` | no |
+| [metric\_alerts](#input\_metric\_alerts) | Map of metric alerts. Each key is the alert name and the value is an object describing the alert. | map(object({
description = string
action_groups = optional(set(string), [])
frequency = optional(string, "PT1M")
severity = optional(number, 3)
enabled = optional(bool, true)
webhook_properties = optional(map(string), {})
criteria = optional(list(object({
metric_namespace = string
metric_name = string
aggregation = string
operator = string
threshold = number
skip_metric_validation = optional(bool, false)
dimensions = optional(list(object({
name = string
operator = string
values = list(string)
})), [])
})), null)
dynamic_criteria = optional(object({
metric_namespace = string
metric_name = string
aggregation = string
operator = string
alert_sensitivity = string
ignore_data_before = optional(string)
skip_metric_validation = optional(bool, false)
dimensions = optional(list(object({
name = string
operator = string
values = list(string)
})), [])
}), null)
})) | `{}` | no |
+| [resource\_group\_name](#input\_resource\_group\_name) | Specifies the Name of the Resource Group within which the Private Endpoint should exist. | `string` | n/a | yes |
## Outputs
@@ -172,4 +178,4 @@ No resources.
| [signalr\_name](#output\_signalr\_name) | n/a |
| [location](#output\_location) | n/a |
| [resource\_group\_name](#output\_resource\_group\_name) | n/a |
-
+
diff --git a/examples/complete/README.md b/examples/complete/README.md
index aae104c..21861f0 100644
--- a/examples/complete/README.md
+++ b/examples/complete/README.md
@@ -1,6 +1,6 @@
# with_cake
-
+
## Requirements
| Name | Version |
@@ -17,6 +17,8 @@ No providers.
| Name | Source | Version |
|------|--------|---------|
| [signalr](#module\_signalr) | ../.. | n/a |
+| [monitor\_action\_group](#module\_monitor\_action\_group) | terraform.registry.launch.nttdata.com/module_primitive/monitor_action_group/azurerm | ~> 1.0.0 |
+| [monitor\_metric\_alert](#module\_monitor\_metric\_alert) | terraform.registry.launch.nttdata.com/module_primitive/monitor_metric_alert/azurerm | ~> 2.0 |
## Resources
@@ -34,6 +36,10 @@ No resources.
| [enabled\_log](#input\_enabled\_log) | n/a | list(object({
category_group = optional(string, "allLogs")
category = optional(string, null)
})) | [| no | | [metric](#input\_metric) | n/a |
{
"category_group": "allLogs"
}
]
object({
category = optional(string, "AllMetrics")
enabled = optional(bool, false)
}) | {
"category": "AllMetrics"
} | no |
| [tags](#input\_tags) | A mapping of tags to assign to the resource. | `map(string)` | `{}` | no |
+| [resource\_group\_name](#input\_resource\_group\_name) | Test resource group | `string` | `"test"` | no |
+| [action\_group](#input\_action\_group) | n/a | object({
name = string
short_name = string
arm_role_receivers = optional(list(object({
name = string
role_id = string
use_common_alert_schema = optional(bool)
})), [])
email_receivers = optional(list(object({
name = string
email_address = string
use_common_alert_schema = optional(bool)
})), [])
}) | {
"arm_role_receivers": [],
"email_receivers": [
{
"email_address": "test@example.com",
"name": "oncall",
"use_common_alert_schema": true
}
],
"name": "ag-test-alerts",
"short_name": "agtest"
} | no |
+| [action\_group\_ids](#input\_action\_group\_ids) | n/a | `list(string)` | `[]` | no |
+| [metric\_alerts](#input\_metric\_alerts) | n/a | map(object({
description = string
action_groups = optional(set(string), [])
frequency = optional(string, "PT5M")
severity = optional(number, 2)
enabled = optional(bool, true)
webhook_properties = optional(map(string), {})
criteria = optional(list(object({
metric_namespace = string
metric_name = string
aggregation = string
operator = string
threshold = number
skip_metric_validation = optional(bool, false)
dimensions = optional(list(object({
name = string
operator = string
values = list(string)
})), [])
})), null)
dynamic_criteria = optional(object({
metric_namespace = string
metric_name = string
aggregation = string
operator = string
alert_sensitivity = string
ignore_data_before = optional(string)
skip_metric_validation = optional(bool, false)
dimensions = optional(list(object({
name = string
operator = string
values = list(string)
})), [])
}), null)
})) | {
"signalr-connections-high": {
"action_groups": [],
"criteria": [
{
"aggregation": "Maximum",
"dimensions": [],
"metric_name": "ConnectionCount",
"metric_namespace": "Microsoft.SignalRService/SignalR",
"operator": "GreaterThan",
"skip_metric_validation": false,
"threshold": 1000
}
],
"description": "High number of SignalR connections",
"dynamic_criteria": null,
"enabled": true,
"frequency": "PT5M",
"severity": 2,
"webhook_properties": {}
}
} | no |
## Outputs
@@ -43,4 +49,4 @@ No resources.
| [signalr\_name](#output\_signalr\_name) | n/a |
| [location](#output\_location) | n/a |
| [resource\_group\_name](#output\_resource\_group\_name) | n/a |
-
+
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
index bd844bb..3455229 100644
--- a/examples/complete/main.tf
+++ b/examples/complete/main.tf
@@ -21,10 +21,50 @@ module "signalr" {
log_analytics_workspace_retention_in_days = var.log_analytics_workspace_retention_in_days
log_analytics_workspace_identity = var.log_analytics_workspace_identity
log_analytics_destination_type = var.log_analytics_destination_type
-
- enable_monitor_diagnostic_setting = true
- enabled_log = var.enabled_log
- metric = var.metric
+ resource_group_name = var.resource_group_name
+ enable_monitor_diagnostic_setting = true
+ enabled_log = var.enabled_log
+ metric = var.metric
tags = local.tags
}
+
+module "monitor_action_group" {
+ source = "terraform.registry.launch.nttdata.com/module_primitive/monitor_action_group/azurerm"
+ version = "~> 1.0"
+
+ count = var.action_group != null ? 1 : 0
+ action_group_name = var.action_group.name
+ resource_group_name = var.resource_group_name
+ short_name = var.action_group.short_name
+ arm_role_receivers = var.action_group.arm_role_receivers
+ email_receivers = var.action_group.email_receivers
+ tags = var.tags
+}
+
+# Metric Alert
+module "monitor_metric_alert" {
+ source = "terraform.registry.launch.nttdata.com/module_primitive/monitor_metric_alert/azurerm"
+ version = "~> 2.0"
+
+ for_each = var.metric_alerts
+ name = each.key
+ resource_group_name = var.resource_group_name
+
+ scopes = [module.signalr.signalr_id]
+
+ description = each.value.description
+ frequency = each.value.frequency
+ severity = each.value.severity
+ enabled = each.value.enabled
+
+ action_group_ids = concat(
+ var.action_group_ids,
+ try(tolist(each.value.action_groups), []),
+ var.action_group != null ? [module.monitor_action_group[0].action_group_id] : []
+ )
+
+ webhook_properties = lookup(each.value, "webhook_properties", null)
+ criteria = each.value.criteria
+ dynamic_criteria = each.value.dynamic_criteria
+}
diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf
index 9a7f578..f6aa7e6 100644
--- a/examples/complete/variables.tf
+++ b/examples/complete/variables.tf
@@ -68,3 +68,120 @@ variable "tags" {
type = map(string)
default = {}
}
+
+variable "resource_group_name" {
+ description = "Test resource group"
+ type = string
+ default = "test"
+}
+
+
+variable "action_group" {
+ type = object({
+ name = string
+ short_name = string
+ arm_role_receivers = optional(list(object({
+ name = string
+ role_id = string
+ use_common_alert_schema = optional(bool)
+ })), [])
+ email_receivers = optional(list(object({
+ name = string
+ email_address = string
+ use_common_alert_schema = optional(bool)
+ })), [])
+ })
+
+ default = {
+ name = "ag-test-alerts"
+ short_name = "agtest"
+
+ email_receivers = [
+ {
+ name = "oncall"
+ email_address = "test@example.com"
+ use_common_alert_schema = true
+ }
+ ]
+
+ arm_role_receivers = []
+ }
+}
+
+variable "action_group_ids" {
+ type = list(string)
+ default = []
+}
+
+variable "metric_alerts" {
+ type = map(object({
+ description = string
+ action_groups = optional(set(string), [])
+ frequency = optional(string, "PT5M")
+ severity = optional(number, 2)
+ enabled = optional(bool, true)
+ webhook_properties = optional(map(string), {})
+ criteria = optional(list(object({
+ metric_namespace = string
+ metric_name = string
+ aggregation = string
+ operator = string
+ threshold = number
+ skip_metric_validation = optional(bool, false)
+ dimensions = optional(list(object({
+ name = string
+ operator = string
+ values = list(string)
+ })), [])
+ })), null)
+ dynamic_criteria = optional(object({
+ metric_namespace = string
+ metric_name = string
+ aggregation = string
+ operator = string
+ alert_sensitivity = string
+ ignore_data_before = optional(string)
+ skip_metric_validation = optional(bool, false)
+ dimensions = optional(list(object({
+ name = string
+ operator = string
+ values = list(string)
+ })), [])
+ }), null)
+ }))
+
+ default = {
+ "signalr-connections-high" = {
+ description = "High number of SignalR connections"
+ action_groups = []
+
+ frequency = "PT5M"
+ severity = 2
+ enabled = true
+
+ criteria = [
+ {
+ metric_namespace = "Microsoft.SignalRService/SignalR"
+ metric_name = "ConnectionCount"
+ aggregation = "Maximum"
+ operator = "GreaterThan"
+ threshold = 1000
+ skip_metric_validation = false
+ dimensions = []
+ }
+ ]
+
+ dynamic_criteria = null
+ webhook_properties = {}
+ }
+ }
+
+ validation {
+ condition = alltrue(
+ [for alert in values(var.metric_alerts) :
+ !(alert.criteria == null && alert.dynamic_criteria == null)
+ ]
+ )
+ error_message = "Each metric alert must define at least one of 'criteria' or 'dynamic_criteria'."
+ }
+}
diff --git a/main.tf b/main.tf
index dc25225..a3e4523 100644
--- a/main.tf
+++ b/main.tf
@@ -92,3 +92,48 @@ module "diagnostic_setting" {
enabled_log = var.enabled_log
metric = var.metric
}
+
+# Optional: create an action group using your object variable "action_group"
+module "monitor_action_group" {
+ source = "terraform.registry.launch.nttdata.com/module_primitive/monitor_action_group/azurerm"
+ version = "~> 1.0"
+
+ count = var.action_group != null ? 1 : 0
+ action_group_name = var.action_group != null ? var.action_group.name : null
+ resource_group_name = coalesce(var.resource_group_name, module.resource_names["resource_group"].standard)
+ short_name = var.action_group != null ? var.action_group.short_name : null
+ arm_role_receivers = var.action_group != null ? lookup(var.action_group, "arm_role_receivers", null) : null
+ email_receivers = var.action_group != null ? lookup(var.action_group, "email_receivers", null) : null
+ tags = merge(local.tags, var.tags)
+
+ depends_on = [module.resource_group]
+}
+
+# Metric alerts: for_each over the map var.metric_alerts
+module "monitor_metric_alert" {
+ source = "terraform.registry.launch.nttdata.com/module_primitive/monitor_metric_alert/azurerm"
+ version = "~> 2.0"
+
+ for_each = var.metric_alerts
+ name = each.key
+ resource_group_name = coalesce(var.resource_group_name, module.resource_names["resource_group"].standard)
+
+ scopes = [module.signalr.signalr_id]
+
+ description = each.value.description
+ frequency = each.value.frequency
+ severity = each.value.severity
+ enabled = each.value.enabled
+
+ action_group_ids = concat(
+ coalesce(var.action_group_ids, []),
+ try(tolist(each.value.action_groups), []),
+ var.action_group != null ? [module.monitor_action_group[0].action_group_id] : []
+ )
+
+ webhook_properties = lookup(each.value, "webhook_properties", null)
+ criteria = lookup(each.value, "criteria", null)
+ dynamic_criteria = lookup(each.value, "dynamic_criteria", null)
+
+ depends_on = [module.signalr]
+}
diff --git a/variables.tf b/variables.tf
index 8aced1a..1151ec2 100644
--- a/variables.tf
+++ b/variables.tf
@@ -246,3 +246,90 @@ variable "tags" {
type = map(string)
default = {}
}
+
+variable "action_group" {
+ description = <