-
Notifications
You must be signed in to change notification settings - Fork 62
/
Copy pathmain.tf
152 lines (133 loc) · 5.26 KB
/
main.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# AWS Backup vault
resource "aws_backup_vault" "ab_vault" {
count = var.enabled && var.vault_name != null ? 1 : 0
name = var.vault_name
kms_key_arn = var.vault_kms_key_arn
force_destroy = var.vault_force_destroy
tags = var.tags
}
# AWS Backup vault lock configuration
resource "aws_backup_vault_lock_configuration" "ab_vault_lock_configuration" {
count = var.enabled && var.vault_name != null && var.locked ? 1 : 0
backup_vault_name = aws_backup_vault.ab_vault[0].name
min_retention_days = var.min_retention_days
max_retention_days = var.max_retention_days
changeable_for_days = var.changeable_for_days
lifecycle {
precondition {
condition = local.check_retention_days
error_message = "When vault locking is enabled (locked = true), min_retention_days and max_retention_days must be provided and min_retention_days must be less than or equal to max_retention_days."
}
}
}
# AWS Backup plan
resource "aws_backup_plan" "ab_plan" {
count = var.enabled && length(local.rules) > 0 ? 1 : 0
name = coalesce(var.plan_name, "aws-backup-plan-${var.vault_name != null ? var.vault_name : "default"}")
# Rules
dynamic "rule" {
for_each = local.rules
content {
rule_name = try(rule.value.name, null)
target_vault_name = try(rule.value.target_vault_name, null) != null ? rule.value.target_vault_name : var.vault_name != null ? aws_backup_vault.ab_vault[0].name : "Default"
schedule = try(rule.value.schedule, null)
start_window = try(rule.value.start_window, null)
completion_window = try(rule.value.completion_window, null)
enable_continuous_backup = try(rule.value.enable_continuous_backup, null)
recovery_point_tags = coalesce(rule.value.recovery_point_tags, var.tags)
# Lifecycle
dynamic "lifecycle" {
for_each = length(try(rule.value.lifecycle, {})) == 0 ? [] : [rule.value.lifecycle]
content {
cold_storage_after = try(lifecycle.value.cold_storage_after, 0)
delete_after = try(lifecycle.value.delete_after, 90)
}
}
# Copy action
dynamic "copy_action" {
for_each = try(rule.value.copy_actions, [])
content {
destination_vault_arn = try(copy_action.value.destination_vault_arn, null)
# Copy Action Lifecycle
dynamic "lifecycle" {
for_each = length(try(copy_action.value.lifecycle, {})) == 0 ? [] : [copy_action.value.lifecycle]
content {
cold_storage_after = try(lifecycle.value.cold_storage_after, 0)
delete_after = try(lifecycle.value.delete_after, 90)
}
}
}
}
}
}
# Advanced backup setting
dynamic "advanced_backup_setting" {
for_each = var.windows_vss_backup ? [1] : []
content {
backup_options = {
WindowsVSS = "enabled"
}
resource_type = "EC2"
}
}
# Tags
tags = var.tags
# First create the vault if needed
depends_on = [aws_backup_vault.ab_vault]
lifecycle {
precondition {
condition = !var.windows_vss_backup || (length(local.selection_resources) > 0 && can(regex(".*EC2.*", join(",", local.selection_resources))))
error_message = "Windows VSS backup is enabled but no EC2 instances are selected for backup. Either disable windows_vss_backup or include EC2 instances in your backup selection."
}
# Add lifecycle validations at the plan level
precondition {
condition = local.lifecycle_validations
error_message = "In one or more rules, cold_storage_after must be less than or equal to delete_after."
}
}
}
locals {
# Rule
rule = var.rule_name == null ? [] : [
{
name = var.rule_name
target_vault_name = var.vault_name != null ? var.vault_name : "Default"
schedule = var.rule_schedule
start_window = var.rule_start_window
completion_window = var.rule_completion_window
lifecycle = var.rule_lifecycle_cold_storage_after == null ? {} : {
cold_storage_after = var.rule_lifecycle_cold_storage_after
delete_after = var.rule_lifecycle_delete_after
}
enable_continuous_backup = var.rule_enable_continuous_backup
recovery_point_tags = var.rule_recovery_point_tags
}
]
# Rules
rules = concat(local.rule, var.rules)
# Helper for VSS validation
selection_resources = flatten([
for selection in var.backup_selections : try(selection.resources, [])
])
# Lifecycle validations
lifecycle_validations = alltrue([
for rule in local.rules : (
length(try(rule.lifecycle, {})) == 0 ? true :
try(rule.lifecycle.cold_storage_after, 0) <= try(rule.lifecycle.delete_after, 90)
) &&
alltrue([
for copy_action in try(rule.copy_actions, []) : (
length(try(copy_action.lifecycle, {})) == 0 ? true :
try(copy_action.lifecycle.cold_storage_after, 0) <= try(copy_action.lifecycle.delete_after, 90)
)
])
])
# Check retention days - handling null values properly
check_retention_days = var.locked ? (
var.min_retention_days == null ? false : (
var.max_retention_days == null ? false : (
var.min_retention_days <= var.max_retention_days
)
)
) : true
}