我创建了一些带有main.tf的虚拟机,而terraform生成了一个cluster.tfstate文件。
现在由于重构,我将VM资源定义移动到一个模块中,并在main.tf中引用该模块。当我运行terraform apply --state=./cluster.tfstate
时,terraform会破坏并重新创建这些虚拟机吗?
我希望它不会。我的理解是否正确?
答案 0 :(得分:1)
让我们使用the aws_instance documentation中提供的示例来尝试:
# Create a new instance of the latest Ubuntu 14.04 on an
# t2.micro node with an AWS Tag naming it "HelloWorld"
provider "aws" {
region = "us-west-2"
}
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_instance" "web" {
ami = "${data.aws_ami.ubuntu.id}"
instance_type = "t2.micro"
tags {
Name = "HelloWorld"
}
}
如果我们terraform apply
这个,我们会得到一个在Terraform中引用为aws_instance.web
的实例:
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
如果我们将此定义移动到模块ubuntu_instance
,则目录结构可能如下所示instance.tf
中的上述代码:
.
├── main.tf
└── ubuntu_instance
└── instance.tf
现在你打算创建与以前相同的实例,但内部Terraform现在命名此资源module.ubuntu_instance.aws_instance.web
如果您尝试应用此功能,您将获得以下信息:
Plan: 1 to add, 0 to change, 1 to destroy.
发生这种情况的原因是Terraform不知道旧代码和新代码引用相同的实例。当您在模块中重构时,您正在删除资源,因此Terraform会删除该资源。
Terraform将您的代码映射到状态文件中的实际资源。创建实例时,由于状态文件,您只能知道该实例映射到aws_instance
。所以正确的方法(如Jun所述)是重构你的代码,然后告诉Terraform将映射移动到真实实例从aws_instance.web
到module.ubuntu_instance.aws_instance.web
然后当你申请时,Terraform会保留实例,因为它与您的代码所说的匹配。 The article Jun linked to is a good discussion of this