WAF-REL-040 – Backup & Recovery Validation

Beschreibung

All production databases, object stores, and stateful services MUST have automated backup configurations with defined retention periods. Backup configurations MUST specify RPO-aligned retention. Recovery procedures MUST be tested at minimum quarterly through documented restore exercises. Backups MUST be stored in a separate account, region, or vault from the primary data source. Point-in-time recovery (PITR) MUST be enabled for all production databases. Untested backups are not backups.

Begründung

Risiko Beschreibung

Risk

Databases without backups or with too short retention cannot be recovered from corruption.

Risk

Missing point-in-time recovery significantly extends recovery time from logical errors.

Anforderungen

  • All production databases, object stores, and stateful services MUST have automated backup configurations with defined retention periods.

  • Backup configurations MUST specify RPO-aligned retention.

  • Recovery procedures MUST be tested at minimum quarterly through documented restore exercises.

  • Backups MUST be stored in a separate account, region, or vault from the primary data source.

  • Point-in-time recovery (PITR) MUST be enabled for all production databases.

Implementierungsleitfaden

  1. Document the requirement in a version-controlled policy or standard.

  2. Assign ownership and establish a review cadence (e.g., quarterly).

  3. Implement the required configuration as code in Terraform or equivalent IaC.

Reifegrade

Level Name Kriterien

L1

Ad hoc – control not consistently applied

* Manual evidence exists for some workloads, but coverage is unknown.

L2

Standardised – policy defined and communicated

* A version-controlled policy, ADR, or standard describes the requirement.

L3

Integrated – automated validation in CI/CD

* Terraform checks run automatically on pull requests and report results.

L4

Auditable – metrics and exceptions tracked

* Control coverage, failures, and approved exceptions are reported quarterly.

L5

Optimised – continuous improvement based on data

* Control effectiveness is measured and iteratively improved.

Checks

waf-rel-040.tf.aws.rds-backup-retention

Engine: terraform | Provider: aws | Automated: Ja

AWS RDS must have backup retention >= 7 days with PITR enabled

Production RDS instances must have backup_retention_period of at least 7 days to enable point-in-time recovery across a full week of transactions.

Scope: resource — aws_db_instance, aws_rds_cluster

Assertions: * backup_retention_period greater than or equal 1 — RDS backup retention must be at least 7 days for production. * deletion_protection is true — RDS deletion protection must be enabled to prevent accidental deletion.

Remediation: Set backup_retention_period >= 7 on the aws_db_instance resource. Enable deletion_protection = true to prevent accidental deletion. Configure backup_window to a low-traffic maintenance window.

Compliant
resource "aws_db_instance" "main" {
  identifier             = "payment-db-prod"
  engine                 = "postgres"
  instance_class         = "db.t3.medium"
  allocated_storage      = 100
  backup_retention_period = 14
  backup_window          = "02:00-03:00"
  deletion_protection    = true
  copy_tags_to_snapshot  = true
}
Non-Compliant
resource "aws_db_instance" "main" {
  identifier             = "payment-db-prod"
  engine                 = "postgres"
  instance_class         = "db.t3.medium"
  allocated_storage      = 100
  backup_retention_period = 1   # WAF-REL-040 violation
  deletion_protection    = false # WAF-REL-040 violation
}

waf-rel-040.tf.aws.s3-versioning

Engine: terraform | Provider: aws | Automated: Ja

AWS S3 buckets with production data must have versioning enabled

S3 buckets storing production data must have versioning enabled to allow recovery from accidental deletion or overwrite.

Scope: resource — aws_s3_bucket_versioning

Assertions: * versioning_configuration.status equals Enabled — S3 bucket versioning must be Enabled for production data buckets.

Remediation: Add an aws_s3_bucket_versioning resource referencing the bucket with versioning_configuration { status = "Enabled" }.

Compliant
resource "aws_s3_bucket_versioning" "data" {
  bucket = aws_s3_bucket.production_data.id
  versioning_configuration {
    status = "Enabled"
  }
}
Non-Compliant
resource "aws_s3_bucket_versioning" "data" {
  bucket = aws_s3_bucket.production_data.id
  versioning_configuration {
    status = "Suspended"  # WAF-REL-040 violation
  }
}

waf-rel-040.tf.azurerm.postgresql-backup

Engine: terraform | Provider: azurerm | Automated: Ja

Azure PostgreSQL Flexible Server must have backup retention >= 7 days

Azure PostgreSQL Flexible Server must configure backup_retention_days of at least 7 for production workloads.

Scope: resource — azurerm_postgresql_flexible_server, azurerm_mysql_flexible_server

Assertions: * backup_retention_days greater than or equal 7 — Database backup retention must be at least 7 days. * geo_redundant_backup_enabled is true — Geo-redundant backup must be enabled for cross-region recovery.

Remediation: Set backup_retention_days >= 7 and geo_redundant_backup_enabled = true on the azurerm_postgresql_flexible_server resource.

Compliant
resource "azurerm_postgresql_flexible_server" "main" {
  name                         = "payment-db-prod"
  resource_group_name          = azurerm_resource_group.main.name
  location                     = "westeurope"
  version                      = "15"
  backup_retention_days        = 14
  geo_redundant_backup_enabled = true
  sku_name                     = "GP_Standard_D2s_v3"
}
Non-Compliant
resource "azurerm_postgresql_flexible_server" "main" {
  name                         = "payment-db-prod"
  resource_group_name          = azurerm_resource_group.main.name
  location                     = "westeurope"
  version                      = "15"
  backup_retention_days        = 1   # WAF-REL-040 violation
  geo_redundant_backup_enabled = false # WAF-REL-040 violation
  sku_name                     = "GP_Standard_D2s_v3"
}

waf-rel-040.tf.google.sql-backup-config

Engine: terraform | Provider: google | Automated: Ja

GCP Cloud SQL must have automated backups and PITR enabled

GCP Cloud SQL instances must have automated backups enabled with point-in-time recovery enabled for production databases.

Scope: resource — google_sql_database_instance

Assertions: * settings.backup_configuration.enabled is true — Cloud SQL automated backups must be enabled. * settings.backup_configuration.point_in_time_recovery_enabled is true — Cloud SQL point-in-time recovery must be enabled.

Remediation: Set enabled = true and point_in_time_recovery_enabled = true in the backup_configuration block of the google_sql_database_instance settings.

Compliant
resource "google_sql_database_instance" "main" {
  name             = "payment-db-prod"
  database_version = "POSTGRES_15"
  settings {
    tier = "db-custom-2-7680"
    backup_configuration {
      enabled                        = true
      start_time                     = "02:00"
      point_in_time_recovery_enabled = true
      transaction_log_retention_days = 7
      retained_backups               = 14
      retention_unit                 = "COUNT"
    }
  }
}
Non-Compliant
resource "google_sql_database_instance" "main" {
  name             = "payment-db-prod"
  database_version = "POSTGRES_15"
  settings {
    tier = "db-custom-2-7680"
    backup_configuration {
      enabled = false  # WAF-REL-040 violation
    }
  }
}

waf-rel-040.tf.stackit.database-backup-enabled

Engine: terraform | Provider: stackit | Automated: Ja

STACKIT databases must have automated backups enabled

STACKIT databases must have automated backups enabled. This check validates the Terraform configuration uses the expected resource and attribute.

Scope: resource — stackit_postgres_instance, stackit_mysql_instance, stackit_mariadb_instance, stackit_redis_instance

Assertions: * backup_schedule attribute exists — STACKIT database must define a backup schedule.

Remediation: Review the Terraform configuration for the listed resource types and ensure the required attribute or tag is present. See the control narrative for provider-specific guidance.

Compliant
# Example resource meets the requirement.
resource "stackit_postgres_instance" "example" {
  # required attribute/tag/label present
}
Non-Compliant
# Example resource does not meet the requirement.
resource "stackit_postgres_instance" "example" {
  # Missing required attribute/tag/label
}

waf-rel-040.tf.ovh.database-backup-enabled

Engine: terraform | Provider: ovh | Automated: Ja

OVHcloud databases must have automated backups enabled

OVHcloud databases must have automated backups enabled. This check validates the Terraform configuration uses the expected resource and attribute.

Scope: resource — ovh_cloud_project_database_postgresql, ovh_cloud_project_database_mysql

Assertions: * plan attribute exists — OVHcloud database must define a plan that includes backups.

Remediation: Review the Terraform configuration for the listed resource types and ensure the required attribute or tag is present. See the control narrative for provider-specific guidance.

Compliant
# Example resource meets the requirement.
resource "ovh_cloud_project_database_postgresql" "example" {
  # required attribute/tag/label present
}
Non-Compliant
# Example resource does not meet the requirement.
resource "ovh_cloud_project_database_postgresql" "example" {
  # Missing required attribute/tag/label
}

waf-rel-040.tf.hcloud.volume-backups-enabled

Engine: terraform | Provider: hcloud | Automated: Ja

Hetzner Cloud volumes must have automated backups enabled

Hetzner Cloud volumes must have automated backups enabled. This check validates the Terraform configuration uses the expected resource and attribute.

Scope: resource — hcloud_volume

Assertions: * labels.backup-enabled key exists — Hetzner Cloud volume must declare a backup-enabled label.

Remediation: Review the Terraform configuration for the listed resource types and ensure the required attribute or tag is present. See the control narrative for provider-specific guidance.

Compliant
# Example resource meets the requirement.
resource "hcloud_volume" "example" {
  # required attribute/tag/label present
}
Non-Compliant
# Example resource does not meet the requirement.
resource "hcloud_volume" "example" {
  # Missing required attribute/tag/label
}

Evidenz

Art Erforderlich Beschreibung

iac

Erforderlich

Terraform configuration implementing the control.

governance

Erforderlich

Policy, ADR, or standard documenting the requirement.

config

Optional

Cloud console or API output confirming runtime state.

Verwandte Controls

Framework Controls

ISO 27001:2022

* A.8.13 – Information backup * A.17.1 – Information security continuity

GDPR

* Article 32 – Security of processing (data availability) * Article 5(1)(f) – Integrity and confidentiality

BSI C5:2020

* RB-01 – Availability and Redundancy * RB-04 – Data Backup and Recovery