如何在不销毁`aws_ebs_volume`(作为独立资源)的情况下执行`terraform destroy`以销毁`aws_instance`

50次阅读
没有评论

问题描述

在使用Terraform配置了一个单独的aws_instanceaws_ebs_volumeaws_volume_attachment资源集,它们分别命名为foo。用户想要执行terraform destroy -target=aws_instance.foo以销毁aws_instance.foo,但不希望Terraform同时销毁aws_ebs_volume.foo。然而,Terraform生成的计划(plan)显示会同时销毁aws_ebs_volume.foo,即使该卷的块设备在AWS控制台上标记为“Delete on termination”为false
用户尝试了terraform destroy -target=aws_volume_attachment.foo以及将aws_volume_attachment从配置中删除后先执行terraform apply,然后再执行terraform destroy -target=aws_instance.foo,但这些尝试都没有成功。
用户希望找到一种方法,能够在销毁aws_instance时保留aws_ebs_volume,以便稍后可以重新连接到新创建的aws_instance上。是否有解决办法?

解决方案

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

方案1

在执行terraform destroy之前,首先使用terraform plan -destroy生成一个目标计划文件(*.plan)。然后,使用该计划文件执行terraform destroy,并针对每个资源(包括aws_instanceaws_ebs_volumeaws_volume_attachment)使用目标选项(-target)进行精确指定。

以下是具体步骤:
1. 首先,使用terraform plan -destroy生成目标计划文件。
bash
terraform plan -destroy \
-target=module.foo.aws_volume_attachment.dev-sdb-attachments[0] \
-target=module.foo.aws_volume_attachment.dev-sdf-attachments[0] \
-target=module.foo.aws_volume_attachment.dev-sdg-attachments[0] \
-target=module.foo.aws_instance.foo[0] \
-target=module.foo.aws_iam_instance_profile.foo[0] \
-out=intermediate.plan

这将生成一个中间计划文件,其中包含指定的资源和操作。

  1. 接下来,使用terraform destroy执行销毁操作,并指定目标计划文件。
    bash
    terraform destroy -target=module.foo.aws_volume_attachment.dev-sdb-attachments[0] \
    -target=module.foo.aws_volume_attachment.dev-sdf-attachments[0] \
    -target=module.foo.aws_volume_attachment.dev-sdg-attachments[0] \
    -target=module.foo.aws_instance.foo[0] \
    -target=module.foo.aws_iam_instance_profile.foo[0] \
    intermediate.plan

    使用-target选项确保只销毁指定的资源。

如果你需要自动化执行此操作,可以在terraform destroy命令中添加-auto-approve标志以避免交互式提示。

方案2

另一种解决方案是,在销毁之前创建卷的快照(snapshot)。快照可以在卷被删除后保留数据,并且可以在需要时重新创建卷。

在执行terraform destroy之前,执行以下步骤:
1. 创建aws_ebs_snapshot资源,针对所需的aws_ebs_volume生成快照。
2. 在销毁操作之前,移除aws_ebs_volume的相关配置,以防止其被销毁。
3. 执行terraform apply以应用更改并创建快照。
4. 最后,执行terraform destroy以销毁aws_instance和其他资源。

这样,快照将保留aws_ebs_volume的数据,以便稍后重新连接到新创建的aws_instance上。

请注意,这种方法需要手动管理快照和重新连接卷的过程。具体的操作和脚本可能需要根据你的需求和实际情况进行调整。

正文完