同时使用 required_providers 和 provider 块的 Terraform

pka*_*mol 3 terraform

我正在阅读terraform指南,其中作者正在使用docker_imagedocker_container资源启动 docker 设置。

在示例代码的main.tf文件包括两个required_providers provider块,如下所示:

terraform {
  required_providers {
    docker = {
      source = "kreuzwerker/docker"
    }
  }
}

provider "docker" {}
Run Code Online (Sandbox Code Playgroud)

为什么两者都需要?

仅通过这一行应该无法terraform理解对docker提供者的需求吗?

provider "docker" {}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ins 29

在考虑 Terraform 提供程序时,需要考虑两个相关概念:提供程序本身以及提供程序的配置。

打个比方,kreuzwerker/docker这里的提供程序有点像您从另一个库导入的类,并为其指定本地名称docker。我将使用伪 JavaScript 语法来使其更加具体:

var docker = require("kreuzwerker/docker");
Run Code Online (Sandbox Code Playgroud)

然而,到目前为止我们所拥有的只是类本身。为了使用它,我们需要创建它的一个实例,在 Terraform 的白话中称为“配置”。再次使用伪 JavaScript 语法:

var dockerInstance = new docker({});
Run Code Online (Sandbox Code Playgroud)

这里的 Terraform 语法显然不如这个伪 JavaScript 形式明确,但我们可以通过向配置中添加提供程序的第二个实例来使区别更加明显,在 Terraform 中,我们通过为其分配一个配置“别名”来实现这一点:

provider "docker" {
  alias = "example"

  host = "ssh://user@remote-host:22"
}
Run Code Online (Sandbox Code Playgroud)

这就像在我们的伪 JavaScript 示例中创建提供者“类”的第二个实例:

var dockerInstance2 = new docker({
  host: 'ssh://user@remote-host:22'
});
Run Code Online (Sandbox Code Playgroud)

显示区别的另一个变体是模块从其调用模块继承提供程序配置。在这种情况下,就好像调用模块隐式地将提供程序配置(实例)传递到模块中,但子模块仍然需要导入提供程序“类”,以便 Terraform 可以看到我们正在讨论的而不是kreuzwerker/docker任何其他可能名为“docker”的提供商。

Terraform 有一些自动的“神奇”行为,试图使更简单的情况变得隐式,但不幸的是,这是以当事情变得更复杂时更难理解正在发生的事情为代价的。提供者和提供者配置是一个特别困难的例子,因为提供者已经使用 Terraform 语言很长时间了,并且该语言的当前版本试图与简单用途保持广泛的向后兼容,同时仍然允许更新的功能就像可以从多个命名空间安装第三方提供商一样。

这里特别令人困惑的假设是,如果您不声明特定的提供程序,Terraform 将创建一个隐式required_providers声明,假设您指的是命名空间中的提供程序hashicorp/,这使得它看起来好像required_providers只适用于第三方提供程序。事实上,这在很大程度上是一种向后兼容机制,因此我建议始终写出required_providers条目,即使对于命名空间中的提供者也是如此hashicorp/,这样经验不足的读者就不需要了解这种特殊的向后兼容性行为。但就您而言,您使用的提供程序无论如何都位于第三方命名空间中,因此该required_providers条目是强制性的。


Mar*_*k B 7

source要提供的需求,因为这不是“官方” HashiCorp供应商之一。在提供者注册表中可能有多个名称为“docker”的提供者,因此source需要提供,以便准确地告诉 Terraform 下载哪个提供者。