如何强制删除由损坏模块创建的资源

85次阅读
没有评论

问题描述

在使用Terraform时,创建了一些dns_cname_record资源,但是Terraform DNS提供程序开始抛出错误,如下所示:

Error: update server is not set

用户已经创建了一个错误报告,因为这个错误阻止了他运行任何Terraform命令。这个错误在每个Terraform命令中都会显示,包括plan
现在,用户想要完全清理和摆脱这个DNS模块,以及所有对它的引用。所以他从所有的.tf文件中删除了所有的dns_cname_record资源。但是在状态文件中仍然有一些资源,他想要摆脱它们。

$ terraform show | grep -w dns_cname_record
# dns_cname_record.foo-example: resource "dns_cname_record" "foo-example" {
# dns_cname_record.bar-example: resource "dns_cname_record" "bar-example" {

所以他尝试了强制销毁而不刷新状态,但是也失败了:

$ TF_LOG=trace terraform destroy -target=dns_cname_record.foo-example -force -refresh=false
...
[TRACE] <root>: eval: *terraform.EvalIf
[TRACE] <root>: eval: *terraform.EvalApplyProvisioners
[TRACE] <root>: eval: *terraform.EvalIf
[TRACE] <root>: eval: *terraform.EvalIf
[TRACE] <root>: eval: *terraform.EvalApply
[DEBUG] dns_cname_record.foo-example: applying the planned Delete change
[TRACE] GRPCProvider: ApplyResourceChange
[DEBUG] dns_cname_record.foo-example: apply errored, but we're indicating that via the Error pointer rather than returning it: update server is not set
[TRACE] <root>: eval: *terraform.EvalWriteState
[TRACE] EvalWriteState: writing current state object for dns_cname_record.foo-example
[TRACE] <root>: eval: *terraform.EvalApplyPost
[ERROR] <root>: eval: *terraform.EvalApplyPost, err: update server is not set
[ERROR] <root>: eval: *terraform.EvalSequence, err: update server is not set
[ERROR] <root>: eval: *terraform.EvalOpFilter, err: update server is not set
[TRACE] [walkDestroy] Exiting eval tree: dns_cname_record.foo-example (destroy)
[TRACE] vertex "dns_cname_record.foo-example (destroy)": visit complete
[TRACE] dag/walk: upstream of "dns_cname_record.foo-example (clean up state)" errored, so skipping
[TRACE] dag/walk: upstream of "provider.dns (close)" errored, so skipping
[TRACE] dag/walk: upstream of "meta.count-boundary (EachMode fixup)" errored, so skipping
[TRACE] dag/walk: upstream of "root" errored, so skipping
Error: update server is not set
Releasing state lock. This may take a few moments...
[DEBUG] plugin: plugin process exited: path=~/.terraform/plugins/darwin_amd64/terraform-provider-dns_v2.1.1_x4 pid=76229
[DEBUG] plugin: plugin exited

最后,由于错误,它没有删除无效的条目。
他还尝试删除terraform-provider-dns_v2.1.1_x4二进制模块文件,但是terraform plan对此抱怨,terraform init会再次下载它,问题重复。
是否有比destroy -force -refresh=false更高级的命令来从破坏本地设置的状态文件中摆脱无效的条目?还是我需要手动编辑状态文件?

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

一个解决方法是拉取当前的状态文件,编辑它并将其用作基线。例如:

$ terraform state pull > terraform.tfstate
$ vim terraform.tfstate # 仔细删除无效的条目。
$ python -mjson.tool terraform.tfstate # 验证 JSON。

注意:在Vim中,将光标放在左括号上,按下d%将删除整个组。
然后进行计划和应用:

$ terraform plan -state=terraform.tfstate -refresh=false
$ terraform apply -state=terraform.tfstate -refresh=false

方案2

另一种方法是将本地状态文件拉取、编辑并推送到远程状态:

$ terraform state pull > terraform.tfstate
$ vim terraform.tfstate # 删除无效的条目并增加序列值。
$ terraform state push terraform.tfstate

对于Azure,最好使用terraform-provider-azurerm而不是通用的DNS提供程序(terraform-provider-dns)。

正文完