【问题标题】:Is there a "terraform" or "meta" terraform provider?是否有“地形”或“元”地形提供者?
【发布时间】:2020-06-05 08:15:45
【问题描述】:

是否有可以管理 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


    【解决方案1】:

    您可能对Terragrunt 感兴趣,它是 Terraform 的包装器,可让您创建模块之间的依赖关系并最大限度地减少重复代码。使用 Terragrunt,您可以一次执行多个模块,但仍保持状态分离。您还可以在 Terraform 运行之前和之后执行挂钩,并且可以轻松地使用多个 AWS 账户。有关演示,请参阅 this repo

    【讨论】:

      【解决方案2】:

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

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

      对于您将系统分解为多个单独的 Terraform 配置的情况,the provider named 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 目前无法让提供者发出需要“替换”对象的一个​​嵌套部分的信号,因此提供者要么需要将其建模为销毁,然后重新创建整个配置,要么将其呈现为更新,但是然后无论如何在内部默默地替换对象。这些听起来都不适合日常使用。

      【讨论】:

      • 感谢马丁,内容丰富的回复。所以是的 - 一些根的原因肯定是你所描述的,通常被称为减少爆炸半径。常规的日常基础设施管理将涉及对需要更改的特定根进行应用。我们还使用 terraform 提供者的远程状态数据对象在根之间传递依赖信息(例如,从核心到服务部署根的子网 ID)。回应提出此问题的用例:DR 或重新配置完整平台生态系统(例如创建新环境)
      • “如果我想以自动方式重新创建一个在 TF 根中定义的面向服务的完整平台,是否有本地 TF 提供商可以帮助我做到这一点?”可能是更好地表达问题的一种方式。非 TF 替代方案将包括 CI 管道或 bash 脚本
      猜你喜欢
      • 1970-01-01
      • 2011-07-31
      • 1970-01-01
      • 1970-01-01
      • 2011-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多