I'm trying to access s3 bucket from load balancer access logs. There is a count set on the s3 bucket creation.
resource aws_s3_bucket lb_logging {
count = var.enable_lb_logging ? 1 : 0
bucket = "${var.environment_id}-account-lb-logging"
acl = "private"
force_destroy = true
lifecycle_rule {
id = "${var.environment_id}-account-lb-logging"
enabled = true
expiration {
days = var.lb_logging_s3_expiration_period
}
}
}
When var.enable_lb_logging is true, it creates the s3 bucket and the need is to use the bucket to store load balancer access logs. My load balancer access logs looks like -
resource aws_lb alb {
internal = var.alb_is_public ? false : true
security_groups = compact(concat(aws_security_group.additional_security_groups.*.id, list(aws_security_group.main.id), list(aws_security_group.account_inbound_rules_arm.id)))
subnets = local.alb_subnets
tags = var.tags
access_logs {
count = length(aws_s3_bucket.lb_logging)
bucket = "${aws_s3_bucket.lb_logging[count.index].bucket}"
enabled = var.enable_lb_logging ? true : false
}
}
During deployment I'm getting the below error
2022-09-08T16:08:46.5043258Z ##[error][1m[31mError: [0m[0m[1mReference to "count" in non-counted context[0m
2022-09-08T16:08:46.5063266Z ##[error][0m on modules\load-balancers.tf line 16, in resource "aws_lb" "alb":
2022-09-08T16:08:46.5110603Z ##[error] 16: bucket = "${aws_s3_bucket.lb_logging[[4mcount.index[0m].bucket}"
2022-09-08T16:08:46.5116983Z ##[error][0m
2022-09-08T16:08:46.5119949Z ##[error]The "count" object can only be used in "module", "resource", and "data"
2022-09-08T16:08:46.5122470Z ##[error]blocks, and only when the "count" argument is set.
Can someone help me on this? how to use count in load balancer?
CodePudding user response:
The error is pretty clear. You cannot use the count
meta-argument anywhere, i.e., in your case, you cannot use it in a block that you want to:
access_logs {
count = length(aws_s3_bucket.lb_logging) # <----- This cannot be done
bucket = "${aws_s3_bucket.lb_logging[count.index].bucket}"
enabled = var.enable_lb_logging ? true : false
}
However, similarly to what you have done for the bucket, you could do something like:
resource aws_lb alb {
count = var.enable_lb_logging ? 1 : 0
internal = var.alb_is_public ? false : true
security_groups = compact(concat(aws_security_group.additional_security_groups.*.id, list(aws_security_group.main.id), list(aws_security_group.account_inbound_rules_arm.id)))
subnets = local.alb_subnets
tags = var.tags
access_logs {
bucket = aws_s3_bucket.lb_logging[count.index].bucket
enabled = var.enable_lb_logging ? true : false
}
}
The question remains if you want to have ALB depend on the bucket or another variable. In that case, you can use a different variable, but then you would have to figure out how to fetch the bucket index. If you are sure there will ever be only one bucket, you can even hardcode the index:
resource aws_lb alb {
internal = var.alb_is_public ? false : true
security_groups = compact(concat(aws_security_group.additional_security_groups.*.id, list(aws_security_group.main.id), list(aws_security_group.account_inbound_rules_arm.id)))
subnets = local.alb_subnets
tags = var.tags
access_logs {
bucket = aws_s3_bucket.lb_logging[0].bucket
enabled = var.enable_lb_logging ? true : false
}
}
However, since the bucket
is a required argument, you could use the dynamic block depending on the value of var.enable_lb_logging
, e.g.:
resource aws_lb alb {
internal = var.alb_is_public ? false : true
security_groups = compact(concat(aws_security_group.additional_security_groups.*.id, list(aws_security_group.main.id), list(aws_security_group.account_inbound_rules_arm.id)))
subnets = local.alb_subnets
tags = var.tags
dynamic "access_logs" {
for_each = var.enable_lb_logging ? [1] : []
content {
bucket = aws_s3_bucket.lb_logging[0].bucket
enabled = var.enable_lb_logging
}
}
}