Terraform vs AWS WAF: What Went Wrong When I Tried to Add Rules to an Existing Web ACL
When considering Infrastructure as Code, the ideal state is one of control, clarity, and clean versioning. However, if you've ever grappled…
Terraform vs AWS WAF: What Went Wrong When I Tried to Add Rules to an Existing Web ACL

When considering Infrastructure as Code, the ideal state is one of control, clarity, and clean versioning. However, if you've ever grappled with integrating Terraform with AWS WAF, particularly for updating an existing Web ACL, you'll understand that the process is not always straightforward. This is the story of how I tried to do the “right thing” and still hit a wall.
🛠 The Goal: Add Custom Rules to an Existing WAF Web ACL I had a Web ACL in AWS, automatically created and associated with an ALB via the AWS Console. My goal was simple: Add three custom WAF rules using Terraform:
Rate limiting (block IPs making over 2000 requests per 5 minutes)
Regex-based path blocking (/.env, /wp-login, etc.)
User-Agent header check (block requests missing or faking headers)
It seems simple, doesn't it?
⚠️ What Went Wrong
- Terraform Doesn’t Like Existing Resources It Didn’t Create I tried to define an aws_wafv2_web_acl in my Terraform script with the same name and scope as the existing one.
hcl
Copy
Edit
resource "aws_wafv2_web_acl" "chy_acl" {
name = "chy-alb"
...
}
Boom! Error: A web ACL with that name already exists. Why? Terraform aims to generate resources from the beginning and doesn't function effectively with items generated through the AWS Console unless you import them beforehand.
- Rate-Based Rules Can’t Live in Rule Groups Next, I thought I’d work around it by creating a rule_group:
resource "aws_wafv2_rule_group" "custom" {
...
rule {
name = "RateLimit2000"
statement {
rate_based_statement {
...
}
}
}
}
Another slap from Terraform:
rate_based_statement is not allowed in rule_group
Turns out, AWS only allows rate-based statements at the Web ACL level, not inside rule groups.
3. Session Token & Invalid Credentials Errors
Then, just for good measure, I got hit with this:
InvalidClientTokenId: The security token included in the request is invalid.
This was because of expired AWS credentials or a bad environment variable setup. Reconfiguring via AWS configure fixed that.
🧘🏽♀️ What I Did Instead
I pivoted.
- Created the regex pattern set and header sanitiser rule as a Terraform-managed rule group
- Applied that via Terraform
- Then manually went into the AWS Console → Web ACL → Add rule group → Selected my new custom group → Done.
It wasn’t the 100% IaC dream I wanted. But it worked. And sometimes, done is better than perfect.
💡 Lessons Learned
- Terraform can’t manage what it didn’t create—unless you import it.
- Rate-based rules don’t belong in rule groups. Keep those directly at the Web ACL level.
- Start small. Test your WAF rules one by one. Regex patterns especially can cause chaos.
- Expect to fall back on the console occasionally. AWS WAF still has quirks that make Terraform-only setups tricky.
🎯 Final Thoughts
Security automation is essential, but tooling maturity still matters. For now, managing AWS WAF with Terraform is doable, but not without knowing its limits. If you’re planning to manage existing WAF rules via Terraform, be prepared to:
- Import resources
- Split logic between rule groups and Web ACL
- Alternatively, you may choose to manually complete the task and move on.
And honestly? That’s okay.
메타데이터
- post_id
- ce633b00dcc0
- slug
- terraform-vs-aws-waf-what-went-wrong-when-i-tried-to-add-rules-to-an-existing-web-acl-ce633b00dcc0
- url
- https://medium.com/@chyjuls/terraform-vs-aws-waf-what-went-wrong-when-i-tried-to-add-rules-to-an-existing-web-acl-ce633b00dcc0
- canonical_url
- https://medium.com/@chyjuls/terraform-vs-aws-waf-what-went-wrong-when-i-tried-to-add-rules-to-an-existing-web-acl-ce633b00dcc0
- author_url
- https://medium.com/@chyjuls
- status
- ok
- fetched_at
- 2026-06-13 07:35:29