从CloudFormation迁移至Terraform,条件创建资源(count参数)报错求助
解决Terraform条件创建SecretsManager资源的问题
你遇到的问题有两个核心原因:一是默认的aws_secretsmanager_secret数据源在密钥不存在时会直接抛出错误,导致Terraform无法继续执行;二是当资源使用count元参数后,引用其属性时必须指定实例索引,不能直接引用资源本身。
以下是完整的解决方案:
1. 安全检查密钥是否存在
使用aws_secretsmanager_secrets数据源先过滤匹配的密钥,避免直接用aws_secretsmanager_secret因找不到资源报错:
# 过滤匹配目标名称的所有密钥 data "aws_secretsmanager_secrets" "matching_db_password" { filter { name = "name" values = ["${var.SecretPrefix}-my-service/RDS/password"] } } # 仅当匹配到密钥时,才读取其详细信息 data "aws_secretsmanager_secret" "existing_db_password" { count = length(data.aws_secretsmanager_secrets.matching_db_password.ids) > 0 ? 1 : 0 name = "${var.SecretPrefix}-my-service/RDS/password" } # 定义本地变量判断密钥是否存在 locals { secret_exists = length(data.aws_secretsmanager_secret.existing_db_password) == 1 }
2. 修复资源引用与条件创建逻辑
当资源使用count后,引用其属性时必须指定索引(因为count值只能是0或1,直接用[0]即可),调整后的资源代码如下:
resource "aws_secretsmanager_secret" "new_db_password" { count = local.secret_exists ? 0 : 1 name = "${var.SecretPrefix}-my-service/RDS/password" description = "password for new my service RDS" tags = { "Application" = "${var.SecretPrefix}-my-service" "resourceowner" = var.owner } tags_all = { "Application" = "${var.SecretPrefix}-my-service" "resourceowner" = var.owner } } resource "random_password" "new_rds_password" { count = local.secret_exists ? 0 : 1 length = 12 special = false } resource "aws_secretsmanager_secret_version" "my_rds_pwd_secret_version" { count = local.secret_exists ? 0 : 1 secret_id = aws_secretsmanager_secret.new_db_password[0].id secret_string = jsonencode({ password = random_password.new_rds_password[0].result }) }
补充说明
- 当目标区域已有对应密钥时,
local.secret_exists为true,所有资源的count设为0,不会创建新资源; - 若需要将已存在的密钥纳入Terraform管理,需执行
terraform import aws_secretsmanager_secret.new_db_password <secret-arn>,之后Terraform会对其进行状态跟踪; - 报错中提到的
count = aws_secretsmanager_secret.new_db_password.count是无效写法,资源的count属性不能直接引用其他资源的count值,需统一使用local.secret_exists来控制条件。
内容的提问来源于stack exchange,提问作者abyk007
相关产品推荐
相关产品推荐

