Terraform upgrade and multiple versions.tf,子模块是否继承提供程序版本?

Terraform upgrade and multiple versions.tf,子模块是否继承提供程序版本?,terraform,Terraform,不太熟悉地形。我将我的项目从12个升级到13个,并希望在之后将其升级到14个 如文档所述,我运行了terraform 0.13升级和terraform 0.13升级模块,我的目录如下: terraform ├── module │ ├── main.tf │ └── versions.tf ├── main.tf └── versions.tf 我移动了我的版本,但问题是我只在根版本中指定了它们。tf: terraform { r

不太熟悉地形。我将我的项目从12个升级到13个,并希望在之后将其升级到14个

如文档所述,我运行了
terraform 0.13升级
terraform 0.13升级模块
,我的目录如下:

 terraform
     ├── module
     │   ├── main.tf
     │   └── versions.tf
     ├── main.tf
     └── versions.tf
我移动了我的版本,但问题是我只在根
版本中指定了它们。tf

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 3.8.0"
    }
}
模块/versions.tf中
我只保留了:

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
    }
}
子模块是否从根目录(导入它们的地方)继承版本,或者这是否意味着我的模块将自动使用更新的提供程序版本(我想是3.64)运行

我是否应该简单地删除module/versions.tf?(每次都有两个版本需要编辑,这很烦人)


谢谢

对于给定的Terraform配置(包括根模块和您可能调用的任何其他模块),每个提供程序只能有一个版本。Terraform通过规范化后具有相同的
值来识别两个提供者是“相同的”,在您的示例中,这两个提供者都使用
hashicorp/google
,这是registry.Terraform.io/hashicorp/google的缩写,因此,他们两人都需要能够就提供商要使用的特定版本达成一致

Terraform处理来自多个提供者的版本约束,方法是将它们组合在一起,并尝试将所有这些约束都放在一起。在这里的示例中,您在子模块中没有编写任何
version
参数,这意味着“允许任何版本”

因此,Terraform将寻找一个既符合
~>3.8.0
约束又符合隐含的“任意版本”约束的可用提供商版本,并且由于
~>3.8.0
约束是“任意版本”的适当子集,它实际上优先于子模块中的开放约束。这不是严格意义上的“继承”,但在本例中,它恰好有点像它,因为子模块完全不受约束

一个更有趣的例子是,如果您的两个模块都指定了不同的版本约束,这意味着我们可以看到将它们组合在一起的更有趣的效果。让我们假设您的两个模块具有以下要求:

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 3.8.2"
    }
  }
}
在这种情况下,这两个约束都不是另一个约束的子集,但它们确实有一些重叠:从3.8.5开始的所有3.8.x版本都是两个模块都可以接受的。因此,Terraform将从该集合中选择最新的可用版本

如果您编写的两个模块具有冲突的版本约束,则这将是一个错误:

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 3.7.0"
    }
  }
}

没有同时是3.7.x版本和3.8.x版本的提供程序版本,因此任何版本都不可能同时匹配这两个约束,因此提供程序版本选择将失败。正是出于这个原因,Terraform文档部分建议仅在根模块中使用
~>
版本约束。

我建议您在模块中使用
version.tf
,将模块依赖项版本锁定并在模块中显式定义,将其视为正常的包版本,这样,您只需要在升级或添加功能时更新模块及其提供程序的版本。
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 3.7.0"
    }
  }
}
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 3.8.5"
    }
  }
}