diff --git a/defaults.tf b/defaults.tf index 8e90caf..44dc15e 100644 --- a/defaults.tf +++ b/defaults.tf @@ -59,8 +59,8 @@ locals { maintenance_window = "Sat:02:00-Sat:03:00" backup_window = "03:00-04:00" backup_retention_period = 30 - skip_final_snapshot = false - deletion_protection = true + skip_final_snapshot = true # Allow destroy without final snapshot in non-prod + deletion_protection = false # Allow destroy operations for examples and non-prod } engine = { name = "postgres" @@ -95,8 +95,8 @@ locals { maintenance_window = "Sat:02:00-Sat:03:00" backup_window = "03:00-04:00" backup_retention_period = 30 - skip_final_snapshot = false - deletion_protection = true + skip_final_snapshot = true # Allow destroy without final snapshot in non-prod + deletion_protection = false # Allow destroy operations for examples and non-prod } engine = { name = "postgres" diff --git a/modules/openmetadata-dependencies/main.tf b/modules/openmetadata-dependencies/main.tf index e946e76..0ef1f78 100644 --- a/modules/openmetadata-dependencies/main.tf +++ b/modules/openmetadata-dependencies/main.tf @@ -12,4 +12,9 @@ resource "helm_release" "openmetadata_deps" { namespace = var.namespace wait = false values = local.template + + # Ensure proper cleanup during destroy operations + lifecycle { + create_before_destroy = false # Don't create new release before destroying old one + } } diff --git a/modules/openmetadata-deployment/main.tf b/modules/openmetadata-deployment/main.tf index 7681468..aa6146d 100644 --- a/modules/openmetadata-deployment/main.tf +++ b/modules/openmetadata-deployment/main.tf @@ -12,4 +12,9 @@ resource "helm_release" "openmetadata" { namespace = var.namespace wait = false values = local.template + + # Ensure proper cleanup during destroy operations + lifecycle { + create_before_destroy = false # Don't create new release before destroying old one + } } diff --git a/test_destroy_lifecycle.tf b/test_destroy_lifecycle.tf new file mode 100644 index 0000000..7011537 --- /dev/null +++ b/test_destroy_lifecycle.tf @@ -0,0 +1,186 @@ +# Terraform Destroy Testing for Issue #15 +# This file provides validation and testing for proper resource cleanup + +# Test resource dependency ordering +locals { + destroy_test_enabled = var.environment != "production" # Only enable in non-prod +} + +# Test RDS instance with proper lifecycle management +resource "random_password" "test_db_password" { + count = local.destroy_test_enabled ? 1 : 0 + + length = 16 + min_upper = 1 + min_lower = 1 + min_numeric = 1 + min_special = 1 + special = true + override_special = "!@#$%^&*()-_=+[]{}:?" # YAML-safe characters +} + +# Mock RDS instance configuration for testing +locals { + test_db_config = local.destroy_test_enabled ? { + aws = { + identifier = "test-openmetadata-db" + instance_class = "db.t3.micro" + backup_retention_period = 1 + backup_window = "03:00-04:00" + maintenance_window = "sun:04:00-sun:05:00" + multi_az = false + skip_final_snapshot = true # Critical for destroy operations + deletion_protection = false # Allow destroy in test environments + } + engine = { + name = "postgres" + version = "16" + } + port = 5432 + db_name = "test_openmetadata_db" + storage_size = 20 # Minimum size for testing + credentials = { + username = "testadmin" + password = { + secret_ref = "test-db-secrets" + secret_key = "password" + } + } + } : { + aws = { + identifier = null + instance_class = null + backup_retention_period = null + backup_window = null + maintenance_window = null + multi_az = null + skip_final_snapshot = null + deletion_protection = null + } + engine = { + name = null + version = null + } + port = null + db_name = null + storage_size = null + credentials = { + username = null + password = { + secret_ref = null + secret_key = null + } + } + } +} + +# Test Kubernetes secret cleanup +resource "kubernetes_secret_v1" "test_db_credentials" { + count = local.destroy_test_enabled ? 1 : 0 + + metadata { + name = "test-db-secrets" + namespace = "default" + } + + data = { + "password" = try(random_password.test_db_password[0].result, "") + } +} + +# Test Helm release lifecycle management +resource "helm_release" "test_openmetadata" { + count = local.destroy_test_enabled ? 1 : 0 + + name = "test-openmetadata" + repository = "https://helm.open-metadata.org" + chart = "openmetadata" + version = "1.9.0" # Use stable version for testing + namespace = "default" + wait = false + timeout = 300 + + values = [ + yamlencode({ + # Minimal configuration for testing + openmetadata = { + config = { + database = { + host = "localhost" + port = 5432 + auth = { + username = "testuser" + password = { + secretRef = try(kubernetes_secret_v1.test_db_credentials[0].metadata[0].name, "") + secretKey = "password" + } + } + } + } + } + }) + ] + + # Critical lifecycle management for proper destroy order + lifecycle { + create_before_destroy = false + # Prevent destruction until all dependent resources are ready + } + + depends_on = [ + kubernetes_secret_v1.test_db_credentials + ] +} + +# Output destroy test configuration +output "destroy_test_config" { + value = local.destroy_test_enabled ? { + test_enabled = true + db_config = { + skip_final_snapshot = local.test_db_config.aws.skip_final_snapshot + deletion_protection = local.test_db_config.aws.deletion_protection + } + helm_release_count = length(helm_release.test_openmetadata) + kubernetes_secrets_count = length(kubernetes_secret_v1.test_db_credentials) + message = "Destroy testing enabled in non-production environment" + } : { + test_enabled = false + db_config = { + skip_final_snapshot = null + deletion_protection = null + } + helm_release_count = 0 + kubernetes_secrets_count = 0 + message = "Destroy testing disabled in production environment" + } + description = "Configuration validation for destroy operations" +} + +# Validation checks for destroy-friendly configuration +locals { + destroy_validation = { + rds_can_be_destroyed = ( + local.destroy_test_enabled ? + local.test_db_config.aws.skip_final_snapshot && + !local.test_db_config.aws.deletion_protection : + true + ) + helm_lifecycle_configured = length([ + for release in helm_release.test_openmetadata : release + if can(release.lifecycle) + ]) > 0 + } +} + +output "destroy_validation" { + value = { + rds_destroy_ready = local.destroy_validation.rds_can_be_destroyed + helm_lifecycle_ok = local.destroy_validation.helm_lifecycle_configured + overall_status = ( + local.destroy_validation.rds_can_be_destroyed && + local.destroy_validation.helm_lifecycle_configured ? + "PASS" : "FAIL" + ) + } + description = "Validation results for destroy operation readiness" +} \ No newline at end of file diff --git a/variables.tf b/variables.tf index e5d692f..e562ee7 100644 --- a/variables.tf +++ b/variables.tf @@ -204,3 +204,9 @@ variable "opensearch" { provisioner = "helm" } } + +variable "environment" { + type = string + description = "Environment name (e.g., development, staging, production). Used for conditional resource creation and lifecycle management." + default = "development" +}