Terraform创建Aurora MySQL Serverless克隆集群报源集群不存在错误
问题根因
- 依赖关系缺失:你通过count批量创建两个集群时,两个模块实例之间没有建立依赖关系,Terraform无法感知克隆集群需要等待源集群完全就绪(包括可恢复时间点生成)才可以创建。虽然日志显示源集群已创建完成,但AWS侧需要额外时间同步源集群的备份恢复元数据,此时调用克隆API会返回找不到源集群的错误。
- 硬编码的源集群标识:你把源集群标识硬编码在tfvars配置中,Terraform无法将该值和第一个集群的创建状态关联,不会自动推迟克隆集群的创建时机。
- 额外的小问题:模块中
scaling_configuration动态块缺少for_each判断,虽然本次场景不影响报错,但不符合serverless配置的最佳实践。
修复方案
步骤1:给Aurora模块添加输出
在./modules/aurora_mysql/outputs.tf中添加如下配置,暴露集群的标识和可恢复时间用于依赖传递:
output "cluster_identifier" { type = string description = "Aurora集群唯一标识" value = aws_rds_cluster.rds_mysql.id } output "latest_restorable_time" { type = string description = "集群最新可恢复时间点" value = aws_rds_cluster.rds_mysql.latest_restorable_time }
步骤2:调整模块调用,建立显式依赖
不推荐用count批量创建有依赖关系的集群,拆分模块调用显式指定依赖:
# 源集群实例 module "aurora_mysql_source" { source = "./modules/aurora_mysql" cluster_identifier = var.aurora_mysql[0].cluster_identifier source_cluster_identifier = var.aurora_mysql[0].source_cluster_identifier engine = var.aurora_mysql[0].engine engine_version = var.aurora_mysql[0].engine_version engine_mode = var.aurora_mysql[0].engine_mode availability_zones = var.aurora_mysql[0].availability_zones database_name = var.aurora_mysql[0].database_name db_port = var.aurora_mysql[0].db_port master_username = var.aurora_mysql[0].master_username master_password = var.aurora_mysql[0].master_password backup_retention_period = var.aurora_mysql[0].backup_retention_period restore = var.aurora_mysql[0].restore restore_type = var.aurora_mysql[0].restore_type db_subnet_group_name = var.aurora_mysql[0].db_subnet_group_name vpc_security_group_ids = var.aurora_mysql[0].vpc_security_group_ids cluster_parameter_group = var.aurora_mysql[0].cluster_parameter_group backtrack_window = var.aurora_mysql[0].backtrack_window skip_final_snapshot = var.aurora_mysql[0].skip_final_snapshot deletion_protection = var.aurora_mysql[0].deletion_protection db_parameter_group = var.aurora_mysql[0].db_parameter_group auto_pause = var.aurora_mysql[0].auto_pause max_capacity = var.aurora_mysql[0].max_capacity min_capacity = var.aurora_mysql[0].min_capacity seconds_until_auto_pause = var.aurora_mysql[0].seconds_until_auto_pause timeout_action = var.aurora_mysql[0].timeout_action } # 克隆集群实例 module "aurora_mysql_clone" { source = "./modules/aurora_mysql" cluster_identifier = var.aurora_mysql[1].cluster_identifier # 直接引用源集群的输出,自动建立隐式依赖 source_cluster_identifier = module.aurora_mysql_source.cluster_identifier engine = var.aurora_mysql[1].engine engine_version = var.aurora_mysql[1].engine_version engine_mode = var.aurora_mysql[1].engine_mode availability_zones = var.aurora_mysql[1].availability_zones database_name = var.aurora_mysql[1].database_name db_port = var.aurora_mysql[1].db_port master_username = var.aurora_mysql[1].master_username master_password = var.aurora_mysql[1].master_password backup_retention_period = var.aurora_mysql[1].backup_retention_period restore = var.aurora_mysql[1].restore restore_type = var.aurora_mysql[1].restore_type db_subnet_group_name = var.aurora_mysql[1].db_subnet_group_name vpc_security_group_ids = var.aurora_mysql[1].vpc_security_group_ids cluster_parameter_group = var.aurora_mysql[1].cluster_parameter_group backtrack_window = var.aurora_mysql[1].backtrack_window skip_final_snapshot = var.aurora_mysql[1].skip_final_snapshot deletion_protection = var.aurora_mysql[1].deletion_protection db_parameter_group = var.aurora_mysql[1].db_parameter_group auto_pause = var.aurora_mysql[1].auto_pause max_capacity = var.aurora_mysql[1].max_capacity min_capacity = var.aurora_mysql[1].min_capacity seconds_until_auto_pause = var.aurora_mysql[1].seconds_until_auto_pause timeout_action = var.aurora_mysql[1].timeout_action # 额外加显式依赖确保源集群完全就绪 depends_on = [module.aurora_mysql_source] }
对应的可以把tfvars中第二个集群的source_cluster_identifier留空,因为已经通过模块引用赋值了。
步骤3:修复模块中的资源定义,等待源集群可恢复
在./modules/aurora_mysql/aurora_mysql.tf中添加数据源校验源集群状态,同时修复scaling_configuration的配置:
# 恢复场景下先查询源集群是否可恢复 data "aws_rds_cluster" "source" { count = var.restore ? 1 : 0 cluster_identifier = var.source_cluster_identifier } resource "aws_rds_cluster" "rds_mysql" { cluster_identifier = var.cluster_identifier engine = var.engine engine_version = var.engine_version engine_mode = var.engine_mode availability_zones = var.availability_zones database_name = var.database_name port = var.db_port master_username = var.master_username master_password = var.master_password backup_retention_period = var.backup_retention_period db_subnet_group_name = var.db_subnet_group_name vpc_security_group_ids = var.vpc_security_group_ids db_cluster_parameter_group_name = var.cluster_parameter_group backtrack_window = var.backtrack_window skip_final_snapshot = var.skip_final_snapshot deletion_protection = var.deletion_protection dynamic "restore_to_point_in_time" { for_each = var.restore == true ? [1] : [] content { # 使用数据源返回的集群ID,确保源集群存在且可恢复 source_cluster_identifier = data.aws_rds_cluster.source[0].id restore_type = var.restore_type use_latest_restorable_time = true } } # 修复scaling_configuration动态块,仅serverless模式下添加 dynamic "scaling_configuration" { for_each = var.engine_mode == "serverless" ? [1] : [] content { auto_pause = var.auto_pause max_capacity = var.max_capacity min_capacity = var.min_capacity seconds_until_auto_pause = var.seconds_until_auto_pause timeout_action = var.timeout_action } } lifecycle { create_before_destroy = false ignore_changes = [ availability_zones ] } }
临时 workaround(如果不想改现有结构)
如果不想调整现有count的结构,可以分两次执行apply:
- 第一次apply只创建源集群:
terraform apply -target=module.aurora_mysql[0] - 等源集群创建完成5-10分钟后,再执行全量apply创建克隆集群。
内容的提问来源于stack exchange,提问作者Abhishek Solanki
相关产品推荐
相关产品推荐

