解决方案:
我在尝试对一个RDS实例(不是AWS Aurora下的)执行destroy
时遇到了同样的问题,但原则是相同的。
以下是我采取的一些步骤来解决这个问题:
将 skip_final_snapshot
更改为 true
并删除 final_snapshot_identifier
(如果存在)
(参见下面的注释#1和#2)。
删除 backup_window
(在AWS Aurora下,它可能被称为 preferred_backup_window
)。
将 backup_retention_period
更改为 0
。
确保将 apply_immediately
设置为 true
(参见下面的注释#3)。
运行 terraform apply
并检查所影响的更改(参见下面的提示#4)。
现在,您可以运行 terraform destroy
,并且不应出现任何错误(在我的情况下,我添加了 deletion_protection
设置为 true
并将其删除)。
评论 #1 - 理解相关字段的目的
来自Terraform文档:
skip_final_snapshot
- (可选)确定在删除DB实例之前是否创建最终的DB快照。如果指定为true
,则不会创建DBSnapshot。如果指定为false
,则将使用final_snapshot_identifier
中的值在删除DB实例之前创建一个DB快照。默认值为false
。
final_snapshot_identifier
- (可选)当删除此DB实例时,您的最终DB快照的名称。如果将skip_final_snapshot
设置为false
,则必须提供此名称。
在问题中指定的代码中,skip_final_snapshot
是true
,但仍然指定了final_snapshot_identifier
。
(*) 不要与snapshot_identifier
字段混淆。
评论 #2 - 是什么导致了这个错误?
对于那些想要了解一些背景的人,可以在提到的开放问题中看到一个很好的讨论串,其中有一个贡献者@caiges给出了一个很好的解释:
首先,
skip_final_snapshot
默认为
False
,这也应该需要设置
final_snapshot_identifier
,但实际上并没有这样做,所以会发生这样的情况:创建/更新被应用,状态被更新,其中
skip_final_snapshot
为
False
,但是
final_snapshot_identifier
为
null
。
这会导致销毁操作在验证阶段失败。
这个问题可以解决,但对于那些已经存在预设状态的人来说,我没有一个很好的解决方案。
一种可能的方法是,如果标识符为 null,则删除操作忽略
skip_final_snapshot
。
另一种可能是,如果将
skip_final_snapshot
设置为或默认为 False,则将
final_snapshot_identifier
默认为某些随机值。
我认为出于数据安全原因,如果
final_snapshot_identifier
为 null,则忽略
skip_final_snapshot
是一个不好的主意,最好只是随机生成一个标识符。
评论 #3 - 确保我们的更改立即生效:
关于 apply_immediately
的说明来自Terraform文档:
注意:使用 apply_immediately 可能会导致服务器重新启动而出现短暂的停机时间。有关更多信息,请参阅 AWS RDS 维护文档。
注释 #4(奖励)- 节省时间:
当您运行terraform plan
时,请确保〜
(就地更新符号)出现在Terraform执行计划下的相关字段中-在下面的示例中,您可以看到将应用2个更改:
~ resource "aws_db_instance" "postgresql" {
address = ...
allocated_storage = 100
allow_major_version_upgrade = false
.
.
~ apply_immediately = false -> true
.
.
~ backup_retention_period = 7 -> 0
.
.
tags = ...
username = ...
vpc_security_group_ids = ...
}
这个问题听起来可能很琐碎,但在像这样的错误情况下,当您尝试理解为什么某些更新没有发生时,它可以节省大量的调试时间。