From 14b0df9c687f514c9299e96ca8d461cec2040ac9 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 28 Sep 2025 11:25:03 +0000 Subject: [PATCH 1/2] feat: add support for aws_backup_global_settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add enable_global_settings and global_settings variables with comprehensive validation - Implement conditional aws_backup_global_settings resource in main.tf - Add outputs for global settings management and monitoring - Create backup_global_settings example with full documentation - Enable centralized cross-account backup governance capabilities - Support enterprise compliance and security requirements Closes #235 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Luis M. Gallardo D. --- examples/backup_global_settings/README.md | 123 +++++++++++++++++++ examples/backup_global_settings/main.tf | 72 +++++++++++ examples/backup_global_settings/outputs.tf | 31 +++++ examples/backup_global_settings/variables.tf | 36 ++++++ examples/backup_global_settings/versions.tf | 10 ++ main.tf | 14 +++ outputs.tf | 52 ++++++++ variables.tf | 36 ++++++ 8 files changed, 374 insertions(+) create mode 100644 examples/backup_global_settings/README.md create mode 100644 examples/backup_global_settings/main.tf create mode 100644 examples/backup_global_settings/outputs.tf create mode 100644 examples/backup_global_settings/variables.tf create mode 100644 examples/backup_global_settings/versions.tf diff --git a/examples/backup_global_settings/README.md b/examples/backup_global_settings/README.md new file mode 100644 index 0000000..414116a --- /dev/null +++ b/examples/backup_global_settings/README.md @@ -0,0 +1,123 @@ +# AWS Backup Global Settings Example + +This example demonstrates how to configure AWS Backup global settings for centralized cross-account backup governance. + +## Features Demonstrated + +- **Global Settings Management**: Enable and configure AWS Backup global settings +- **Cross-Account Backup**: Enable centralized backup governance across multiple AWS accounts +- **Enterprise Governance**: Account-level settings for backup operations +- **Backup Configuration**: Basic vault, plan, and selection setup with global settings + +## Architecture + +``` +AWS Account (Management/Central) +├── Global Settings (Account-level) +│ └── isCrossAccountBackupEnabled: true +├── Backup Vault +├── Backup Plan +└── Resource Selections +``` + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Note that this example will create resources which may cost money. Run `terraform destroy` when you don't need these resources. + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 5.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 5.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [aws\_backup\_global\_settings](#module\_aws\_backup\_global\_settings) | ../.. | n/a | + +## Resources + +Created by the module: +- `aws_backup_global_settings` - Account-level backup settings +- `aws_backup_vault` - Backup vault for storing recovery points +- `aws_backup_plan` - Backup plan with scheduling and lifecycle policies +- `aws_backup_selection` - Resource selection for automated backups + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [backup\_retention\_days](#input\_backup\_retention\_days) | Number of days to retain backups | `number` | `30` | no | +| [backup\_schedule](#input\_backup\_schedule) | Cron expression for backup schedule | `string` | `"cron(0 2 * * ? *)"` | no | +| [enable\_cross\_account\_backup](#input\_enable\_cross\_account\_backup) | Enable cross-account backup functionality | `bool` | `true` | no | +| [tags](#input\_tags) | A mapping of tags to assign to resources | `map(string)` | `{"BackupGovernance": "centralized", "Environment": "production", "Owner": "backup-team", "Terraform": true}` | no | +| [vault\_name](#input\_vault\_name) | Name of the backup vault to create | `string` | `"centralized-backup-vault"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [cross\_account\_backup\_enabled](#output\_cross\_account\_backup\_enabled) | Whether cross-account backup is enabled | +| [global\_settings](#output\_global\_settings) | Configured global settings | +| [global\_settings\_id](#output\_global\_settings\_id) | AWS Account ID where global settings are applied | +| [global\_settings\_summary](#output\_global\_settings\_summary) | Summary of global settings configuration | +| [plan\_arn](#output\_plan\_arn) | ARN of the backup plan | +| [vault\_arn](#output\_vault\_arn) | ARN of the backup vault | + +## Global Settings Configuration + +### Cross-Account Backup Enablement + +When `isCrossAccountBackupEnabled` is set to `"true"`: + +1. **Centralized Governance**: Enables centralized backup management across AWS accounts +2. **Organization Policies**: Allows AWS Organizations backup policies to be applied +3. **Cross-Account IAM**: Enables backup operations across account boundaries +4. **Compliance**: Supports enterprise compliance frameworks requiring centralized backup + +### Enterprise Use Cases + +- **Multi-Account Organizations**: Centralized backup governance for AWS Organizations +- **Compliance Requirements**: Meeting regulatory requirements for backup management +- **Security**: Controlled cross-account backup operations +- **Cost Optimization**: Centralized backup strategies and policies + +## Next Steps + +After deploying this example: + +1. **Configure AWS Organizations Backup Policies** for centralized governance +2. **Set up cross-account IAM roles** for backup operations +3. **Implement backup compliance frameworks** across accounts +4. **Monitor backup activities** through AWS CloudTrail and CloudWatch + +## Important Notes + +- Global settings are **account-level** configurations (one per AWS account) +- Cross-account backup requires proper **IAM permissions** across accounts +- This feature is particularly valuable for **enterprise environments** +- Consider **AWS Organizations integration** for complete centralized governance + +## Compliance and Security + +This configuration supports: +- SOC 2 compliance for backup governance +- GDPR requirements for data retention +- HIPAA backup and recovery standards +- Financial services backup regulations \ No newline at end of file diff --git a/examples/backup_global_settings/main.tf b/examples/backup_global_settings/main.tf new file mode 100644 index 0000000..fe5c9a2 --- /dev/null +++ b/examples/backup_global_settings/main.tf @@ -0,0 +1,72 @@ +# AWS Backup Global Settings Example +# +# This example demonstrates how to configure AWS Backup global settings +# for centralized cross-account backup governance. + +# AWS Backup with Global Settings +module "aws_backup_global_settings" { + source = "../.." + + # Enable global settings management + enable_global_settings = true + + # Configure global settings for cross-account backup governance + global_settings = { + "isCrossAccountBackupEnabled" = "true" + } + + # Basic vault configuration + vault_name = "centralized-backup-vault" + + # Basic plan for demonstration + plan_name = "global-settings-plan" + + # Simple rule + rules = [ + { + name = "daily-backup" + schedule = "cron(0 2 * * ? *)" # Daily at 2 AM + start_window = 120 + completion_window = 360 + lifecycle = { + delete_after = 30 + } + copy_actions = [] + recovery_point_tags = { + BackupType = "Automated" + Governance = "Centralized" + Environment = "production" + } + } + ] + + # Resource selection + selections = [ + { + name = "production-resources" + resources = [ + "arn:aws:ec2:*:*:instance/*", + "arn:aws:rds:*:*:db:*" + ] + selection_tags = [ + { + type = "STRINGEQUALS" + key = "Environment" + value = "production" + }, + { + type = "STRINGEQUALS" + key = "BackupRequired" + value = "true" + } + ] + } + ] + + tags = { + Owner = "backup-team" + Environment = "production" + BackupGovernance = "centralized" + Terraform = true + } +} \ No newline at end of file diff --git a/examples/backup_global_settings/outputs.tf b/examples/backup_global_settings/outputs.tf new file mode 100644 index 0000000..f75fcd7 --- /dev/null +++ b/examples/backup_global_settings/outputs.tf @@ -0,0 +1,31 @@ +# Global Settings Outputs +output "global_settings_id" { + description = "AWS Account ID where global settings are applied" + value = module.aws_backup_global_settings.global_settings_id +} + +output "global_settings" { + description = "Configured global settings" + value = module.aws_backup_global_settings.global_settings +} + +output "cross_account_backup_enabled" { + description = "Whether cross-account backup is enabled" + value = module.aws_backup_global_settings.cross_account_backup_enabled +} + +output "global_settings_summary" { + description = "Summary of global settings configuration" + value = module.aws_backup_global_settings.global_settings_summary +} + +# Additional backup outputs for reference +output "vault_arn" { + description = "ARN of the backup vault" + value = module.aws_backup_global_settings.vault_arn +} + +output "plan_arn" { + description = "ARN of the backup plan" + value = module.aws_backup_global_settings.plan_arn +} \ No newline at end of file diff --git a/examples/backup_global_settings/variables.tf b/examples/backup_global_settings/variables.tf new file mode 100644 index 0000000..6ca0975 --- /dev/null +++ b/examples/backup_global_settings/variables.tf @@ -0,0 +1,36 @@ +# Optional variables for customizing the example + +variable "vault_name" { + description = "Name of the backup vault to create" + type = string + default = "centralized-backup-vault" +} + +variable "enable_cross_account_backup" { + description = "Enable cross-account backup functionality" + type = bool + default = true +} + +variable "backup_schedule" { + description = "Cron expression for backup schedule" + type = string + default = "cron(0 2 * * ? *)" # Daily at 2 AM +} + +variable "backup_retention_days" { + description = "Number of days to retain backups" + type = number + default = 30 +} + +variable "tags" { + description = "A mapping of tags to assign to resources" + type = map(string) + default = { + Owner = "backup-team" + Environment = "production" + BackupGovernance = "centralized" + Terraform = true + } +} \ No newline at end of file diff --git a/examples/backup_global_settings/versions.tf b/examples/backup_global_settings/versions.tf new file mode 100644 index 0000000..1d70a22 --- /dev/null +++ b/examples/backup_global_settings/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + } +} \ No newline at end of file diff --git a/main.tf b/main.tf index fb5cc7e..8ca1643 100644 --- a/main.tf +++ b/main.tf @@ -206,6 +206,20 @@ resource "aws_backup_plan" "ab_plan" { } } +# AWS Backup Global Settings +resource "aws_backup_global_settings" "ab_global_settings" { + count = var.enabled && var.enable_global_settings ? 1 : 0 + + global_settings = var.global_settings + + lifecycle { + precondition { + condition = var.enable_global_settings ? length(var.global_settings) > 0 : true + error_message = "When enable_global_settings is true, global_settings map cannot be empty. At minimum, specify isCrossAccountBackupEnabled." + } + } +} + # Multiple AWS Backup plans with optimized timeouts resource "aws_backup_plan" "ab_plans" { for_each = var.enabled ? local.plans_map : {} diff --git a/outputs.tf b/outputs.tf index 89ed0a9..9dcf22d 100644 --- a/outputs.tf +++ b/outputs.tf @@ -185,3 +185,55 @@ output "restore_testing_summary" { } } : null } + +# +# Global Settings +# +output "global_settings_id" { + description = "AWS Account ID where global settings are applied" + value = try(aws_backup_global_settings.ab_global_settings[0].id, null) +} + +output "global_settings" { + description = "AWS Backup global settings configuration" + value = try(aws_backup_global_settings.ab_global_settings[0].global_settings, null) +} + +output "cross_account_backup_enabled" { + description = "Whether cross-account backup is enabled for centralized governance" + value = try(aws_backup_global_settings.ab_global_settings[0].global_settings["isCrossAccountBackupEnabled"], null) == "true" +} + +# +# Global Settings Summary +# +output "global_settings_summary" { + description = "Summary of global settings configuration and governance capabilities" + value = var.enable_global_settings ? { + enabled = true + cross_account_backup_enabled = try(aws_backup_global_settings.ab_global_settings[0].global_settings["isCrossAccountBackupEnabled"], "false") == "true" + account_id = try(aws_backup_global_settings.ab_global_settings[0].id, null) + configured_settings = var.global_settings + + # Governance and compliance information + governance_impact = { + "cross_account_backup" = try(aws_backup_global_settings.ab_global_settings[0].global_settings["isCrossAccountBackupEnabled"], "false") == "true" ? "Enabled - centralized backup governance active" : "Disabled - account-level backup management" + "enterprise_ready" = try(aws_backup_global_settings.ab_global_settings[0].global_settings["isCrossAccountBackupEnabled"], "false") == "true" + } + + # Next steps and recommendations + next_steps = { + "1" = "Configure AWS Organizations backup policies for centralized governance" + "2" = "Set up cross-account IAM roles for backup operations" + "3" = "Implement backup compliance frameworks across accounts" + "4" = "Monitor backup activities through AWS CloudTrail and CloudWatch" + } + + # CLI commands for management + management_commands = { + describe_settings = "aws backup describe-global-settings" + list_backup_policies = "aws organizations list-policies --filter BACKUP_POLICY" + check_compliance = "aws backup list-backup-jobs --by-account-id ${try(aws_backup_global_settings.ab_global_settings[0].id, "ACCOUNT_ID")}" + } + } : null +} diff --git a/variables.tf b/variables.tf index ec0fe43..f7962ed 100644 --- a/variables.tf +++ b/variables.tf @@ -770,3 +770,39 @@ variable "restore_testing_iam_role_arn" { error_message = "The restore_testing_iam_role_arn must be a valid IAM role ARN. Avoid using 'test', 'temp', 'delete', or 'remove' in role names for security reasons." } } + +# +# AWS Backup Global Settings +# +variable "enable_global_settings" { + description = "Whether to manage AWS Backup global settings. Enable this to configure account-level backup settings." + type = bool + default = false +} + +variable "global_settings" { + description = "Global settings for AWS Backup. Currently supports isCrossAccountBackupEnabled for centralized cross-account backup governance." + type = map(string) + default = { + "isCrossAccountBackupEnabled" = "false" + } + + validation { + condition = can(var.global_settings["isCrossAccountBackupEnabled"]) ? contains(["true", "false"], var.global_settings["isCrossAccountBackupEnabled"]) : true + error_message = "isCrossAccountBackupEnabled must be either 'true' or 'false' as a string (not boolean). This setting controls cross-account backup capabilities for enterprise governance." + } + + validation { + condition = alltrue([ + for key, value in var.global_settings : can(regex("^[a-zA-Z][a-zA-Z0-9]*$", key)) + ]) + error_message = "Global setting keys must start with a letter and contain only alphanumeric characters. Currently supported: 'isCrossAccountBackupEnabled'." + } + + validation { + condition = alltrue([ + for key, value in var.global_settings : length(value) > 0 + ]) + error_message = "Global setting values cannot be empty strings. Use 'true' or 'false' for boolean settings." + } +} From f7f93ab9c3d171dbbe9ff387f1b61b6a66760780 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Tue, 14 Oct 2025 07:29:05 +0000 Subject: [PATCH 2/2] fix: use variables in backup_global_settings example - Use enable_cross_account_backup variable instead of hardcoded 'true' - Use vault_name, backup_schedule, backup_retention_days variables - Use tags variable for consistent tagging - Resolves unused variable issue from bug hunt review Co-authored-by: Luis M. Gallardo D. --- README.md | 22 ++++++++++++++++++++ examples/backup_global_settings/main.tf | 15 +++++-------- examples/backup_global_settings/variables.tf | 4 ++-- outputs.tf | 10 ++++----- variables.tf | 2 +- 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 6f7f562..eff5ad9 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ No modules. | Name | Type | |------|------| | [aws_backup_framework.ab_framework](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/backup_framework) | resource | +| [aws_backup_global_settings.ab_global_settings](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/backup_global_settings) | resource | | [aws_backup_logically_air_gapped_vault.ab_airgapped_vault](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/backup_logically_air_gapped_vault) | resource | | [aws_backup_plan.ab_plan](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/backup_plan) | resource | | [aws_backup_plan.ab_plans](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/backup_plan) | resource | @@ -123,8 +124,10 @@ No modules. | [changeable\_for\_days](#input\_changeable\_for\_days) | The number of days before the lock date. If omitted creates a vault lock in governance mode, otherwise it will create a vault lock in compliance mode | `number` | `null` | no | | [default\_lifecycle\_cold\_storage\_after\_days](#input\_default\_lifecycle\_cold\_storage\_after\_days) | Default number of days after creation that a recovery point is moved to cold storage. Used when cold\_storage\_after is not specified in lifecycle configuration. | `number` | `0` | no | | [default\_lifecycle\_delete\_after\_days](#input\_default\_lifecycle\_delete\_after\_days) | Default number of days after creation that a recovery point is deleted. Used when delete\_after is not specified in lifecycle configuration. | `number` | `90` | no | +| [enable\_global\_settings](#input\_enable\_global\_settings) | Whether to manage AWS Backup global settings. Enable this to configure account-level backup settings. | `bool` | `false` | no | | [enable\_org\_policy](#input\_enable\_org\_policy) | Enable AWS Organizations backup policy | `bool` | `false` | no | | [enabled](#input\_enabled) | Change to false to avoid deploying any AWS Backup resources | `bool` | `true` | no | +| [global\_settings](#input\_global\_settings) | Global settings for AWS Backup. Currently supports isCrossAccountBackupEnabled for centralized cross-account backup governance. | `map(string)` |
{
"isCrossAccountBackupEnabled": "false"
}
| no | | [iam\_role\_arn](#input\_iam\_role\_arn) | If configured, the module will attach this role to selections, instead of creating IAM resources by itself | `string` | `null` | no | | [iam\_role\_name](#input\_iam\_role\_name) | Allow to set IAM role name, otherwise use predefined default | `string` | `""` | no | | [locked](#input\_locked) | Change to true to add a lock configuration for the backup vault | `bool` | `false` | no | @@ -169,10 +172,14 @@ No modules. |------|-------------| | [airgapped\_vault\_arn](#output\_airgapped\_vault\_arn) | The ARN of the air gapped vault | | [airgapped\_vault\_id](#output\_airgapped\_vault\_id) | The name of the air gapped vault | +| [cross\_account\_backup\_enabled](#output\_cross\_account\_backup\_enabled) | Whether cross-account backup is enabled for centralized governance | | [framework\_arn](#output\_framework\_arn) | The ARN of the backup framework | | [framework\_creation\_time](#output\_framework\_creation\_time) | The date and time that the backup framework was created | | [framework\_id](#output\_framework\_id) | The unique identifier of the backup framework | | [framework\_status](#output\_framework\_status) | The deployment status of the backup framework | +| [global\_settings](#output\_global\_settings) | AWS Backup global settings configuration | +| [global\_settings\_id](#output\_global\_settings\_id) | AWS Account ID where global settings are applied | +| [global\_settings\_summary](#output\_global\_settings\_summary) | Summary of global settings configuration and governance capabilities | | [plan\_arn](#output\_plan\_arn) | The ARN of the backup plan | | [plan\_id](#output\_plan\_id) | The id of the backup plan | | [plan\_role](#output\_plan\_role) | The service role of the backup plan | @@ -290,6 +297,21 @@ In case you get an error message similar to this one: error creating Backup Vault (): AccessDeniedException: status code: 403, request id: 8e7e577e-5b74-4d4d-95d0-bf63e0b2cc2e, ``` +Add the [required IAM permissions mentioned in the CreateBackupVault row](https://docs.aws.amazon.com/aws-backup/latest/devguide/access-control.html#backup-api-permissions-ref) to the role or user creating the Vault (the one running Terraform CLI). In particular make sure `kms` and `backup-storage` permissions are added. + + +## Known Issues + +During the development of the module, the following issues were found: + +### Error creating Backup Vault + +In case you get an error message similar to this one: + +``` +error creating Backup Vault (): AccessDeniedException: status code: 403, request id: 8e7e577e-5b74-4d4d-95d0-bf63e0b2cc2e, +``` + Add the [required IAM permissions mentioned in the CreateBackupVault row](https://docs.aws.amazon.com/aws-backup/latest/devguide/access-control.html#backup-api-permissions-ref) to the role or user creating the Vault (the one running Terraform CLI). In particular make sure `kms` and `backup-storage` permissions are added. ## Testing diff --git a/examples/backup_global_settings/main.tf b/examples/backup_global_settings/main.tf index fe5c9a2..2a3b2f6 100644 --- a/examples/backup_global_settings/main.tf +++ b/examples/backup_global_settings/main.tf @@ -12,11 +12,11 @@ module "aws_backup_global_settings" { # Configure global settings for cross-account backup governance global_settings = { - "isCrossAccountBackupEnabled" = "true" + "isCrossAccountBackupEnabled" = tostring(var.enable_cross_account_backup) } # Basic vault configuration - vault_name = "centralized-backup-vault" + vault_name = var.vault_name # Basic plan for demonstration plan_name = "global-settings-plan" @@ -25,11 +25,11 @@ module "aws_backup_global_settings" { rules = [ { name = "daily-backup" - schedule = "cron(0 2 * * ? *)" # Daily at 2 AM + schedule = var.backup_schedule start_window = 120 completion_window = 360 lifecycle = { - delete_after = 30 + delete_after = var.backup_retention_days } copy_actions = [] recovery_point_tags = { @@ -63,10 +63,5 @@ module "aws_backup_global_settings" { } ] - tags = { - Owner = "backup-team" - Environment = "production" - BackupGovernance = "centralized" - Terraform = true - } + tags = var.tags } \ No newline at end of file diff --git a/examples/backup_global_settings/variables.tf b/examples/backup_global_settings/variables.tf index 6ca0975..1c715e5 100644 --- a/examples/backup_global_settings/variables.tf +++ b/examples/backup_global_settings/variables.tf @@ -15,7 +15,7 @@ variable "enable_cross_account_backup" { variable "backup_schedule" { description = "Cron expression for backup schedule" type = string - default = "cron(0 2 * * ? *)" # Daily at 2 AM + default = "cron(0 2 * * ? *)" # Daily at 2 AM } variable "backup_retention_days" { @@ -33,4 +33,4 @@ variable "tags" { BackupGovernance = "centralized" Terraform = true } -} \ No newline at end of file +} diff --git a/outputs.tf b/outputs.tf index 9dcf22d..63338f7 100644 --- a/outputs.tf +++ b/outputs.tf @@ -201,7 +201,7 @@ output "global_settings" { output "cross_account_backup_enabled" { description = "Whether cross-account backup is enabled for centralized governance" - value = try(aws_backup_global_settings.ab_global_settings[0].global_settings["isCrossAccountBackupEnabled"], null) == "true" + value = try(aws_backup_global_settings.ab_global_settings[0].global_settings["isCrossAccountBackupEnabled"], null) == "true" } # @@ -210,10 +210,10 @@ output "cross_account_backup_enabled" { output "global_settings_summary" { description = "Summary of global settings configuration and governance capabilities" value = var.enable_global_settings ? { - enabled = true - cross_account_backup_enabled = try(aws_backup_global_settings.ab_global_settings[0].global_settings["isCrossAccountBackupEnabled"], "false") == "true" - account_id = try(aws_backup_global_settings.ab_global_settings[0].id, null) - configured_settings = var.global_settings + enabled = true + cross_account_backup_enabled = try(aws_backup_global_settings.ab_global_settings[0].global_settings["isCrossAccountBackupEnabled"], "false") == "true" + account_id = try(aws_backup_global_settings.ab_global_settings[0].id, null) + configured_settings = var.global_settings # Governance and compliance information governance_impact = { diff --git a/variables.tf b/variables.tf index f7962ed..1ce40bd 100644 --- a/variables.tf +++ b/variables.tf @@ -788,7 +788,7 @@ variable "global_settings" { } validation { - condition = can(var.global_settings["isCrossAccountBackupEnabled"]) ? contains(["true", "false"], var.global_settings["isCrossAccountBackupEnabled"]) : true + condition = can(var.global_settings["isCrossAccountBackupEnabled"]) ? contains(["true", "false"], var.global_settings["isCrossAccountBackupEnabled"]) : true error_message = "isCrossAccountBackupEnabled must be either 'true' or 'false' as a string (not boolean). This setting controls cross-account backup capabilities for enterprise governance." }