模块块
模块是用于将多个资源组合在一起的容器。
每个 OpenTofu 配置至少包含一个模块,称为根模块,它包含在主工作目录中 .tf
和 .tofu
文件中定义的资源。
模块可以调用其他模块,这使您能够以简洁的方式将子模块的资源包含到配置中。模块也可以多次调用,无论是在同一配置中还是在不同的配置中,从而允许资源配置进行打包和重复使用。
本页介绍了如何从另一个模块中调用模块。有关创建可重用子模块的更多信息,请参见 模块开发。
调用子模块
调用模块意味着使用其 输入变量 的特定值将该模块的内容包含到配置中。模块使用 module
块从其他模块中调用。
module "servers" {
source = "./app-cluster"
servers = 5
}
包含这样 module
块的模块是子模块的调用模块。
module
关键字之后的标签是本地名称,调用模块可以使用它来引用该模块的实例。
在块主体({
和 }
之间)是模块的参数。模块调用使用以下类型的参数
-
source
参数对于所有模块都是必需的。 -
建议从注册表中使用模块时使用
version
参数。 -
大多数其他参数对应于模块定义的 输入变量。(上面的示例中的
servers
参数就是其中之一。) -
OpenTofu 定义了几个其他元参数,这些元参数可与所有模块一起使用,包括
for_each
和depends_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
;由于它们是从相同的源存储库加载的,因此它们始终与调用者共享相同的版本。
元参数
除了 source
和 version
之外,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 仅允许选择单个资源实例。 没有语法可以强制替换属于特定模块的所有资源实例。