Uptime/

SSL Certificate Monitoring

Expired SSL certificates cause downtime and erode trust. This guide shows how to monitor SSL certificates and security headers across multiple domains with Terraform.

Security Check Configuration

Security checks use the security check type with a security_config block. You can validate SSL certificates, TLS versions, and required security headers.

main.tfhcl
resource "uptime_service" "api" {
  name        = "API Server"
  url         = "https://api.example.com"
  is_public   = true
}

resource "uptime_check" "ssl_scan" {
  service_id       = uptime_service.api.id
  name             = "SSL & Security Scan"
  type             = "security"
  interval_seconds = 3600
  timeout_seconds  = 60

  security_config {
    check_ssl               = true
    check_headers           = true
    check_tls_version       = true
    ssl_expiry_warning_days = 30
    required_headers        = [
      "Strict-Transport-Security",
      "X-Content-Type-Options",
      "X-Frame-Options",
      "Content-Security-Policy",
      "Referrer-Policy",
    ]
  }
}

Recommended Security Headers

The OWASP recommended security headers are: Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, Content-Security-Policy, and Referrer-Policy. Checking for these helps ensure your services follow security best practices.

SSL Expiry Alerts

Use the ssl_expiry condition type to get notified before certificates expire. Combine with a consecutive_failures alert for immediate notification on any security scan failure.

main.tfhcl
# Alert 14 days before SSL expiry
resource "uptime_alert" "ssl_warning" {
  check_id       = uptime_check.ssl_scan.id
  name           = "SSL Expiring Soon"
  condition_type = "ssl_expiry"

  ssl_expiry_config {
    days_before = 14
  }

  channel {
    type   = "email"
    target = "security@example.com"
  }
}

# Alert immediately on any security scan failure
resource "uptime_alert" "security_failure" {
  check_id       = uptime_check.ssl_scan.id
  name           = "Security Scan Failed"
  condition_type = "consecutive_failures"

  consecutive_failures_config {
    count = 1
  }

  channel {
    type   = "slack"
    target = "https://hooks.slack.com/services/T00/B00/xxx"
  }

  channel {
    type   = "email"
    target = "security@example.com"
  }
}

Monitoring Multiple Domains

Use Terraform's for_each to monitor SSL certificates across all your domains with a single configuration.

ssl-monitoring.tfhcl
terraform {
  required_providers {
    uptime = {
      source = "registry.terraform.io/skunkworq/uptime"
    }
  }
}

provider "uptime" {}

variable "monitored_domains" {
  type = map(string)
  default = {
    "api"      = "https://api.example.com"
    "app"      = "https://app.example.com"
    "docs"     = "https://docs.example.com"
  }
}

resource "uptime_service" "domains" {
  for_each    = var.monitored_domains
  name        = "${each.key} (SSL)"
  url         = each.value
  description = "SSL monitoring for ${each.key}"
}

resource "uptime_check" "ssl" {
  for_each         = var.monitored_domains
  service_id       = uptime_service.domains[each.key].id
  name             = "SSL Scan - ${each.key}"
  type             = "security"
  interval_seconds = 3600
  timeout_seconds  = 60

  security_config {
    check_ssl               = true
    check_tls_version       = true
    ssl_expiry_warning_days = 30
  }
}

resource "uptime_alert" "ssl_expiry" {
  for_each       = var.monitored_domains
  check_id       = uptime_check.ssl[each.key].id
  name           = "SSL Expiring - ${each.key}"
  condition_type = "ssl_expiry"

  ssl_expiry_config {
    days_before = 14
  }

  channel {
    type   = "email"
    target = "security@example.com"
  }
}

Check Frequency

An interval of 3600 seconds (1 hour) is sufficient for SSL monitoring. Certificates don't change frequently, and this keeps check volume manageable.

Related