首页 > 解决方案 > 是否有“地形”或“元”地形提供者?

问题描述

是否有可以管理 terraform 根的提供程序?某种编排将多个根/部署组件映射在一起?

例如,如果我想在 AWS 中创建一个分布式平台,我可能想为配置 VPC、子网、路由等的核心/网络创建一个根。然后是另一个配置 kubernetes 的根。在 ec2/asg / kubernetes / lambda / etc 中运行的许多微服务也可能有自己的根源。对于微服务的常规部署,可以使用单个根来部署服务更新,但是如果我想配置整个平台,是否有可以应用多个具有依赖关系的根的提供程序?

代码可能类似于:

resource "terraform_root" "core" {
  root_location: core/network
}

resource "terraform_root" "kubernetes" {
    depends: [terraform_root.core]
    root_location: git@github.com:myorg/myrepo?ver=1.2.1
    variables : { something }
}

resource "terraform_root" "microservice_x" {
    depends: [terraform_root.kubernetes]
    root_location: some_location
}

如果没有,创建这样的自定义提供程序会是某种与 tf 的反模式吗?有什么顾虑?

标签: terraform

解决方案


使用 Terraform对此进行建模的预期方法是使用 Terraform 模块,它允许您一次管理多个资源集合,同时将它们彼此命名空间。

拥有一个运行 Terraform 子实例的 Terraform 提供程序通常只是使用 Terraform 模块的更复杂的版本。但是,它会有一个显着不同的行为:这些“配置根”中的每一个都有自己的后端,因此有自己的一组状态(每个工作区)。虽然通常建议将您的 Terraform 管理的基础架构拆分为多个状态,但这样做的理由是您可以将它们分开terraform planterraform apply以管理整个堆栈中广泛更改的意外影响的风险。让许多单独的“配置根”由一次运行来管理terraform apply似乎会破坏这一优势,因此只会减少单一配置中模块的影响。

对于您已将系统分解为多个单独的 Terraform 配置的情况,命名的提供程序terraform可以从一个配置的状态中检索输出以在另一个配置中使用,访问控制允许。所以从这个意义上说,有一个“元 Terraform 提供者”,但不是你想要的。


撇开做这样的事情的价值不谈,实现一个封装 Terraform 的 Terraform 提供者在技术上似乎是可行的,如下所示:

  • 当要求提供者创建计划时,运行terraform plan -out=tempfile然后terraform show -json tempfile获取计划的机器可读版本并以某种方式将其合并到提供者的计划响应中。这可能最终会将计划的资源更改显示为代表整个子配置的单个资源上的属性更改,可能像这样:

     ~ resource "terraform_config" "example" {
       ~ resources = {
           ~ "aws_instance.example[0]" = {
                 ami           = "ami-abc123"
               ~ instance_type = "t2.micro" -> "m3.medium"
             }
           ~ "aws_instance.example[1]" = {
                 ami           = "ami-abc123"
               ~ instance_type = "t2.micro" -> "m3.medium"
             }
         }
         root_dir  = "./child_thingy"
         variables = {
           example = "baz"
         }
     }
    
  • 当要求提供者应用更改时,运行terraform apply tempfile以应用更改。为了稳健地做到这一点,我想它需要将保存的二进制计划文件从内部嵌入到terraform plan外部terraform plan结果中,因此可以确保应用正确的计划。

上面确实显示了该模型与 Terraform 模块的内置概念的至少一个明显差异:其他配置的所有更改都将被外部 Terraform 视为对单个资源的更新,而对于模块 Terraform将在顶层显示所有更改。

这里要处理的另一个复杂性是如何处理需要替换资源的嵌套配置中的更改。Terraform 目前无法让提供者发出需要“替换”对象的一个​​嵌套部分的信号,因此提供者要么需要将其建模为销毁,然后重新创建整个配置,要么将其呈现为更新,但是然后无论如何在内部默默地替换对象。这些听起来都不适合日常使用。


推荐阅读