Terraform中AppSync解析器与函数重命名的依赖问题求助
问题场景
用Terraform创建关联AppSync函数的解析器时,首次部署可正常运行,但修改Terraform文件里AppSync函数的名称后,执行terraform apply会报错:
Error deleting AppSync Function... BadRequestException: Cannot delete a function which is currently used by a resolver. Resolver type: Test, field: testField
尝试在解析器中加depends_on字段无效;在函数中加指向解析器的depends_on则触发循环依赖错误:
Error: Cycle: module..., module..., module..., ....
根因分析
Terraform默认的资源依赖关系是解析器依赖函数(因为解析器的pipeline_config引用了函数的function_id)。当修改函数名称触发资源替换时,Terraform默认执行顺序是:
- 尝试删除旧的AppSync函数
- 创建新的AppSync函数
- 更新解析器指向新函数
但第一步删除旧函数时,解析器仍在引用它,AWS会直接阻止删除操作,导致报错。手动添加反向depends_on会形成循环依赖(解析器依赖函数,函数又依赖解析器),Terraform无法处理这种循环。
解决方案
给AppSync函数资源添加**create_before_destroy生命周期元参数**,强制Terraform先创建新函数,再更新解析器指向新函数,最后删除旧函数。这样旧函数被删除前,解析器已经不再引用它,就能避开AWS的报错。
修改后的示例代码
resource "aws_appsync_resolver" "TestResolver" { api_id = var.app-sync-id field = "testField" type = "Query" request_template = "{}" response_template = "$util.toJson($context.result)" kind = "PIPELINE" pipeline_config { functions = [ aws_appsync_function.TestFunction.function_id ] } } resource "aws_appsync_function" "TestFunction" { api_id = var.app-sync-id data_source = local.table-name name = "TestFunction" # 修改此名称会触发资源替换 request_mapping_template = <<EOF ...whatever EOF response_mapping_template = <<EOF ...whatever EOF # 配置生命周期,先创建新函数再删除旧函数 lifecycle { create_before_destroy = true } }
额外说明
create_before_destroy会让Terraform在删除旧资源前先创建新资源,确保解析器能先切换到新函数的引用- 此方法适用于任何会触发AppSync函数资源替换的场景(不只是修改名称)
- 要保证AppSync函数的
name在当前API中唯一,AWS不允许同一API下存在同名函数
内容的提问来源于stack exchange,提问作者klaucode

