Skip to content

Commit f3be31d

Browse files
refs platform/board#4071: add SSL certificate expiration alert configuration
1 parent 5107317 commit f3be31d

File tree

4 files changed

+60
-4
lines changed

4 files changed

+60
-4
lines changed

CHANGELOG.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,20 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
88

99
## [Unreleased]
1010

11+
## [0.7.0] - 2025-12-12
1112

12-
## [0.6.0] - 2025-12-10
13+
[Compare with previous version](https://github.com/sparkfabrik/terraform-google-services-monitoring/compare/0.6.0...0.7.0)
1314

14-
[Compare with previous version](https://github.com/sparkfabrik/terraform-google-services-monitoring/compare/0.5.0...0.6.0)
15+
### Added
1516

16-
### Changed
17+
- refs platform/board#4071: add SSL certificate expiration alert configuration
1718

19+
## [0.6.0] - 2025-12-11
20+
21+
[Compare with previous version](https://github.com/sparkfabrik/terraform-google-services-monitoring/compare/0.5.0...0.6.0)
1822

1923
### Added
24+
2025
- refs platform/board#4052: add Typesense monitoring alerts and configuration for uptime checks and container checks
2126

2227
## [0.5.0] - 2025-12-01

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Supported services:
4040
| <a name="input_kyverno"></a> [kyverno](#input\_kyverno) | Configuration for Kyverno monitoring alerts. Allows customization of cluster name, project, notification channels, alert documentation, metric thresholds, auto-close timing, enablement, extra filters, and namespace. | <pre>object({<br/> enabled = optional(bool, true)<br/> cluster_name = string<br/> project_id = optional(string, null)<br/> notification_enabled = optional(bool, true)<br/> notification_channels = optional(list(string), [])<br/> # Rate limit for notifications, e.g. "300s" for 5 minutes, used only for log match alerts<br/> logmatch_notification_rate_limit = optional(string, "300s")<br/> alert_documentation = optional(string, null)<br/> auto_close_seconds = optional(number, 3600)<br/> filter_extra = optional(string, "")<br/> namespace = optional(string, "kyverno")<br/> })</pre> | n/a | yes |
4141
| <a name="input_notification_channels"></a> [notification\_channels](#input\_notification\_channels) | List of notification channel IDs to notify when an alert is triggered | `list(string)` | `[]` | no |
4242
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | The Google Cloud project ID where logging exclusions will be created | `string` | n/a | yes |
43+
| <a name="input_ssl_alert"></a> [ssl\_alert](#input\_ssl\_alert) | Configuration for SSL certificate expiration alerts. Allows customization of project, notification channels, alert thresholds, and user labels. | <pre>object({<br/> enabled = optional(bool, false)<br/> project_id = optional(string, null)<br/> notification_enabled = optional(bool, true)<br/> notification_channels = optional(list(string), [])<br/> threshold_days = optional(list(number), [15, 7])<br/> user_label = optional(map(string), {})<br/> })</pre> | `{}` | no |
4344
| <a name="input_typesense"></a> [typesense](#input\_typesense) | Configuration for Typesense monitoring alerts. Supports uptime checks for HTTP endpoints and container-level alerts (pod restarts) in GKE. Each app is identified by its name (map key). For container checks, the app name corresponds to the Kubernetes 'app' label; for apps with only uptime checks, this correspondence does not apply. | <pre>object({<br/> enabled = optional(bool, false)<br/> project_id = optional(string, null)<br/> notification_enabled = optional(bool, true)<br/> notification_channels = optional(list(string), [])<br/> cluster_name = optional(string, null) # GKE cluster name for container checks<br/><br/> # Apps configuration - map keyed by app_name<br/> apps = optional(map(object({<br/> # Uptime check configuration (optional)<br/> uptime_check = optional(object({<br/> enabled = optional(bool, true)<br/> host = string<br/> path = optional(string, "/readyz")<br/> }), null)<br/><br/> # Container check configuration for GKE (optional)<br/> container_check = optional(object({<br/> enabled = optional(bool, true)<br/> namespace = string<br/> pod_restart = optional(object({<br/> threshold = optional(number, 0)<br/> alignment_period = optional(number, 60)<br/> duration = optional(number, 0)<br/> auto_close_seconds = optional(number, 3600)<br/> }), {})<br/> }), null)<br/> })), {})<br/> })</pre> | `{}` | no |
4445

4546
## Outputs
@@ -59,6 +60,7 @@ Supported services:
5960
| [google_monitoring_alert_policy.cloud_sql_disk_utilization](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/monitoring_alert_policy) | resource |
6061
| [google_monitoring_alert_policy.cloud_sql_memory_utilization](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/monitoring_alert_policy) | resource |
6162
| [google_monitoring_alert_policy.kyverno_logmatch_alert](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/monitoring_alert_policy) | resource |
63+
| [google_monitoring_alert_policy.ssl_expiring_days](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/monitoring_alert_policy) | resource |
6264
| [google_monitoring_alert_policy.typesense_pod_restart](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/monitoring_alert_policy) | resource |
6365

6466
## Modules

ssl_alert.tf

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
locals {
2+
ssl_alert_project_id = var.ssl_alert.project_id != null ? var.ssl_alert.project_id : var.project_id
3+
4+
ssl_alert_notification_channels = var.ssl_alert.notification_enabled ? (length(var.ssl_alert.notification_channels) > 0 ? var.ssl_alert.notification_channels : var.notification_channels) : []
5+
}
6+
7+
resource "google_monitoring_alert_policy" "ssl_expiring_days" {
8+
for_each = var.ssl_alert.enabled ? toset([for days in var.ssl_alert.threshold_days : tostring(days)]) : []
9+
10+
display_name = "SSL certificate expiring soon (${each.value} days)"
11+
combiner = "OR"
12+
conditions {
13+
condition_threshold {
14+
filter = "metric.type=\"monitoring.googleapis.com/uptime_check/time_until_ssl_cert_expires\" AND resource.type=\"uptime_url\""
15+
comparison = "COMPARISON_LT"
16+
threshold_value = each.value
17+
duration = "600s"
18+
trigger {
19+
count = 1
20+
}
21+
aggregations {
22+
alignment_period = "1200s"
23+
per_series_aligner = "ALIGN_NEXT_OLDER"
24+
cross_series_reducer = "REDUCE_MEAN"
25+
group_by_fields = [
26+
"resource.label.*"
27+
]
28+
}
29+
}
30+
display_name = "SSL certificate expiring soon (${each.value} days)"
31+
}
32+
33+
user_labels = var.ssl_alert.user_labels
34+
35+
notification_channels = local.ssl_alert_notification_channels
36+
project = local.ssl_alert_project_id
37+
}

variables.tf

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ variable "cert_manager" {
102102
variable "typesense" {
103103
description = "Configuration for Typesense monitoring alerts. Supports uptime checks for HTTP endpoints and container-level alerts (pod restarts) in GKE. Each app is identified by its name (map key). For container checks, the app name corresponds to the Kubernetes 'app' label; for apps with only uptime checks, this correspondence does not apply."
104104
default = {}
105-
106105
type = object({
107106
enabled = optional(bool, false)
108107
project_id = optional(string, null)
@@ -152,3 +151,16 @@ variable "typesense" {
152151
error_message = "When any app has container_check configured, 'cluster_name' must be provided at the typesense level."
153152
}
154153
}
154+
155+
variable "ssl_alert" {
156+
description = "Configuration for SSL certificate expiration alerts. Allows customization of project, notification channels, alert thresholds, and user labels."
157+
default = {}
158+
type = object({
159+
enabled = optional(bool, false)
160+
project_id = optional(string, null)
161+
notification_enabled = optional(bool, true)
162+
notification_channels = optional(list(string), [])
163+
threshold_days = optional(list(number), [15, 7])
164+
user_label = optional(map(string), {})
165+
})
166+
}

0 commit comments

Comments
 (0)