1.3.1.1. 资源模块(Resource Module)
资源模块用于部署某一种特定的云平台产品或服务(例如,虚拟机、数据库、Blob 存储桶等等),并确保默认配置是符合最佳实践的,包括但不限于:
- 启用可用区(Availability Zones)
- 配置防火墙(Firewall)
- 强制实施云平台推荐的身份验证方式
- 配置共享接口,如 RBAC、资源锁(Locks)、私有终结点(Private Endpoints)等(如果支持的话)
这些模块可能包括与主资源相关的附加资源,例如虚拟机模块可能包括磁盘和网络接口卡(NIC)。然而,资源模块不得部署主资源的外部依赖项,例如虚拟机模块不得创建虚拟网络(vNet)和子网(Subnet)等外部资。
1.3.1.1.1. 适用场景
资源模块是模块化 Terraform 解决方案的中坚力量,理论上,使用 Terraform 管理器基础设施的用户不应该直接创建对应的 resource
块,而是大量使用资源模块进行组装。资源模块适用于需要构建符合 WAF(Well Architected Framework) 最佳实践的定制架构的用户,或用于创建模式模块的用户。
1.3.1.1.2. 高度内聚
就像我们上面举的虚拟机模块的例子,虚拟机资源模块中如果出现 Key Vault、Virtual Network 等资源,将是非常错误的,应将这些资源交给其他资源模块来管理。但是在虚拟机模块中出现 Managed Disk 资源则是合理的,因为 Managed Disk 是虚拟机的一个组成部分。
资源模块中应当包含一个主资源,可以包含多个依附于主资源的子资源。例如:可以包含一个虚拟机资源,以及多个托管磁盘、网络接口。
有时一个资源模块中可能出现多个主资源的 resource
块,例如,AzureRM Provider 中有 azurerm_linux_virtual_machine
和 azurerm_windows_virtual_machine
两种虚拟机资源,对于虚拟机模块,允许同时出现这两种 resource
块,但我们应当为这两个块设置互斥的 for_each
或是 count
条件,确保任意时刻资源模块只会部署二者之一。
1.3.1.1.3. 可配置性的最大化
由于资源模块在最终用户的代码库中应该是扮演了 resource
块的角色,所以我们应尽可能确保资源模块中定义的 resource
的各种属性,都是可以通过模块暴露出的 variable
块进行配置的,因为我们并不能预测或者限制用户将如何配置这些资源,所以我们尽最大的努力确保用户可以构建出他们想要的配置组合。想要手动将所有可配置项都暴露成 variable
块是一件相当耗费时间精力的工作,有时我们可以使用一些工具来帮助我们。
这就要求我们尽量将模块涉及的主资源及其附加资源的所有可配置属性都以 variable
的形式暴露出来,哪怕这意味着用户有可能会构造出不符合最佳实践的配置,比如把数据库暴露在公网上,我们也应该允许用户这样配置。但是允许用户做出不安全的配置的同时,我们也应确保我们提供的 examples
代码是符合最佳实践的,或者说,不应包含已知的不安全实践。(我们会在后续章节中讨论该话题)
读者可以把资源模块理解成专为用户可以最大化自由地构建基础设施所准备的模块,它最大的价值是提前提用户将相关的资源归类在一起,并提供了一些 Provider 无法提供的数据校验、最佳实践应用方面的简化等附加价值。