阻止资源删除
若要防止对特定资源执行销毁操作,可以将
prevent_destroy
该属性添加到资源定义中。此生命周期选项可防止 Terraform 意外删除关键资源。
prevent_destroy
添加到您的 EC2 实例。
resource "aws_instance" "example" { ami = data.aws_ami.ubuntu.id instance_type = "t2.micro" vpc_security_group_ids = [aws_security_group.sg_web.id] user_data = <<-EOF #!/bin/bash apt-get update apt-get install -y apache2 sed -i -e 's/80/8080/' /etc/apache2/ports.conf echo "Hello World" > /var/www/html/index.html systemctl restart apache2 EOF tags = { Name = "terraform-learn-state-ec2" drift_example = "v1" } + lifecycle { + prevent_destroy = true + } }
运行销毁命令以观察行为。
terraform destroy
aws_security_group.sg_web: Refreshing state... [id=sg-0c9b526ba6f89d910] aws_instance.example: Refreshing state... [id=i-099bb19ca402a6761] ╷ │ Error: Instance cannot be destroyed │ │ on main.tf line 31: │ 31: resource "aws_instance" "example" { │ │ Resource aws_instance.example has lifecycle.prevent_destroy set, but the │ plan calls for this resource to be destroyed. To avoid this error and │ continue with the plan, either disable lifecycle.prevent_destroy or reduce │ the scope of the plan using the -target flag.
在对属性的更改会强制替换并造成停机的情况下,该属性非常有用。
在资源被销毁之前创建资源
对于可能导致停机但必须发生的更改,请在销毁旧资源之前使用
create_before_destroy
该属性创建新资源。更新安全组规则以允许端口访问 。
resource "aws_security_group" "sg_web" { name = "sg_web" ingress { - from_port = "8080" + from_port = "80" - to_port = "8080" + to_port = "80" protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ## ... }
通过添加属性
create_before_destroy
并更新 VM 使其在端口80上运行,更新 EC2 实例以反映此更改。
resource "aws_instance" "example" { ami = data.aws_ami.ubuntu.id instance_type = "t2.micro" vpc_security_group_ids = [aws_security_group.sg_web.id] user_data = <<-EOF #!/bin/bash apt-get update apt-get install -y apache2 - sed -i -e 's/80/8080/' /etc/apache2/ports.conf echo "Hello World" > /var/www/html/index.html systemctl restart apache2 EOF tags = { Name = "terraform-learn-state-ec2" Drift_example = "v1" } lifecycle { - prevent_destroy = true + create_before_destroy = true } }
运行并观察强制替换的更改。
terraform apply
aws_security_group.sg_web: Refreshing state... [id=sg-0c9b526ba6f89d910] aws_instance.example: Refreshing state... [id=i-099bb19ca402a6761] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: ~ update in-place +/- create replacement and then destroy Terraform will perform the following actions: # aws_instance.example must be replaced +/- resource "aws_instance" "example" { ##... # aws_security_group.sg_web will be updated in-place ~ resource "aws_security_group" "sg_web" { id = "sg-0c9b526ba6f89d910" ##... Plan: 1 to add, 1 to change, 1 to destroy. Changes to Outputs: ~ instance_id = "i-099bb19ca402a6761" -> (known after apply) ~ public_ip = "3.138.139.170" -> (known after apply) Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes aws_security_group.sg_web: Modifying... [id=sg-0c9b526ba6f89d910] aws_security_group.sg_web: Still modifying... [id=sg-0c9b526ba6f89d910, 10s elapsed] aws_security_group.sg_web: Still modifying... [id=sg-0c9b526ba6f89d910, 20s elapsed] aws_security_group.sg_web: Modifications complete after 22s [id=sg-0c9b526ba6f89d910] aws_instance.example: Creating… aws_instance.example: Creation complete after 1m14s [id=i-0b2fd8a0df19c215d] aws_instance.example (940b3833): Destroying... [id=i-099bb19ca402a6761] aws_instance.example: Destruction complete after 41s Apply complete! Resources: 1 added, 1 changed, 1 destroyed. Outputs: instance_id = "i-0b2fd8a0df19c215d" public_ip = "18.116.49.153"
忽略更改
对于不应影响 Terraform 操作的 Terraform 工作流外部的更改,请使用
ignore_changes
该参数。更新 AWS CLI 中的标签。
aws ec2 create-tags --resources $(terraform output -raw instance_id) --tags Key=drift_example,Value=v2
将属性
ignore_changes
添加到 EC2 实例中的lifecycle
块。
resource "aws_instance" "example" { ##... lifecycle { create_before_destroy = true + ignore_changes = [tags] } }
应用将刷新您的状态文件,而不是按照配置中所述覆盖您的标签。
terraform apply
aws_security_group.sg_web: Refreshing state... [id=sg-0c9b526ba6f89d910] aws_instance.example: Refreshing state... [id=i-0b2fd8a0df19c215d] Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: instance_id = "i-0b2fd8a0df19c215d" public_ip = "18.116.49.153"
检查状态文件中的实例,以确认您的标签是否更改。
terraform state show aws_instance.example
##... # aws_instance.example: resource "aws_instance" "example" { tags = { "Name" = "terraform-learn-state-ec2" "drift_example" = "v2" } ##...