【Terraform学习】Terraform管理资源生命周期(Terraform配置语言学习)

阻止资源删除

  • 若要防止对特定资源执行销毁操作,可以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"
    }
##...

你可能感兴趣的:(terraform,terraform,学习,云原生)