如何阻止 Terraform 删除导入的资源?

How to block Terraform from deleting an imported resource?

我是 Terraform 的新手,所以我确定我遗漏了一些东西,但我找到的答案似乎与我提出的问题不同。

我有一个 AWS VPC/Security 组,我们需要在其中创建我们的 EC2 实例,并且这个 VPC/SG 已经创建。要创建 EC2 实例,Terraform 要求如果我没有默认 VPC,则必须导入我自己的。但是一旦我导入并应用了我的计划,当我想销毁它时,它也会试图销毁我的 VPC。我如何封装我的资源,以便当我 运行 "terraform apply" 时,我可以使用我导入的 VPC 创建一个 EC2 实例,但是当我 运行 "terraform destroy" 我只销毁我的 EC2 实例?

万一有人要提,我明白了:

lifecycle = {
    prevent_destroy = true
}

不是我要找的。

这是我目前的练习代码。

resource "aws_vpc" "my_vpc" {
  cidr_block = "xx.xx.xx.xx/24"
}

provider "aws" {
  region = "us-west-2"
}


data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]
  }

  owners = ["099720109477"] # Canonical
}


resource "aws_instance" "web" {

  ami           = "${data.aws_ami.ubuntu.id}"
  instance_type = "t3.nano"

  vpc_security_group_ids = ["sg-0e27d851dxxxxxxxxxx"]
  subnet_id              = "subnet-0755c2exxxxxxxx"

  tags = {
    Name = "HelloWorld"
  }
}

Terraform 不应要求您部署或导入 VPC 才能将 EC2 实例部署到其中。您应该能够通过 id 引用 VPC、子网和安全组,以便 TF 了解您现有的网络基础设施,就像您已经为 SG 和子网所做的那样。部署 EC2 实例 "aws_instance" 所需要做的就是像您已经做的那样在现有 VPC 中为其提供一个现有子网 ID。为什么说 Terraform 需要部署或导入 VPC?您在没有 VPC 且仅使用现有 VPC 的情况下部署有什么错误或问题?

如果你真的愿意,你可以通过 AWS 保护 VPC,但我认为你不会真的想将 VPC 导入你的 Terraform 状态并让 Terraform 在这里管理它。听起来您希望 VPC 为其他资源提供服务,可能是手动部署的应用程序或通过其他 TF 堆栈,并且 VPC 独立于任何应用程序部署而存在。

要回答原始问题,您可以使用数据源并通过 ID 或标记名称匹配您的 VPC:

data "aws_vpc" "main" {
  tags = {
    Name = "main_vpc"
  }
}

data "aws_vpc" "main" {
  id = "vpc-nnnnnnnn"
}

然后引用它:data.aws_vpc.main

此外,如果您已经包含了您的 VPC,但不想在将其从您的状态中删除时破坏它,您可以使用 terraform state 命令设法做到这一点:https://www.terraform.io/docs/commands/state/index.html