- OpenTofu 语言
- 模块
- 创建模块
- 标准模块结构
标准模块结构
标准模块结构是我们推荐用于在单独的存储库中分发可重用模块的文件和目录布局。OpenTofu 工具旨在理解标准模块结构,并利用该结构生成文档、为模块注册表编制模块索引等。
标准模块结构期望如下所述的布局。此列表可能看起来很长,但除了根模块之外,所有内容都是可选的。大多数模块不需要做任何额外的工作来遵循标准结构。
-
根模块。这是标准模块结构中唯一必需的元素。OpenTofu 文件必须存在于存储库的根目录中。这应该是模块的主要入口点,并且预计是明确的。对于 Consul 模块,根模块设置了一个完整的 Consul 集群。但是,它做出了很多假设,我们预计高级用户将使用特定的嵌套模块来更仔细地控制他们想要的内容。
-
README。根模块和任何嵌套模块都应该有 README 文件。此文件应命名为
README
或README.md
。后者将被视为 Markdown 格式。应该包含模块的描述及其用途。如果您想包含一个关于如何将此模块与其他资源结合使用的示例,请将其放在 类似这样的示例目录中。考虑包含一个可视化图表,描绘模块可能创建的基础设施资源及其关系。README 不需要记录模块的输入或输出,因为工具会自动生成这些内容。如果您要链接到存储库本身中包含的文件或嵌入图像,请使用提交特定的绝对 URL,以便链接将来不会指向资源的错误版本。
-
LICENSE。此模块可用的许可证。如果您要公开发布模块,许多组织在没有明确的许可证的情况下不会采用模块。我们建议始终拥有许可证文件,即使它不是开源许可证。
-
main.tf
、variables.tf
、outputs.tf
。即使它们为空,这些也是最小模块的推荐文件名。main.tf
应该是主要入口点。对于简单的模块,这可能是创建所有资源的地方。对于复杂的模块,资源创建可以拆分为多个文件,但任何嵌套模块调用都应该在主文件中。variables.tf
和outputs.tf
分别应包含变量和输出的声明。 -
变量和输出应具有描述。所有变量和输出都应具有一到两句描述,解释其用途。这用于文档。有关更多详细信息,请参阅 变量配置 和 输出配置 的文档。
-
嵌套模块。嵌套模块应存在于
modules/
子目录下。任何具有README.md
的嵌套模块都被认为可供外部用户使用。如果不存在 README,则认为仅供内部使用。这些纯粹是建议性的;OpenTofu 不会主动拒绝使用内部模块。嵌套模块应该用于将复杂的行为拆分为多个小型模块,高级用户可以仔细选择和使用它们。例如,Consul 模块 有一个用于创建集群的嵌套模块,它与设置必要的 IAM 策略的模块是分开的。这允许用户引入他们自己的 IAM 策略选择。如果根模块包含对嵌套模块的调用,则应使用相对路径,例如
./modules/consul-cluster
,以便 OpenTofu 将其视为属于同一个存储库或包的一部分,而不是再次单独下载它们。如果存储库或包包含多个嵌套模块,则理想情况下,它们应该由调用者 组合,而不是相互直接调用并创建深度嵌套的模块树。
-
示例。模块的使用示例应存在于存储库根目录下的
examples/
子目录中。每个示例都可以有一个 README 来解释示例的目标和用法。子模块的示例也应该放在根examples/
目录中。因为示例通常会被复制到其他存储库中进行自定义,所以任何
module
块都应将其source
设置为外部调用者将使用的地址,而不是相对路径。
下面展示了一个遵循标准结构的最小推荐模块。虽然根模块是唯一必需的元素,但我们建议以下结构作为最小结构。
$ tree minimal-module/
.
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf
下面展示了一个遵循标准结构的完整模块示例。此示例包含所有可选元素,因此它是一个模块可以达到的最复杂形式。
$ tree complete-module/
.
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf
├── ...
├── modules/
│ ├── nestedA/
│ │ ├── README.md
│ │ ├── variables.tf
│ │ ├── main.tf
│ │ ├── outputs.tf
│ ├── nestedB/
│ ├── .../
├── examples/
│ ├── exampleA/
│ │ ├── main.tf
│ ├── exampleB/
│ ├── .../