Terraform 不允许像这样改变模块源,因为模块安装发生在过程中terraform init
,因此必须在评估主代码之前静态地做出所有决定,类似于在许多其他语言中依赖项安装的工作方式。
实现生产自动化与其他调用者(例如开发人员)不同的模块视图的目标的另一种方法是使用 Terraform 的本机模块注册机制及其相关的服务发现协议。
要做到这一点,需要运行一个实现注册协议的服务,这本质上只是对模块源的额外间接层,允许它们由远程服务器决定,而不是在配置中硬编码。如果您的模块注册表正在运行,terraform.example.com
那么您的模块源字符串可能如下所示:
module "s3_module" {
source = "terraform.example.com/any-namespace/s3/aws"
bucket_name = "thereoncewasakingguardinghisgardenallalone"
}
注册表协议可以返回 Terraform 支持的任何类型的模块源地址,包括git::
git 存储库。因此,您可以设置注册表,使上述模块地址指向一个普通的 Git 存储库,以便于开发人员。
默认情况下,Terraform 将使用其服务发现协议来查找terraform.example.com
. 您应该设置主要的服务发现文档以引用将在生产之外使用的注册表,以避免在每个开发人员的系统上进行手动配置。
在您的生产系统中——可能 Terraform 以某种自动化方式运行——您可以使用CLI 配置设置来覆盖发现terraform.example.com
以指向更适合您的生产环境的不同注册表 API:
# Note that this goes in the _CLI configuration_, which is *not* the
# same thing as the .tf files that describe your infrastructure.
host "terraform.example.com" {
services = {
"modules.v1" = "https://production-terraform.example.com/modules/"
}
}
有了该 CLI 配置,Terraform 将进行terraform.example.com
不同的解释并改用此其他注册表 API,您可以在其中安排它仅选择 AWS S3 存储桶中的打包模块,或任何其他似乎适合生产的约束。
Terraform Cloud 和 Enterprise 有一个内置的私有模块注册表,但是如果您正确设置了服务发现协议,您可以在自己的基础架构上部署任何与相同协议通信的东西,并使用它来代替。HashiCorp 没有您可以自己运行的官方私有注册表,但是该协议有一些社区实现,并且该协议的最重要部分(列出可用版本和查找下载 URL)非常简单,可以由从 AWS S3 或类似网站提供的静态网站。