如何在 Terraform 中管理本地生成的有状态文件

Posted

技术标签:

【中文标题】如何在 Terraform 中管理本地生成的有状态文件【英文标题】:How to manage locally generated stateful files in Terraform 【发布时间】:2021-12-28 08:11:41 【问题描述】:

我有一个 Terraform (1.0+) 脚本,它根据一些输入从模板生成本地配置文件,例如:

locals 
  config_tpl = templatefile("$path.module/config.tpl", 
    foo = "bar"
  )


resource "local_file" "config" 
  content  = local._config_tpl
  filename = "$path.module/config.yaml"

该文件随后被从local-exec 块运行的后续命令使用,该块又生成本地配置文件:

resource "null_resource" "my_command" 
  provisioner "local-exec" 
    when        = create
    command     = "../scripts/my_command.sh"
    working_dir = "$path.module"
  

  depends_on = [
    local_file.config,
  ]

my_command.sh 生成当前没有可用的 Terraform 提供程序的基础架构。

所有生成的文件都应该构成配置状态的一部分,因为它们在以后的升级过程中需要,最终会破坏环境。

我还想从 CI/CD 管道运行这些脚本,因此您自然希望每次运行时工作区都是干净的,这意味着生成的文件将不存在。

是否有管理此类文件的模式?我最初的想法是创建云存储桶,压缩文件并将它们存储在那里,然后在需要时将它们拉回。然而,这感觉比已经发生的更肮脏,而且似乎有可能遇到依赖问题。

或者,我是否遗漏了一些完全不同的东西来解决诸如此类的问题?

【问题讨论】:

【参考方案1】:

您在这里遇到的问题是the hashicorp/local provider's documentation 中的警告正在讨论的问题:

Terraform 主要处理能够比单次 Terraform 运行更长时间的远程资源,因此本地资源有时会违反它的假设。此处的资源最好谨慎使用,因为根据本地状态,可能难以在许多不同的本地系统上应用相同的 Terraform 配置,而这些本地资源可能无法普遍使用。有关详细信息,请参阅每个资源中的具体说明。

简短而不幸的答案是,您在这里尝试做的不是 Terraform 旨在解决的问题:其目的是管理远程系统中的长期对象,而不是您正在运行的本地工作站上的工件地形。

对于您的config.yaml 文件,您可能会发现使用local_file 的云存储对象资源类型而不是 是一个合适的替代方案,这样Terraform 只会将文件直接写入远程存储,根本不影响本地系统。当然,只有当你打算让 read 这个文件也能够从同一个云存储中读取,或者你可以编写一个单独的胶水脚本来在@987654325 之后获取对象时,这才会有所帮助@已完成。

没有直接的方法可以将配置器的结果视为状态中的持久数据。如果您使用配置器,那么根据定义,它们始终是仅在创建资源期间采取的一次性操作。

【讨论】:

正如我所怀疑的......我想真正的解决方案是要求我提供的服务的维护者开发一流的提供商。谢谢!

以上是关于如何在 Terraform 中管理本地生成的有状态文件的主要内容,如果未能解决你的问题,请参考以下文章

如何从 terraform 状态中删除资源?

Terraform 管理阿里云 VPC

将现有 Azure 资源导入本地 Terraform 状态文件

Terraform:多租户的状态管理

无法使用“terraform init -reconfigure”将 S3 后端中的 Terraform 远程状态转换为本地状态

Terraform状态State管理,让变更有记录