terraform-provider-aws
terraform-provider-aws copied to clipboard
aws_wafv2_web_acl resource dependency wrong way around
Terraform Version: 0.13.5 AWS provider version: v3.27.0 I have the following TF, when I run this after having run it before with a list of IP addresses it tries to delete the IP set before it removes the rule which was created including that IP set. I am unsure if this is due to me adding the for_each and making it a dynamic block though. In that case which config is correct? It results in the following error:
Error deleting WAFv2 IPSet: WAFAssociatedItemException: AWS WAF couldn’t perform the operation because your resource is being used by another resource or it’s associated with another resource.
resource "aws_wafv2_web_acl" "waf" {
name = "${local.name}-${var.environment}-WAF"
description = "${local.name}-${var.environment}-WAF"
scope = "REGIONAL"
default_action {
allow {}
}
dynamic "rule" {
for_each = var.waf_whitelist_ips != null ? [1] : []
content {
name = "WAFWhitelistIPs"
priority = 0
action {
allow {}
}
statement {
ip_set_reference_statement {
arn = aws_wafv2_ip_set.ipset[0].arn
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "${local.name}-${var.environment}-WHITELISTIps"
sampled_requests_enabled = true
}
}
}
rule {
name = "AWSManagedIpReputation"
priority = 1
override_action {
none {}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesAmazonIpReputationList"
vendor_name = "AWS"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "${local.name}-${var.environment}-WAF-IP-Bad-Rep"
sampled_requests_enabled = true
}
}
// WAF whitelist IP set
resource "aws_wafv2_ip_set" "ipset" {
count = var.waf_whitelist_ips != null ? 1 : 0
name = "WAFWhitelistIPs"
scope = "REGIONAL"
ip_address_version = "IPV4"
addresses = var.waf_whitelist_ips
}
Hi @waqark3389 , thank you for creating this issue. I'm unable to reproduce on my end unfortunately with the complete config you've provided, the dynamic block seems to work as I'd expect. Would you be able to provide any debug logs to further investigate the error?
I facing the same issue. The problem isn't with dynamic block here. Instead, when you will set waf_whitelist_ips to null it won't be able to delete the IP set as it is being used within the rule. hence, until the rule is removed from the rule IP set cannot be deleted
We are facing this issue when trying to remove a rule that is referencing an ip set. It first tries to destroy the IP set but that does not work because it is still being referenced in the web acl rule. The actual behaviour should be to first adjust the web acl and delete the necessary rule and then destroying the ip set. Also settings an explicit depends_on in the web acl to the ip set does not solve the problem.
To confirm, I have the same issue when I try and delete an ip ruleset it fails because it tries to delete it first without removing the ruleset first.
Hello! I am facing with the same issue (Terraform v0.15.1 + provider registry.terraform.io/hashicorp/aws v3.37.0). In order to reproduce:
- Create e.g., 2
aws_wafv2_ip_setoraws_wafv2_regex_pattern_setand link inaws_wafv2_web_aclviarule. 1 acl with 2 rules. - Remove one
aws_wafv2_ip_setoraws_wafv2_regex_pattern_setand the relatedrule. - Create plan: it should show that 1 rule and e.g., 1 ip set to be removed with the acl updated in place.
Result: Terraform starts to delete aws_wafv2_ip_set first not the rule which is not possible.
Expected: Terraform should start to remove rule first.
The issue is the same if the resource name changes and acl rule to be updated. The lifecycle does not have an impact.
Hello, I had similar issue when aws_wafv2_regex_pattern_set couldn't be destroyed as it was used by aws_wafv2_web_acl. I added depends_on = [aws_wafv2_regex_pattern_set.custom_allow_regex] to aws_wafv2_web_acl resource and it still did not help exactly like in cases described above.
What DID help was to add
lifecycle {
create_before_destroy = true
}
to both aws_wafv2_regex_pattern_set and aws_wafv2_web_acl resources so now terraform is firstly create new aws_wafv2_regex_pattern_set, update it in aws_wafv2_web_acl and then it is free to destroy previous aws_wafv2_regex_pattern_set resource.
Hope it will help you :)
We're running into this problem too with 0.15.x. Does anyone know if it has been fixed in 1.x?
Hello, I had similar issue when
aws_wafv2_regex_pattern_setcouldn't be destroyed as it was used byaws_wafv2_web_acl. I addeddepends_on = [aws_wafv2_regex_pattern_set.custom_allow_regex]toaws_wafv2_web_aclresource and it still did not help exactly like in cases described above.What DID help was to add
lifecycle { create_before_destroy = true }to both
aws_wafv2_regex_pattern_setandaws_wafv2_web_aclresources so now terraform is firstly create newaws_wafv2_regex_pattern_set, update it inaws_wafv2_web_acland then it is free to destroy previousaws_wafv2_regex_pattern_setresource. Hope it will help you :)
It worked for me. Thanks
@phuocntsts what version of the provider are you using? Original issue was filed with v3.27.0. Latest is v3.63.0. v3.47.0 was latest release when @Pola93 claimed the fix you're using. So has this been fixed since v3.47.0? Possibly fixed by #17876 that was included in release v3.33.0
@phuocntsts what version of the provider are you using? Original issue was filed with v3.27.0. Latest is v3.63.0. v3.47.0 was latest release when @Pola93 claimed the fix you're using. So has this been fixed since v3.47.0? Possibly fixed by #17876 that was included in release v3.33.0
Hi @jmeridth , my current version is v3.62.0. today I get the same error and it worked for me when I try with "lifecycle".
Hi, I also solved exactly this problem using "lifecycle" block. I was trying to modify ip set, regex pattern set and rule groups. Thank you.
lifecycle {
create_before_destroy = true
}
I tried to use the lifecycle block but Terraform expectedly failed to create a WAF rule group (in my case) because of the already existing one. We use Terraform v1.0.0 and terraform-provider-aws v4.15.1.
Disregard - I can't delete this comment
We are hitting this too, in our case the create_before_destroy does not work because the existing waf is just being updated not replaced
To workaround this we had to do a two step decomm First update the waf to remove the rules that no longer use the other resources. Then apply that Then we can decome the regex/ipset resources in a second apply
Still a problem when updating an existing WAF with Terraform 1.3.2 and AWS provider 4.56.0.
Lifecycle block did not help.
Still having this problem :/
It is still a problem when updating WAF: Terraform v1.4.6 and AWS provider 4.66.1
For anyone hitting this, and neither being able to fix it with the create_before_destroy configuration nor being able to temporarily remove resources to make TF happy: Another option that now worked for me is to manually remove the resources that TF wants to delete from the state (using terraform state rm), let TF do the other updates, and then manually remove the resources using the AWS console/CLI.
TF still can't handle this simple dependency correctly, failing horribly as an IaC tool (manual workarounds, lol). I can't wait for this issue to turn 3 year-old (I collect TF old issues that never get fixed because they are deeply rooted into conceptions flaws. That's why I'm in such a good mood).
where should we add in the waf resource or rule resource ?
lifecycle {
create_before_destroy = true
}
as I create dynamic rules like this
resource "aws_wafv2_ip_set" "waf_ip_sets" {
for_each = local.clientIpSets
name = "${var.infra_env}-${lower(each.key)}-ips"
ip_address_version = each.value.version
addresses = each.value.addresses
description = each.value.description
scope = "REGIONAL"
tags = {
CreatedBy = "Manash"
ManagedBy = "terraform"
infra_env = var.infra_env
}
}```
where should we add in the waf resource or rule resource ?
lifecycle { create_before_destroy = true }as I create dynamic rules like this
resource "aws_wafv2_ip_set" "waf_ip_sets" { for_each = local.clientIpSets name = "${var.infra_env}-${lower(each.key)}-ips" ip_address_version = each.value.version addresses = each.value.addresses description = each.value.description scope = "REGIONAL" tags = { CreatedBy = "Manash" ManagedBy = "terraform" infra_env = var.infra_env } }```
As it is mentioned in the comment
lifecycle {
create_before_destroy = true
}
should be added to both resources
aws_wafv2_web_aclaws_wafv2_ip_set
You can try this step by step. First add to aws_wafv2_web_acl and if not fixed, add it to aws_wafv2_ip_set and check.
Adding a lifecycle does not fix the issue.
lifecycle {
create_before_destroy = true
}
What is your case and components versions?
We are also hitting this scenario, but in our case it is an IPSet referenced in a RuleGroup. Sadly using lifecycle/depends_on blocks doesn't work because the RuleGroup is just updated, not recreated. Not to mention that RuleGroups themselves are referenced in web ACLs, so forcing recreation wouldn't work either.
It would be greatly appreciated if this was addressed officially, even if the fix is simply a well-defined workaround instead of code changes in this provider. Web ACLs are critical pieces of security infrastructure, thus it's very important to have the ability to remove IPSets (and thus their references) from infrastructure swiftly and confidently
edit: we are on hashicorp/aws v5.22.0, Terraform ~>1.6
Hello, I had similar issue when
aws_wafv2_regex_pattern_setcouldn't be destroyed as it was used byaws_wafv2_web_acl. I addeddepends_on = [aws_wafv2_regex_pattern_set.custom_allow_regex]toaws_wafv2_web_aclresource and it still did not help exactly like in cases described above.What DID help was to add
lifecycle { create_before_destroy = true }to both
aws_wafv2_regex_pattern_setandaws_wafv2_web_aclresources so now terraform is firstly create newaws_wafv2_regex_pattern_set, update it inaws_wafv2_web_acland then it is free to destroy previousaws_wafv2_regex_pattern_setresource. Hope it will help you :)
Thank you @Pola93. This worked for me. To provide more context for my case: terraform version: 1.4.6 aws provider version: 5.15.0
I was renaming the aws_wafv2_ip_set and aws_wafv2_rule_group resources previously created. So terraform apply was destroying them before updating the associated aws_wafv2_web_acl rules. To fix this dependency, I only added the lifecycle { create_before_destroy = true } block to the aws_wafv2_ip_set and aws_wafv2_rule_group resource blocks and it worked on terraform apply.
Note: I did not have to add the lifecycle { create_before_destroy = true } block to aws_wafv2_web_acl.