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
97 changes: 97 additions & 0 deletions infrastructure/modules/key-vault/alerts.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
resource "azurerm_monitor_scheduled_query_rules_alert_v2" "kv_secret_near_expiry" {
count = var.enable_alerting == true ? 1 : 0

name = "${azurerm_key_vault.keyvault.name}-secret-near-expiry"
resource_group_name = var.resource_group_name_monitoring != null ? var.resource_group_name_monitoring : var.resource_group_name
location = var.location

evaluation_frequency = var.secret_near_expiry_alert.evaluation_frequency
window_duration = var.secret_near_expiry_alert.window_duration
scopes = [azurerm_key_vault.keyvault.id]
severity = 2

criteria {
query = <<-QUERY
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.KEYVAULT"
| where OperationName contains "SecretNearExpiry"
| project
SecretName = column_ifexists("eventGridEventProperties_data_ObjectName_s","")
| summarize Events=count() by SecretName
QUERY

time_aggregation_method = "Total"
threshold = var.secret_near_expiry_alert.threshold
operator = "GreaterThanOrEqual"

resource_id_column = "SecretName"
metric_measure_column = "Events"

dimension {
name = "SecretName"
operator = "Include"
values = ["*"]
}
}

description = "The Key Vault secret is nearing expiration."

action {
action_groups = [var.action_group_id]
}

lifecycle {
ignore_changes = [
tags
]
}
}

resource "azurerm_monitor_scheduled_query_rules_alert_v2" "kv_secret_expired" {
count = var.enable_alerting == true ? 1 : 0

name = "${azurerm_key_vault.keyvault.name}-secret-expired"
resource_group_name = var.resource_group_name_monitoring != null ? var.resource_group_name_monitoring : var.resource_group_name
location = var.location

evaluation_frequency = var.secret_expired_alert.evaluation_frequency
window_duration = var.secret_expired_alert.window_duration
scopes = [azurerm_key_vault.keyvault.id]
severity = 2

criteria {
query = <<-QUERY
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.KEYVAULT"
| where OperationName contains "SecretExpired"
| project
SecretName = column_ifexists("eventGridEventProperties_data_ObjectName_s","")
| summarize Events=count() by SecretName
QUERY

time_aggregation_method = "Total"
threshold = var.secret_expired_alert.threshold
operator = "GreaterThanOrEqual"

resource_id_column = "SecretName"
metric_measure_column = "Events"

dimension {
name = "SecretName"
operator = "Include"
values = ["*"]
}
}

description = "The Key Vault secret has expired."

action {
action_groups = [var.action_group_id]
}

lifecycle {
ignore_changes = [
tags
]
}
}
53 changes: 53 additions & 0 deletions infrastructure/modules/key-vault/tfdocs.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,59 @@ Description: Resource tags to be applied throughout the deployment.
Type: `map(string)`

Default: `{}`

### <a name="input_resource_group_name_monitoring"></a> [resource\_group\_name\_monitoring](#input\_resource\_group\_name\_monitoring)

Description: The name of the resource group in which to create monitoring resources for the Key Vault. Changing this forces a new resource to be created.

Type: `string`

Default: `null`

### <a name="input_action_group_id"></a> [action\_group\_id](#input\_action\_group\_id)

Description: The ID of the Action Group to use for alerts.

Type: `string`

Default: `null`

### <a name="input_enable_alerting"></a> [enable\_alerting](#input\_enable\_alerting)

Description: Whether monitoring and alerting is enabled for the Key Vault.

Type: `bool`

Default: `false`

### <a name="input_secret_near_expiry_alert"></a> [secret\_near\_expiry\_alert](#input\_secret\_near\_expiry\_alert)

Description: Configuration for the Key Vault secret near expiry alert.

Type:

```hcl
object({
evaluation_frequency = string
window_duration = string
threshold = number
})
```

### <a name="input_secret_expired_alert"></a> [secret\_expired\_alert](#input\_secret\_expired\_alert)

Description: Configuration for the Key Vault secret expired alert.

Type:

```hcl
object({
evaluation_frequency = string
window_duration = string
threshold = number
})
```

## Modules

The following Modules are called:
Expand Down
70 changes: 70 additions & 0 deletions infrastructure/modules/key-vault/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ variable "disk_encryption" {
default = true
}

/* --------------------------------------------------------------------------------------------------
Monitoring and Diagnostics Variables
-------------------------------------------------------------------------------------------------- */

variable "log_analytics_workspace_id" {
type = string
description = "id of the log analytics workspace to send resource logging to via diagnostic settings"
Expand All @@ -35,6 +39,72 @@ variable "monitor_diagnostic_setting_keyvault_metrics" {
description = "Controls what metrics will be enabled for the keyvault"
}

variable "resource_group_name_monitoring" {
type = string
description = "The name of the resource group in which to create the Monitoring resources for the Key Vault. Changing this forces a new resource to be created."
default = null
}

variable "action_group_id" {
type = string
description = "The ID of the Action Group to use for alerts."
default = null
}

variable "enable_alerting" {
description = "Whether monitoring and alerting is enabled for the Key Vault."
type = bool
default = false
}

variable "secret_near_expiry_alert" {
type = object({
evaluation_frequency = string
window_duration = string
threshold = number
})

validation {
condition = contains(
["PT1M", "PT5M", "PT15M", "PT30M", "PT1H", "PT6H", "PT12H", "P1D"],
var.secret_near_expiry_alert.evaluation_frequency
)
error_message = "secret_near_expiry_alert.evaluation_frequency must be one of: PT1M, PT5M, PT15M, PT30M, PT1H, PT6H, PT12H, P1D"
}

validation {
condition = contains(
["PT1M", "PT5M", "PT15M", "PT30M", "PT1H", "PT6H", "PT12H", "P1D"],
var.secret_near_expiry_alert.window_duration
)
error_message = "secret_near_expiry_alert.window_duration must be one of: PT1M, PT5M, PT15M, PT30M, PT1H, PT6H, PT12H, P1D"
}
}

variable "secret_expired_alert" {
type = object({
evaluation_frequency = string
window_duration = string
threshold = number
})

validation {
condition = contains(
["PT1M", "PT5M", "PT15M", "PT30M", "PT1H", "PT6H", "PT12H", "P1D"],
var.secret_expired_alert.evaluation_frequency
)
error_message = "secret_expired_alert.evaluation_frequency must be one of: PT1M, PT5M, PT15M, PT30M, PT1H, PT6H, PT12H, P1D"
}

validation {
condition = contains(
["PT1M", "PT5M", "PT15M", "PT30M", "PT1H", "PT6H", "PT12H", "P1D"],
var.secret_expired_alert.window_duration
)
error_message = "secret_expired_alert.window_duration must be one of: PT1M, PT5M, PT15M, PT30M, PT1H, PT6H, PT12H, P1D"
}
}

variable "name" {
description = "The name of the Key Vault."
type = string
Expand Down
Loading