Terraform部署AWS SES遇Invalid count参数错误求助
Terraform部署AWS SES时Invalid count argument错误的解决办法
问题场景
首次使用Terraform部署AWS SES服务,依赖Route53中已有的域名和zone_id,配置代码通过count基于aws_ses_domain_dkim.dkim_domain.dkim_tokens的长度创建DKIM对应的Route53记录,执行terraform apply时触发错误,提示count依赖的资源属性需到apply阶段才能确定,无法预测实例数量。
配置代码
resource "aws_ses_domain_identity" "domain_identity" { domain = var.my_domain # 已存在的域名 } resource "aws_ses_domain_dkim" "dkim_domain" { domain = aws_ses_domain_identity.domain_identity.domain } resource "aws_route53_record" "ses_verification" { depends_on = [aws_ses_domain_dkim.dkim_domain] zone_id = var.zone_id # 已存在的zone_id name = "_amazonaws.qa.com" type = "TXT" ttl = 600 records = [aws_ses_domain_identity.domain_identity.verification_token] } resource "aws_route53_record" "ses_dkim_record" { depends_on = [aws_ses_domain_dkim.dkim_domain] count = length(aws_ses_domain_dkim.dkim_domain.dkim_tokens) zone_id = var.zone_id name = element(aws_ses_domain_dkim.dkim_domain.dkim_tokens, count.index) type = "CNAME" ttl = 600 records = [concat(element(aws_ses_domain_dkim.dkim_domain.dkim_tokens, count.index),".amazonses.com")] }
错误信息
╷ │ Error: Invalid count argument │ │ on ses/main.tf line 30, in resource "aws_route53_record" "ses_dkim_record": │ 30: count = length(aws_ses_domain_dkim.dkim_domain.dkim_tokens) │ │ The "count" value depends on resource attributes that cannot be determined │ until apply, so Terraform cannot predict how many instances will be │ created. To work around this, use the -target argument to first apply only │ the resources that the count depends on. ╵ Cleaning up project directory and file based variables 00:00 ERROR: Job failed: command terminated with exit code 1
解决方案
方法1:使用for_each替代count(推荐)
Terraform 0.13及以上版本支持用for_each处理动态集合,相比count更适配依赖apply阶段生成列表的场景。修改aws_route53_record.ses_dkim_record部分代码:
resource "aws_route53_record" "ses_dkim_record" { for_each = toset(aws_ses_domain_dkim.dkim_domain.dkim_tokens) zone_id = var.zone_id # DKIM记录名称格式为「token.你的域名」,比如 token1.qa.com name = "${each.value}.${var.my_domain}" type = "CNAME" ttl = 600 records = ["${each.value}.amazonses.com"] }
- 用
toset()将dkim_tokens转换为集合,满足for_each的参数要求 - 修正原代码中
name字段的错误(原代码缺少域名后缀,会导致记录创建位置不符合SES DKIM要求) - 改用
${}做字符串拼接,替代原代码中错误的concat用法(concat用于列表拼接,不适合字符串操作)
方法2:分阶段部署(临时方案)
按照错误提示,用-target参数先创建SES相关资源,再创建Route53记录:
- 先部署SES域名身份和DKIM资源:
terraform apply -target aws_ses_domain_identity.domain_identity -target aws_ses_domain_dkim.dkim_domain
- 再执行完整部署:
terraform apply
该方法适合无法升级Terraform版本的场景,但需要手动分两步执行,自动化程度较低。
额外修正:SES验证记录名称
原代码中aws_route53_record.ses_verification的name字段写死为_amazonaws.qa.com,若var.my_domain不是qa.com会导致错误,建议改为动态拼接:
name = "_amazonses.${var.my_domain}"
这才是SES域名验证记录的标准格式。
内容的提问来源于stack exchange,提问作者K P
相关产品推荐
相关产品推荐

