Terraform中ALB访问日志配置引用count报错求助
问题描述
我尝试将带count参数的S3桶用于存储负载均衡器(ALB)的访问日志。
S3桶创建代码:
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 } } }
当var.enable_lb_logging为true时创建该桶,我配置ALB访问日志的代码如下:
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 } }
部署时出现错误:
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.
请问如何正确在负载均衡器配置中使用count以解决该问题?
解决方案
Terraform的count对象仅能在resource、module、data块中使用,无法嵌套在access_logs这类内部嵌套块里,这是报错的核心原因。不需要给access_logs添加count,直接通过条件判断结合S3桶属性引用即可实现需求,以下是两种可行方法:
方法一:直接条件引用S3桶属性
利用S3桶count仅为0或1的特性,结合var.enable_lb_logging控制日志开关:
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 { enabled = var.enable_lb_logging bucket = var.enable_lb_logging ? aws_s3_bucket.lb_logging[0].bucket : "" } }
- 当
var.enable_lb_logging为true时,access_logs启用并引用已创建的S3桶;为false时,日志关闭,bucket字段填空值即可(Terraform会自动忽略无效配置)。 - 由于S3桶的
count只会是0或1,直接用[0]索引是安全的,Terraform会自动处理count为0的场景(此时条件判断不会走到引用分支)。
方法二:用for_each替代count(可选优化)
若想让S3桶的引用更清晰,可将S3桶的count改为for_each:
resource aws_s3_bucket lb_logging { for_each = var.enable_lb_logging ? toset(["lb-log-bucket"]) : toset([]) 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 } } }
然后在ALB配置中通过for_each的键引用:
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 { enabled = var.enable_lb_logging bucket = var.enable_lb_logging ? aws_s3_bucket.lb_logging["lb-log-bucket"].bucket : "" } }
这种方式无需使用索引,语义更明确,适合后续扩展多桶场景。
内容的提问来源于stack exchange,提问作者BMD
相关产品推荐
相关产品推荐

