'WAF for all ALBs in an account using terraform
This is my waf.tf terraform file:
resource "aws_wafv2_web_acl" "waf_acl-dev" {
name = "waf_log4j_Protections-dev"
description = "WAFv2 for dev"
scope = "REGIONAL"
default_action {
allow {}
}
rule {
name = "AWSManagedRulesKnownBadInputsRule"
priority = 1
override_action {
count {}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesKnownBadInputsRuleSet"
vendor_name = "AWS"
# Excluding all these leaves only Log4JRCE
excluded_rule {
name = "Host_localhost_HEADER"
}
excluded_rule {
name = "PROPFIND_METHOD"
}
excluded_rule {
name = "ExploitablePaths_URIPATH"
}
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AWSManagedRulesKnownBadInputsRule"
sampled_requests_enabled = true
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AWSManagedKnownBadInputsRule"
sampled_requests_enabled = true
}
}
variable "lb_arn" {
type = string
default = ""
}
data "aws_lb" "all_alb" {
tags = {
Environment = "Dev"
}
# arn = var.lb_arn
# for_each = data.aws_lb.all_alb
# id = each.value
}
output "all_alb" {
value = data.aws_lb.all_alb
}
resource "aws_wafv2_web_acl_association" "waf_acl-association-dev" {
for_each = data.aws_lb.all_alb.arn
resource_arn = each.value
web_acl_arn = aws_wafv2_web_acl.waf_acl-dev.arn
}
My objective is to create a WAF with rules (that portion works fine), and attach multiple ALBs to the WAF using tags on each ALB. Im running it inside a teamcity loop that loops into multiple AWS accounts (That is out of scope). Each account can have one or multiple ALBs with the tag provided. When I run this code I get the following error:
Error: Search returned 2 results, please revise so only one is returned
17:39:18 │
17:39:18 │ with data.aws_lb.all_alb,
17:39:18 │ on xa-waf-inow.tf line 49, in data "aws_lb" "all_alb":
17:39:18 │ 49: data "aws_lb" "all_alb" {
I also tried a few other alternatives like putting [0] at the end of line 49 but Im still getting hit with some syntax error or the other. Can someone please help?Thanks
Edit:
I also tried for_each
in data block:
data "aws_lb" "all_alb" {
for_each = {
tags = {
Environment = "Dev"
}
}
arn = each.key
}
output "all_alb" {
value = data.aws_lb.all_alb
}
resource "aws_wafv2_web_acl_association" "waf_acl-association-dev" {
# for_each = data.aws_lb.all_alb.arn
resource_arn = data.aws_lb.all_alb[each.key]
web_acl_arn = aws_wafv2_web_acl.waf_acl-dev.arn
}
But got this error:
Error: Reference to "each" in context without for_each
18:24:01 │
18:24:01 │ on xa-waf-inow.tf line 65, in resource "aws_wafv2_web_acl_association" "waf_acl-association-dev":
18:24:01 │ 65: resource_arn = data.aws_lb.all_alb[each.key]
18:24:01 │
18:24:01 │ The "each" object can be used only in "module" or "resource" blocks, and
18:24:01 │ only when the "for_each" argument is set.
Solution 1:[1]
The aws_lb
data source must return only one result. You can't change that, as this is how it was destined.
If you want to return multiple ALBs you have two choices:
- Use
for_each
with the data source. This way your data source will run for each id of your alb. This means that you have to provide the alb ids as an input variable. - Or, create your own custom data source. Since this is fully custom code that you have to write, it can overcome any limitations of TF's build in data sources.
Solution 2:[2]
I was able to get this to work for myself. My issue was a mixture of lists and sets. I believe I can change my variable to a set, and not have to deal with any sets here, but I know the below works as is.
VARIABLES.TF
variable "list_of_alb" {
type = list(string)
}
MAIN.TF
list_of_alb = [
"${terraform.workspace}-unique-1",
"${terraform.workspace}-unique-2"
]
DATA.TF
- the problem child
data "aws_lb" "main" {
for_each = toset( var.list_of_alb )
name = each.value
}
WAF.TF
resource "aws_wafv2_web_acl_association" "main" {
for_each = toset(var.list_of_alb)
resource_arn = data.aws_lb.main[each.value].arn
web_acl_arn = aws_wafv2_web_acl.main.arn
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Marcin |
Solution 2 | John Casillas |