在Terraform中指定模块位置时使用变量

在Terraform中指定模块位置时使用变量,terraform,Terraform,我正在尝试运行以下代码: locals { terraform_modules_git = "git::ssh://....@vs-ssh.visualstudio.com/v3/...../terraform-modules" terraform_modules_module = "resource_group?ref=v15.0.0" } module "MyModuleCall" { source = &

我正在尝试运行以下代码:

locals {
    terraform_modules_git = "git::ssh://....@vs-ssh.visualstudio.com/v3/...../terraform-modules"
    terraform_modules_module = "resource_group?ref=v15.0.0"
}

module "MyModuleCall" {
    source = "${local.terraform_modules_git}/${local.terraform_modules_module}"
}
我的目标是将所有标记引用合并到一个地方,而不是在我的所有模块中多次复制带有repo名称的长字符串

我得到了这个错误:

Error: Variables not allowed

  on main.tf line 12, in module "MyModuleCall":
  12:   source = "${local.terraform_modules_git}/${local.terraform_modules_module}"

Variables may not be used here.
有人知道他们为什么要设置这个限制吗?使用变量有什么错?
有人看到任何解决方法吗?

您无法动态生成
源代码。您必须显式地对其进行硬编码,如中所述:

此值必须是无模板序列的文本字符串;不允许使用任意表达式


遗憾的是,除了使用前的预处理模板之外,我不知道有什么解决方法。预处理只会找到
源代码,并将其替换为所需的内容。

您无法动态生成
源代码。您必须显式地对其进行硬编码,如中所述:

此值必须是无模板序列的文本字符串;不允许使用任意表达式


遗憾的是,除了使用前的预处理模板之外,我不知道有什么解决方法。预处理只会找到源代码,并将其替换为所需的源代码。

Terraform中的依赖项在执行程序之前是静态处理的,因为运行时需要访问所有涉及的代码(在Terraform的情况下,模块和提供程序)在创建运行时上下文以执行任何代码之前。这与大多数其他编程语言类似,在运行主程序之前,通常使用单独的命令安装依赖项,如
pip install
npm install
go get
。在Terraform的情况下,依赖项安装程序是
Terraform init
,“运行程序”意味着运行
Terraform plan
Terraform apply

因此,Terraform不能也不允许动态构造模块或提供程序源地址。如果您需要从调用模块中指定的地址中提取模块的物理位置和访问方法,那么一个选项是使用a来告诉Terraform如何将本地地址(如
yourcompany.example.com/yourteam/resource group/azure
)映射到Terraform实际用于获取它的更复杂的Git URL


然而,在实践中,大多数团队更喜欢直接指定他们的Git url,因为这样可以简化整个系统,尽管代价是以后很难将模块移动到新位置。这两者之间的一个折衷方案是使用一个提供Terraform注册表服务的托管服务,例如Terraform Cloud,但这当然是以在整个系统中引入另一个可能的故障点为代价的。

Terraform中的依赖项在执行程序之前是静态处理的,因为运行时需要在创建运行时上下文以执行任何代码之前访问所有涉及的代码(在Terraform的情况下,包括模块和提供程序)。这与大多数其他编程语言类似,在运行主程序之前,通常使用单独的命令安装依赖项,如
pip install
npm install
go get
。在Terraform的情况下,依赖项安装程序是
Terraform init
,“运行程序”意味着运行
Terraform plan
Terraform apply

因此,Terraform不能也不允许动态构造模块或提供程序源地址。如果您需要从调用模块中指定的地址中提取模块的物理位置和访问方法,那么一个选项是使用a来告诉Terraform如何将本地地址(如
yourcompany.example.com/yourteam/resource group/azure
)映射到Terraform实际用于获取它的更复杂的Git URL


然而,在实践中,大多数团队更喜欢直接指定他们的Git url,因为这样可以简化整个系统,尽管代价是以后很难将模块移动到新位置。这两者之间的一个折衷方案是使用一个提供Terraform注册表服务的托管服务,例如Terraform Cloud,但这当然是以在整个系统中引入另一个可能的故障点为代价的。

是的。他们应该是更好的程序员。。。语言应该是一种语言……是的。他们应该是更好的程序员。。。语言应该是一种语言1.感谢您的参与。然而所有初级编译器开发人员都知道什么是“常量表达式”。它们是在编译时计算的。我所知道的编程语言都没有这个问题。Terraform看起来是第一个。他们也许应该在亚马逊订购一本关于编译器的书。这应该会有所帮助。不需要从数据源块中获取模块的位置。常量表达式的最简单形式就足够了。在任何情况下,在“terraform init”期间,他们已经完成了完整的解析。在这一点上计算一个常量表达式不是什么大问题。Terraform语言中的常量表达式只包含文字值,而不包含对本地值的引用,因此您在问题中共享了错误。在其他语言中有“const”的概念。通过这种方式,某些内容被显式标记为不可变。Terraform没有这样的东西。但即使不显式地将某些内容标记为const,编译器仍然可以完成它的工作,并了解该值是否会更改。并且,将此属性传播到表达式中。事实上,地形语言没有符号表示常量的概念。感谢参与。然而所有初级编译器开发人员都知道什么是“常量表达式”。它们是在编译时计算的。都不