如何处理 terraform 进程崩溃并避免重试时资源泄漏?

Posted

技术标签:

【中文标题】如何处理 terraform 进程崩溃并避免重试时资源泄漏?【英文标题】:How to handle terraform process crash and avoid the resource leak on retry? 【发布时间】:2021-12-07 14:03:44 【问题描述】:

我在 docker 容器中部署了一个微服务,用于管理和执行 terraform commads 以在 AWS 上创建基础设施。支持的terraform模板如下:

provider "aws" 
  profile = "default"
  region  = "us-east-1"



resource "aws_default_vpc" "default" 
  tags = 
    Name = "Default VPC"
  


resource "aws_security_group" "se_security_group" 
  name        = "test-sg"
  description = "secure soft edge ports"
  vpc_id      = aws_default_vpc.default.id

  tags = 
    Name = "test-sg"
  



resource "aws_instance" "web" 
  ami           = "ami-*********"
  instance_type = "t3.micro"

  tags = 
    Name = "test"
  
  
   depends_on = [
    aws_security_group.se_security_group,
  ]


有了这个系统,当 terraform 进程正在执行(创建 EC2 实例)时,如果 docker 容器崩溃,那么状态文件将没有关于正在创建的 EC2 资源的条目。在容器重启时,如果 terraform 进程在同一个状态文件上重启,最终会创建一个全新的 EC2 实例,从而导致资源泄漏。

    terraform 中的崩溃场景通常如何处理? 有没有办法在状态文件没有 EC2 条目的情况下回滚之前的事务?

请帮我解决这个问题。谢谢

【问题讨论】:

这通常不会自动处理,因为它不会发生(经常发生)。如果 terraform 崩溃,需要手动处理状态文件和创建的资源,删除资源或将其导入状态。 如果 terraform 使用身份验证令牌访问状态并且令牌在申请中途过期,它也可能崩溃。我经常遇到这种情况。 【参考方案1】:

terraform中的crash场景一般是如何处理的?

这取决于崩溃发生的时间。一些可能的情况是:

    很可能,只要您的后端支持锁定,您的状态文件就会保持锁定状态。在这种情况下,重启后不会创建任何内容,因为 Terraform 无法获取状态文件的锁,因此会抛出错误。我们将不得不强制解锁状态。 我们设法解锁了状态文件/状态文件根本不是小盒。在这种情况下,我们可能需要以下场景:
状态文件将包含一个带有资源标识符的条目,即使资源配置时发生崩溃也是如此。在这种情况下,Terraform 将刷新状态,并在需要进行任何更改时显示在计划中。不过,我们应该先阅读计划并决定是要应用还是先进行一些手动调整。 Terraform 无法识别已存在的资源,因此它会尝试配置它。同样,我们应该阅读状态文件并决定自己要做什么。我们可以导入已经存在的资源,也可以终止它并让 Terraform 尝试再次创建它。

有没有办法在状态文件没有 EC2 条目的情况下回滚之前的事务?

不,没有办法回滚到上一个事务。 Terraform 将尝试配置 .tf 文件中的任何内容。我们可以做的是从我们的源代码管理中签出以前版本的代码并应用它。

【讨论】:

观察到,在实验中发生崩溃的情况下,之前配置的资源没有记录在状态文件中。重新尝试时,terraform 最终会再次创建相同的资源,从而产生 2 个资源。例如:考虑到 terraform 正在创建一个发生崩溃的 EC2 实例。据观察,在重新触发 terraform 命令时,正在创建具有相同名称的新 EC 实例,从而导致存在 2 个实例

以上是关于如何处理 terraform 进程崩溃并避免重试时资源泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

tvOS:如何处理 TabBar 和 UICollectionView 之间的焦点更改并防止崩溃

如何处理死锁

如何处理崩溃日志?

如何处理 WM_ERASEBKGND 避免闪烁?

如何处理锁(JPA)?

Linux 中的 SEH 等效项或如何处理操作系统信号(如 SIGSERV)并继续