Terraform多次执行apply未新建EC2实例的原因咨询
我首次学习使用Terraform,完成「输出变量」配置后两次执行terraform apply,结果没有创建新的EC2实例,而是直接返回已有运行实例的详情。想知道Terraform是怎么识别到已有实例的?
执行结果
> terraform apply aws_instance.my_rhel9_vm: Refreshing state... [id=i-04778c232e988be09] No changes. Your infrastructure matches the configuration. Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed. Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: instance_id = "i-04778c232e988be09" public_ip = "18.212.217.57" > terraform apply aws_instance.my_rhel9_vm: Refreshing state... [id=i-04778c232e988be09] No changes. Your infrastructure matches the configuration. Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed. Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: instance_id = "i-04778c232e988be09" public_ip = "18.212.217.57"
我的配置文件
provider.tf
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.27.0" } } }
main.tf
resource "aws_instance" "my_rhel9_vm" { ami = var.ami //RHEL 9 AMI instance_type = var.type tags = { Name = var.name_tag } }
variables.tf
variable "ami" { type = string description = "RHEL 9 AMI ID in US-East-1" default = "ami-05a5f6298acdb05b6" } variable "type" { type = string description = "Instance Type" default = "t2.micro" } variable "name_tag" { type = string description = "Name of the EC2 instance" default = "My EC2 RHEL 9 instance" } output "public_ip" { value = aws_instance.my_vm.public_ip description = "Public IP Address of EC2 instance" } output "instance_id" { value = aws_instance.my_vm.id description = "Instance ID" } #locals { # ami = "ami-05a5f6298acdb05b6" # type = "t2.micro" # name_tag = "My EC2 RHEL 9 instance" #}
核心是Terraform的状态文件:Terraform会自动生成并维护
terraform.tfstate文件,第一次执行apply创建EC2实例后,这个文件会完整记录该实例的ID、配置参数、实际资源属性等关键信息。每次执行apply时,Terraform第一步就是刷新状态(对应你看到的aws_instance.my_rhel9_vm: Refreshing state...日志),它会同时对比状态文件的记录和云环境中的实际资源,再检查你的配置文件是否有变更。配置、状态、实际资源完全匹配:你的
main.tf里定义的aws_instance.my_rhel9_vm资源,所有参数(AMI、实例类型、标签)都和状态文件记录、AWS上实际运行的实例完全一致,因此Terraform判定不需要创建新实例,也不需要修改现有实例,直接输出已有的实例详情。资源身份的绑定逻辑:Terraform通过资源的唯一地址(比如
aws_instance.my_rhel9_vm)来关联状态文件记录和实际资源,而非依赖标签或其他属性。只要这个资源地址对应的状态记录存在,且实际资源与配置匹配,就不会重复创建资源。
另外注意:你variables.tf里的输出配置存在笔误——输出引用的是aws_instance.my_vm,但main.tf里的资源名称是my_rhel9_vm,不过从执行结果看你应该是修正过这个问题才正常运行的。
内容的提问来源于stack exchange,提问作者Dan

