是否可以“可变化” Terraform 中模块的源路径?

Kil*_*ore 6 terraform terragrunt

是否可以在 Terraform 或 Terragrunt 中使用变量作为模块源。使用 Terragrunt 我知道我们可以将模块源覆盖到本地目录,但它似乎不允许我们使用不同的存储库。

该用例是支持开发存储库和实时存储库。开发人员将使用与生产/实时部署不同的存储库来开发模块。

我熟悉使用 Terragrunt 方法来分离环境。我们可以走这条路线,例如 live 文件夹中的配置将指向一个存储库,而 dev/qa 文件夹中的配置则指向另一个存储库。

代码片段:

module "s3_module" {
  source = "${var.source_url}"
  bucket_name = "thereoncewasakingguardinghisgardenallalone"
}
Run Code Online (Sandbox Code Playgroud)

错误:

下载模块时出错:加载模块时出错:下载'file:///home/vagrant/code/Terraform/Examples/Lab-US-West-1/${var.source_url}'时出错:源路径错误:stat /home/ vagrant/code/Terraform/Examples/Lab-US-West-1/${var.source_url}:没有这样的文件或目录

Mar*_*ins 2

Terraform 不允许像这样改变模块源,因为模块安装发生在期间terraform init,因此必须在评估主代码之前静态地做出所有决定,类似于许多其他语言中依赖项安装的工作方式。

实现为生产自动化提供与其他调用者(例如开发人员)不同的模块视图的目标的另一种方法是使用 Terraform 的本机模块注册表机制及其关联的服务发现协议。

要做到这一点,需要运行一个实现注册表协议的服务,这本质上只是模块源的一个额外的间接层,允许它们由远程服务器决定,而不是在配置中硬编码。如果您的模块注册表正在运行,terraform.example.com那么您的模块源字符串可能如下所示:

module "s3_module" {
  source = "terraform.example.com/any-namespace/s3/aws"

  bucket_name = "thereoncewasakingguardinghisgardenallalone"
}
Run Code Online (Sandbox Code Playgroud)

注册表协议可以返回 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/"
  }
}
Run Code Online (Sandbox Code Playgroud)

完成该 CLI 配置后,Terraform 将进行terraform.example.com不同的解释并使用其他注册表 API,您可以安排它仅选择 AWS S3 存储桶中的打包模块,或者任何其他似乎适合生产的约束。

Terraform Cloud 和 Enterprise 有一个内置的私有模块注册表,但您可以在自己的基础设施上部署任何与相同协议通信的内容,并在正确设置服务发现协议的情况下使用它。HashiCorp 没有可以自己运行的官方私有注册表,但该协议有一些社区实现,并且该协议最重要的部分(列出可用版本并查找下载 URL)非常简单,可以由由 AWS S3 或类似服务提供的静态网站。