Skip to content

Commit 44e99e3

Browse files
feat: add support for aws_backup_global_settings (#277)
* feat: add support for aws_backup_global_settings - 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. <lgallard@users.noreply.github.com> * 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. <lgallard@users.noreply.github.com> --------- Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> Co-authored-by: Luis M. Gallardo D. <lgallard@users.noreply.github.com>
1 parent 1bc55d9 commit 44e99e3

File tree

9 files changed

+391
-0
lines changed

9 files changed

+391
-0
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ No modules.
8080
| Name | Type |
8181
|------|------|
8282
| [aws_backup_framework.ab_framework](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/backup_framework) | resource |
83+
| [aws_backup_global_settings.ab_global_settings](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/backup_global_settings) | resource |
8384
| [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 |
8485
| [aws_backup_plan.ab_plan](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/backup_plan) | resource |
8586
| [aws_backup_plan.ab_plans](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/backup_plan) | resource |
@@ -123,8 +124,10 @@ No modules.
123124
| <a name="input_changeable_for_days"></a> [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 |
124125
| <a name="input_default_lifecycle_cold_storage_after_days"></a> [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 |
125126
| <a name="input_default_lifecycle_delete_after_days"></a> [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 |
127+
| <a name="input_enable_global_settings"></a> [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 |
126128
| <a name="input_enable_org_policy"></a> [enable\_org\_policy](#input\_enable\_org\_policy) | Enable AWS Organizations backup policy | `bool` | `false` | no |
127129
| <a name="input_enabled"></a> [enabled](#input\_enabled) | Change to false to avoid deploying any AWS Backup resources | `bool` | `true` | no |
130+
| <a name="input_global_settings"></a> [global\_settings](#input\_global\_settings) | Global settings for AWS Backup. Currently supports isCrossAccountBackupEnabled for centralized cross-account backup governance. | `map(string)` | <pre>{<br/> "isCrossAccountBackupEnabled": "false"<br/>}</pre> | no |
128131
| <a name="input_iam_role_arn"></a> [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 |
129132
| <a name="input_iam_role_name"></a> [iam\_role\_name](#input\_iam\_role\_name) | Allow to set IAM role name, otherwise use predefined default | `string` | `""` | no |
130133
| <a name="input_locked"></a> [locked](#input\_locked) | Change to true to add a lock configuration for the backup vault | `bool` | `false` | no |
@@ -169,10 +172,14 @@ No modules.
169172
|------|-------------|
170173
| <a name="output_airgapped_vault_arn"></a> [airgapped\_vault\_arn](#output\_airgapped\_vault\_arn) | The ARN of the air gapped vault |
171174
| <a name="output_airgapped_vault_id"></a> [airgapped\_vault\_id](#output\_airgapped\_vault\_id) | The name of the air gapped vault |
175+
| <a name="output_cross_account_backup_enabled"></a> [cross\_account\_backup\_enabled](#output\_cross\_account\_backup\_enabled) | Whether cross-account backup is enabled for centralized governance |
172176
| <a name="output_framework_arn"></a> [framework\_arn](#output\_framework\_arn) | The ARN of the backup framework |
173177
| <a name="output_framework_creation_time"></a> [framework\_creation\_time](#output\_framework\_creation\_time) | The date and time that the backup framework was created |
174178
| <a name="output_framework_id"></a> [framework\_id](#output\_framework\_id) | The unique identifier of the backup framework |
175179
| <a name="output_framework_status"></a> [framework\_status](#output\_framework\_status) | The deployment status of the backup framework |
180+
| <a name="output_global_settings"></a> [global\_settings](#output\_global\_settings) | AWS Backup global settings configuration |
181+
| <a name="output_global_settings_id"></a> [global\_settings\_id](#output\_global\_settings\_id) | AWS Account ID where global settings are applied |
182+
| <a name="output_global_settings_summary"></a> [global\_settings\_summary](#output\_global\_settings\_summary) | Summary of global settings configuration and governance capabilities |
176183
| <a name="output_plan_arn"></a> [plan\_arn](#output\_plan\_arn) | The ARN of the backup plan |
177184
| <a name="output_plan_id"></a> [plan\_id](#output\_plan\_id) | The id of the backup plan |
178185
| <a name="output_plan_role"></a> [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:
290297
error creating Backup Vault (): AccessDeniedException: status code: 403, request id: 8e7e577e-5b74-4d4d-95d0-bf63e0b2cc2e,
291298
```
292299

300+
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.
301+
<!-- END_TF_DOCS -->
302+
303+
## Known Issues
304+
305+
During the development of the module, the following issues were found:
306+
307+
### Error creating Backup Vault
308+
309+
In case you get an error message similar to this one:
310+
311+
```
312+
error creating Backup Vault (): AccessDeniedException: status code: 403, request id: 8e7e577e-5b74-4d4d-95d0-bf63e0b2cc2e,
313+
```
314+
293315
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.
294316

295317
## Testing
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# AWS Backup Global Settings Example
2+
3+
This example demonstrates how to configure AWS Backup global settings for centralized cross-account backup governance.
4+
5+
## Features Demonstrated
6+
7+
- **Global Settings Management**: Enable and configure AWS Backup global settings
8+
- **Cross-Account Backup**: Enable centralized backup governance across multiple AWS accounts
9+
- **Enterprise Governance**: Account-level settings for backup operations
10+
- **Backup Configuration**: Basic vault, plan, and selection setup with global settings
11+
12+
## Architecture
13+
14+
```
15+
AWS Account (Management/Central)
16+
├── Global Settings (Account-level)
17+
│ └── isCrossAccountBackupEnabled: true
18+
├── Backup Vault
19+
├── Backup Plan
20+
└── Resource Selections
21+
```
22+
23+
## Usage
24+
25+
To run this example you need to execute:
26+
27+
```bash
28+
$ terraform init
29+
$ terraform plan
30+
$ terraform apply
31+
```
32+
33+
Note that this example will create resources which may cost money. Run `terraform destroy` when you don't need these resources.
34+
35+
## Requirements
36+
37+
| Name | Version |
38+
|------|---------|
39+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
40+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.0 |
41+
42+
## Providers
43+
44+
| Name | Version |
45+
|------|---------|
46+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.0 |
47+
48+
## Modules
49+
50+
| Name | Source | Version |
51+
|------|--------|---------|
52+
| <a name="module_aws_backup_global_settings"></a> [aws\_backup\_global\_settings](#module\_aws\_backup\_global\_settings) | ../.. | n/a |
53+
54+
## Resources
55+
56+
Created by the module:
57+
- `aws_backup_global_settings` - Account-level backup settings
58+
- `aws_backup_vault` - Backup vault for storing recovery points
59+
- `aws_backup_plan` - Backup plan with scheduling and lifecycle policies
60+
- `aws_backup_selection` - Resource selection for automated backups
61+
62+
## Inputs
63+
64+
| Name | Description | Type | Default | Required |
65+
|------|-------------|------|---------|:--------:|
66+
| <a name="input_backup_retention_days"></a> [backup\_retention\_days](#input\_backup\_retention\_days) | Number of days to retain backups | `number` | `30` | no |
67+
| <a name="input_backup_schedule"></a> [backup\_schedule](#input\_backup\_schedule) | Cron expression for backup schedule | `string` | `"cron(0 2 * * ? *)"` | no |
68+
| <a name="input_enable_cross_account_backup"></a> [enable\_cross\_account\_backup](#input\_enable\_cross\_account\_backup) | Enable cross-account backup functionality | `bool` | `true` | no |
69+
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to resources | `map(string)` | `{"BackupGovernance": "centralized", "Environment": "production", "Owner": "backup-team", "Terraform": true}` | no |
70+
| <a name="input_vault_name"></a> [vault\_name](#input\_vault\_name) | Name of the backup vault to create | `string` | `"centralized-backup-vault"` | no |
71+
72+
## Outputs
73+
74+
| Name | Description |
75+
|------|-------------|
76+
| <a name="output_cross_account_backup_enabled"></a> [cross\_account\_backup\_enabled](#output\_cross\_account\_backup\_enabled) | Whether cross-account backup is enabled |
77+
| <a name="output_global_settings"></a> [global\_settings](#output\_global\_settings) | Configured global settings |
78+
| <a name="output_global_settings_id"></a> [global\_settings\_id](#output\_global\_settings\_id) | AWS Account ID where global settings are applied |
79+
| <a name="output_global_settings_summary"></a> [global\_settings\_summary](#output\_global\_settings\_summary) | Summary of global settings configuration |
80+
| <a name="output_plan_arn"></a> [plan\_arn](#output\_plan\_arn) | ARN of the backup plan |
81+
| <a name="output_vault_arn"></a> [vault\_arn](#output\_vault\_arn) | ARN of the backup vault |
82+
83+
## Global Settings Configuration
84+
85+
### Cross-Account Backup Enablement
86+
87+
When `isCrossAccountBackupEnabled` is set to `"true"`:
88+
89+
1. **Centralized Governance**: Enables centralized backup management across AWS accounts
90+
2. **Organization Policies**: Allows AWS Organizations backup policies to be applied
91+
3. **Cross-Account IAM**: Enables backup operations across account boundaries
92+
4. **Compliance**: Supports enterprise compliance frameworks requiring centralized backup
93+
94+
### Enterprise Use Cases
95+
96+
- **Multi-Account Organizations**: Centralized backup governance for AWS Organizations
97+
- **Compliance Requirements**: Meeting regulatory requirements for backup management
98+
- **Security**: Controlled cross-account backup operations
99+
- **Cost Optimization**: Centralized backup strategies and policies
100+
101+
## Next Steps
102+
103+
After deploying this example:
104+
105+
1. **Configure AWS Organizations Backup Policies** for centralized governance
106+
2. **Set up cross-account IAM roles** for backup operations
107+
3. **Implement backup compliance frameworks** across accounts
108+
4. **Monitor backup activities** through AWS CloudTrail and CloudWatch
109+
110+
## Important Notes
111+
112+
- Global settings are **account-level** configurations (one per AWS account)
113+
- Cross-account backup requires proper **IAM permissions** across accounts
114+
- This feature is particularly valuable for **enterprise environments**
115+
- Consider **AWS Organizations integration** for complete centralized governance
116+
117+
## Compliance and Security
118+
119+
This configuration supports:
120+
- SOC 2 compliance for backup governance
121+
- GDPR requirements for data retention
122+
- HIPAA backup and recovery standards
123+
- Financial services backup regulations
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# AWS Backup Global Settings Example
2+
#
3+
# This example demonstrates how to configure AWS Backup global settings
4+
# for centralized cross-account backup governance.
5+
6+
# AWS Backup with Global Settings
7+
module "aws_backup_global_settings" {
8+
source = "../.."
9+
10+
# Enable global settings management
11+
enable_global_settings = true
12+
13+
# Configure global settings for cross-account backup governance
14+
global_settings = {
15+
"isCrossAccountBackupEnabled" = tostring(var.enable_cross_account_backup)
16+
}
17+
18+
# Basic vault configuration
19+
vault_name = var.vault_name
20+
21+
# Basic plan for demonstration
22+
plan_name = "global-settings-plan"
23+
24+
# Simple rule
25+
rules = [
26+
{
27+
name = "daily-backup"
28+
schedule = var.backup_schedule
29+
start_window = 120
30+
completion_window = 360
31+
lifecycle = {
32+
delete_after = var.backup_retention_days
33+
}
34+
copy_actions = []
35+
recovery_point_tags = {
36+
BackupType = "Automated"
37+
Governance = "Centralized"
38+
Environment = "production"
39+
}
40+
}
41+
]
42+
43+
# Resource selection
44+
selections = [
45+
{
46+
name = "production-resources"
47+
resources = [
48+
"arn:aws:ec2:*:*:instance/*",
49+
"arn:aws:rds:*:*:db:*"
50+
]
51+
selection_tags = [
52+
{
53+
type = "STRINGEQUALS"
54+
key = "Environment"
55+
value = "production"
56+
},
57+
{
58+
type = "STRINGEQUALS"
59+
key = "BackupRequired"
60+
value = "true"
61+
}
62+
]
63+
}
64+
]
65+
66+
tags = var.tags
67+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Global Settings Outputs
2+
output "global_settings_id" {
3+
description = "AWS Account ID where global settings are applied"
4+
value = module.aws_backup_global_settings.global_settings_id
5+
}
6+
7+
output "global_settings" {
8+
description = "Configured global settings"
9+
value = module.aws_backup_global_settings.global_settings
10+
}
11+
12+
output "cross_account_backup_enabled" {
13+
description = "Whether cross-account backup is enabled"
14+
value = module.aws_backup_global_settings.cross_account_backup_enabled
15+
}
16+
17+
output "global_settings_summary" {
18+
description = "Summary of global settings configuration"
19+
value = module.aws_backup_global_settings.global_settings_summary
20+
}
21+
22+
# Additional backup outputs for reference
23+
output "vault_arn" {
24+
description = "ARN of the backup vault"
25+
value = module.aws_backup_global_settings.vault_arn
26+
}
27+
28+
output "plan_arn" {
29+
description = "ARN of the backup plan"
30+
value = module.aws_backup_global_settings.plan_arn
31+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Optional variables for customizing the example
2+
3+
variable "vault_name" {
4+
description = "Name of the backup vault to create"
5+
type = string
6+
default = "centralized-backup-vault"
7+
}
8+
9+
variable "enable_cross_account_backup" {
10+
description = "Enable cross-account backup functionality"
11+
type = bool
12+
default = true
13+
}
14+
15+
variable "backup_schedule" {
16+
description = "Cron expression for backup schedule"
17+
type = string
18+
default = "cron(0 2 * * ? *)" # Daily at 2 AM
19+
}
20+
21+
variable "backup_retention_days" {
22+
description = "Number of days to retain backups"
23+
type = number
24+
default = 30
25+
}
26+
27+
variable "tags" {
28+
description = "A mapping of tags to assign to resources"
29+
type = map(string)
30+
default = {
31+
Owner = "backup-team"
32+
Environment = "production"
33+
BackupGovernance = "centralized"
34+
Terraform = true
35+
}
36+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = ">= 5.0"
8+
}
9+
}
10+
}

main.tf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,20 @@ resource "aws_backup_plan" "ab_plan" {
206206
}
207207
}
208208

209+
# AWS Backup Global Settings
210+
resource "aws_backup_global_settings" "ab_global_settings" {
211+
count = var.enabled && var.enable_global_settings ? 1 : 0
212+
213+
global_settings = var.global_settings
214+
215+
lifecycle {
216+
precondition {
217+
condition = var.enable_global_settings ? length(var.global_settings) > 0 : true
218+
error_message = "When enable_global_settings is true, global_settings map cannot be empty. At minimum, specify isCrossAccountBackupEnabled."
219+
}
220+
}
221+
}
222+
209223
# Multiple AWS Backup plans with optimized timeouts
210224
resource "aws_backup_plan" "ab_plans" {
211225
for_each = var.enabled ? local.plans_map : {}

0 commit comments

Comments
 (0)