I’d like to change the data protection of a log group in AWS. Initially I used the following code pattern, but found that there was a racing issue.
The first resource - name_a already exists. name_b is a new one. The resource - name_a is used for another log group, but I’d like to change one log group only this time, which controlled by counting the variable.
resource "aws_cloudwatch_log_data_protection_policy" "name_a" {
count = var.protect_a ? 1:0
log_group_name = var.log_group_name
policy_document = file("/a/path/to/json.file")
}
resource "aws_cloudwatch_log_data_protection_policy" "name_b" {
count = var.protect_b ? 1:0
log_group_name = var.log_group_name
policy_document = file("/a/path/to/new_json.file")
}
Terraform Plan shows destruction of name_a and creation of name_b. When applying the changes occasionally destruction (name_a) completes after creation (name_b), which ends up wiping out the data protection policy. It looks like there is a racing issue.
I tried another method by adding depends_on name_a hoping that creation will wait for completion of destruction, but often I get an error - self reference name_a (destroy).
resource "aws_cloudwatch_log_data_protection_policy" "name_a" {
count = var.protect_a ? 1:0
log_group_name = var.log_group_name
policy_document = file("/a/path/to/json.file")
}
resource "aws_cloudwatch_log_data_protection_policy" "name_b" {
count = var.protect_b ? 1:0
log_group_name = var.log_group_name
policy_document = file("/a/path/to/new_json.file")
depends_on = [
aws_cloudwatch_log_data_protection_policy.name_a
]
}
I also tried adding null_resource with depends_on name_a and another depends_on null_resource in the name_b resource block. At one time it seemed to be working fine, but then started throwing up the same self reference error. Because I tried so many little variations and cannot show the exact code pattern here, but in principle I added another block of null_resource as I described.
resource "aws_cloudwatch_log_data_protection_policy" "name_a" {
count = var.protect_a ? 1:0
log_group_name = var.log_group_name
policy_document = file("/a/path/to/json.file")
}
resource "aws_cloudwatch_log_data_protection_policy" "name_b" {
count = var.protect_b ? 1:0
log_group_name = var.log_group_name
policy_document = file("/a/path/to/new_json.file")
depends_on = [
null_resource.wait_for_deletion
]
}
resouce "null_resouce" "wait_for_deletion" {
count = strcontains(var.log_group_name, "a_name") ? 1:0
triggers = {
removed = var.protect_a && !var.protect_b ? "present" : "removed"
}
depends_on = [
aws_cloudwatch_log_data_protection_policy.name_a
]
}
A more better reliable approach would be a two-step one - terraform apply to delete the existing one then another apply to add a new one. Or, manually change the state, ie, move the existing one to name_b then apply the new json file.
But, is there a reliable way to achieve this in one run?
Appreciate your inputs and help