跳至主要内容

模块块

模块是用于将多个资源组合在一起的容器。

每个 OpenTofu 配置至少包含一个模块,称为根模块,它包含在主工作目录中 .tf.tofu 文件中定义的资源。

模块可以调用其他模块,这使您能够以简洁的方式将子模块的资源包含到配置中。模块也可以多次调用,无论是在同一配置中还是在不同的配置中,从而允许资源配置进行打包和重复使用。

本页介绍了如何从另一个模块中调用模块。有关创建可重用子模块的更多信息,请参见 模块开发

调用子模块

调用模块意味着使用其 输入变量 的特定值将该模块的内容包含到配置中。模块使用 module 块从其他模块中调用。

代码块
module "servers" {
source = "./app-cluster"

servers = 5
}

包含这样 module 块的模块是子模块的调用模块

module 关键字之后的标签是本地名称,调用模块可以使用它来引用该模块的实例。

在块主体({} 之间)是模块的参数。模块调用使用以下类型的参数

  • source 参数对于所有模块都是必需的。

  • 建议从注册表中使用模块时使用 version 参数。

  • 大多数其他参数对应于模块定义的 输入变量。(上面的示例中的 servers 参数就是其中之一。)

  • OpenTofu 定义了几个其他元参数,这些元参数可与所有模块一起使用,包括 for_eachdepends_on

所有模块都需要一个 source 参数,它是由 OpenTofu 定义的元参数。它的值要么是包含模块配置文件的本地目录的路径,要么是 OpenTofu 应该下载并使用的远程模块源。有关此参数的可能值的更多信息,请参见 模块源

可以在多个 module 块中指定相同的源地址,以创建定义在其中的资源的多个副本,可能具有不同的变量值。

在添加、删除或修改 module 块后,您必须重新运行 tofu init 以允许 OpenTofu有机会调整已安装的模块。默认情况下,此命令不会升级已安装的模块;使用 -upgrade 选项改为升级到最新可用版本。

版本

当使用从模块注册表安装的模块时,我们建议明确约束可接受的版本号,以避免意外或不希望的更改。

module 块中使用 version 参数来指定版本

代码块
module "consul" {
source = "hashicorp/consul/aws"
version = "0.0.5"

servers = 3
}

version 参数接受 版本约束字符串。OpenTofu 将使用满足约束的最新安装的模块版本;如果没有安装可接受的版本,它将下载满足约束的最新版本。

版本约束仅适用于从模块注册表安装的模块,例如 公共 OpenTofu 注册表 或任何 TACOS(TF 自动化和协作软件)私有模块注册表。其他模块源可以在源字符串本身内提供自己的版本控制机制,或者根本不支持版本。特别是,从本地文件路径获取的模块不支持 version;由于它们是从相同的源存储库加载的,因此它们始终与调用者共享相同的版本。

元参数

除了 sourceversion 之外,OpenTofu 还定义了几个其他可选元参数,这些参数在所有模块中都有特殊含义,在以下页面中进行了更详细的说明

  • count - 从单个 module 块创建模块的多个实例。有关详细信息,请参见 count 页面

  • for_each - 从单个 module 块创建模块的多个实例。有关详细信息,请参见 for_each 页面

  • providers - 将提供者配置传递给子模块。有关详细信息,请参见 providers 页面。如果未指定,子模块将从调用模块继承所有默认(未别名)提供者配置。

  • depends_on - 在整个模块和列出的目标之间创建显式依赖关系。有关详细信息,请参见 depends_on 页面

OpenTofu 不使用 lifecycle 参数。但是,lifecycle 块为将来的版本保留。

访问模块输出值

在模块中定义的资源是封装的,因此调用模块无法直接访问它们的属性。但是,子模块可以声明 输出值 以选择性地导出某些值供调用模块访问。

例如,如果上面的示例中引用的 ./app-cluster 模块导出了名为 instance_ids 的输出值,则调用模块可以使用表达式 module.servers.instance_ids 来引用该结果。

代码块
resource "aws_elb" "example" {
# ...

instances = module.servers.instance_ids
}

有关引用命名值的更多信息,请参见 表达式

将资源状态转移到模块中

resource 块从一个模块移动到几个子模块中会导致 OpenTofu 将新位置视为完全不同的资源。结果,OpenTofu 计划销毁旧地址上的所有资源实例,并在新地址上创建新实例。

为了保留现有对象,您可以使用重构块来记录每个资源实例的旧地址和新地址。 这将指示 OpenTofu 将旧地址处的现有对象视为最初在相应的新地址处创建的对象。

在模块中替换资源

您可能有一个需要用新对象替换的对象,其原因对于 OpenTofu 来说并不自动可见,例如,如果特定虚拟机在性能下降的基础硬件上运行。 在这种情况下,您可以使用-replace=... 计划选项强制 OpenTofu 提出替换该对象的建议。

如果该对象属于嵌套模块中的资源,请指定该资源的完整路径,包括指向该资源的所有嵌套模块步骤。 例如

代码块
$ tofu plan -replace=module.example.aws_instance.example

以上选择了在根模块中声明的 module "example" 子模块内声明的 resource "aws_instance" "example"

由于替换是一种非常破坏性的操作,因此 OpenTofu 仅允许选择单个资源实例。 没有语法可以强制替换属于特定模块的所有资源实例。