跳至主要内容

提供商要求

OpenTofu 依靠称为“提供商”的插件来与远程系统交互。OpenTofu 配置必须声明它们需要的提供商,以便 OpenTofu 可以安装和使用它们。本页介绍如何声明提供商,以便 OpenTofu 可以安装它们。

此外,一些提供商在使用前需要配置(例如端点 URL 或云区域)。提供商配置 页面介绍如何为提供商配置设置。

要求提供商

每个模块都必须声明它需要的提供商,以便 OpenTofu 可以安装和使用它们。提供商要求在 required_providers 块中声明。

提供商要求包括本地名称、源位置和版本约束。

代码块
terraform {
required_providers {
mycloud = {
source = "mycorp/mycloud"
version = "~> 1.0"
}
}
}

required_providers 块必须嵌套在顶层的 terraform 中(该块还可以包含其他设置)。

required_providers 块中的每个参数都会启用一个提供商。键决定提供商的 本地名称(它在本模块中的唯一标识符),而值是一个包含以下元素的对象

  • source - 您打算使用的提供商的全局 源地址,例如 hashicorp/aws

  • version - 一个 版本约束,指定模块兼容的可用提供商版本子集。

名称和地址

每个提供商都有两个标识符

  • 一个唯一的 源地址,仅在要求提供商时使用。
  • 一个 本地名称,在模块中的其他任何地方都使用。

本地名称

本地名称是特定于模块的,并且是在要求提供商时分配的。本地名称必须在每个模块中都是唯一的。

required_providers 块之外,OpenTofu 配置始终通过本地名称引用提供商。例如,以下配置将 mycloud 声明为 mycorp/mycloud 的本地名称,然后在 配置提供商 时使用该本地名称

代码块
terraform {
required_providers {
mycloud = {
source = "mycorp/mycloud"
version = "~> 1.0"
}
}
}

provider "mycloud" {
# ...
}

提供商的用户可以选择任何本地名称。但是,几乎每个提供商都有一个 首选本地名称,它用作其所有资源类型的名称前缀。(例如,来自 hashicorp/aws 的资源都以 aws 开头,例如 aws_instanceaws_security_group。)

只要有可能,您都应该使用提供商的首选本地名称。这使您的配置更容易理解,并且可以让您从大多数资源中省略 provider 元参数。(如果资源没有指定要使用哪个提供商配置,OpenTofu 将资源类型的第一个词解释为本地提供商名称。)

源地址

提供商的源地址是其全局标识符。它还指定了 OpenTofu 可以下载它的主要位置。

源地址由三个用斜杠 (/) 分隔的部分组成,如下所示

[<HOSTNAME>/]<NAMESPACE>/<TYPE>

  • 主机名(可选):分发提供商的注册表的主机名。如果省略,则默认为 registry.opentofu.org

  • 命名空间:指定注册表中的一个组织命名空间。在大多数情况下,它表示发布提供商的组织。此字段可能对其他注册表主机具有其他含义。

  • 类型:提供商管理的平台或系统的简短名称。在特定注册表主机上的特定命名空间中必须是唯一的。

    类型通常是提供商的首选本地名称。(有一些例外;例如,hashicorp/google-betahashicorp/google 的另一个发布通道,因此其首选本地名称是 google。如果有疑问,请查看提供商的文档。)

例如,官方 HTTP 提供商 属于 registry.opentofu.org 上的 hashicorp 命名空间,因此其源地址是 registry.opentofu.org/hashicorp/http 或更常见的是,只是 hashicorp/http

具有所有三个显式给出的组件的源地址称为提供商的 完全限定地址。您将在各种输出(如错误消息)中看到完全限定地址,但在大多数情况下,会使用简化的显示版本。当源主机是公共注册表时,此显示版本会省略源主机,因此您可能会看到缩短的版本 "hashicorp/random" 而不是 "registry.opentofu.org/hashicorp/random"

处理本地名称冲突

只要有可能,我们建议使用提供商的首选本地名称,该名称通常与其源地址的“类型”部分相同。

但是,有时需要在同一个模块中使用两个具有相同首选本地名称的提供商,通常是当提供商以通用的基础设施类型命名时。OpenTofu 要求每个模块中的每个提供商都有唯一的本地名称,因此您需要为其中至少一个提供商使用非首选名称。

当这种情况发生时,我们建议将每个提供商的命名空间与其类型名称组合起来,以生成带有连字符的复合本地名称

代码块
terraform {
required_providers {
# In the rare situation of using two providers that
# have the same type name -- "http" in this example --
# use a compound local name to distinguish them.
hashicorp-http = {
source = "hashicorp/http"
version = "~> 2.0"
}
mycorp-http = {
source = "mycorp/http"
version = "~> 1.0"
}
}
}

# References to these providers elsewhere in the
# module will use these compound local names.
provider "mycorp-http" {
# ...
}

data "http" "example" {
provider = hashicorp-http
#...
}

OpenTofu 将无法从其资源类型猜测任何提供商的名称,因此您需要为每个受影响的资源指定 provider 元参数。但是,模块的读者和维护者将能够轻松理解正在发生的事情,避免混淆比避免打字更重要。

版本约束

每个提供者插件都有自己的一套可用版本,允许提供者的功能随着时间的推移而发展。您声明的每个提供者依赖项都应在version参数中给出版本约束,以便 OpenTofu 可以为所有模块兼容的每个提供者选择一个版本。

version参数是可选的;如果省略,OpenTofu 将接受任何版本的提供者作为兼容。但是,我们强烈建议为您的模块所依赖的每个提供者指定版本约束。

为了确保 OpenTofu 始终为给定的配置安装相同的提供者版本,您可以使用 OpenTofu CLI 创建一个依赖项锁定文件 并将其与您的配置一起提交到版本控制中。如果存在锁定文件,OpenTofu CLI 和 TACOS(TF 自动化和协作软件)在安装提供者时都会遵守它。

提供者版本最佳实践

每个模块至少应该声明它已知可用的最小提供者版本,使用>=版本约束语法

代码块
terraform {
required_providers {
mycloud = {
source = "hashicorp/aws"
version = ">= 1.0"
}
}
}

旨在用作配置根目录的模块(即您运行tofu apply的目录)也应该指定它打算使用的最大提供者版本,以避免意外升级到不兼容的新版本。~>运算符是允许版本的最右侧部分增量的一个方便的简写。以下示例使用该运算符来仅允许特定次要版本内的补丁版本

代码块
terraform {
required_providers {
mycloud = {
source = "hashicorp/aws"
version = "~> 1.0.4"
}
}
}

不要在您打算在多个配置中重用的模块中使用~>(或其他最大版本约束),即使您知道该模块与某些较新版本不兼容。这样做有时可以防止错误,但更多情况下会迫使用户在执行例行升级时同时更新多个模块。指定最小版本,记录任何已知的兼容性问题,并让根模块管理最大版本。

内置提供者

大多数提供者都是作为插件单独分发的,但有一个提供者内置于 OpenTofu 本身。此提供者启用了terraform_remote_state 数据源.

由于此提供者内置于 OpenTofu 中,因此您无需在required_providers块中声明它即可使用其功能。但是,为了保持一致性,它确实有一个特殊的提供者源地址,即terraform.io/builtin/terraform。此地址有时可能会出现在 OpenTofu 的错误消息和其他输出中,以便明确地引用内置提供者,而不是类型名称为“tofu”的假设的第三方提供者。

还有一个源地址为hashicorp/terraform的现有提供者,它是现在内置提供者的旧版本。hashicorp/terraform与 OpenTofu 不兼容,不应在required_providers块中声明。

内部提供者

任何人都可以开发和分发自己的提供者。

一些组织开发了自己的提供者来配置专有系统,并希望在未将这些提供者发布到注册表的情况下从 OpenTofu 使用它们。

分发此类提供者的一个选择是通过实施提供者注册表协议来运行内部私有注册表。

仅仅为了分发单个内部提供者而运行一个额外的服务可能不可取,因此 OpenTofu 也支持其他提供者安装方法,包括通过文件系统镜像将提供者插件直接放置在本地文件系统的特定目录中。

所有提供者都必须具有一个源地址,该地址包含(或隐含)注册表的主机名,但该主机名不需要提供实际的注册表服务。对于您打算从本地文件系统目录分发的内部提供者,您可以在组织控制的域中使用任意主机名。

例如,如果您的公司域是example.com,那么您可能选择使用tofu.example.com作为您的占位符主机名,即使该主机名在 DNS 中实际上无法解析。然后,您可以选择任何命名空间和类型,在该主机名下表示您的内部提供者,从而得到一个类似tofu.example.com/examplecorp/ourcloud的源地址

代码块
terraform {
required_providers {
mycloud = {
source = "tofu.example.com/examplecorp/ourcloud"
version = ">= 1.0"
}
}
}

要从本地文件系统安装此提供者的 1.0.0 版本,请选择隐含的本地镜像目录之一,并在其下创建如下目录结构

代码块
tofu.example.com/examplecorp/ourcloud/1.0.0

在该1.0.0目录下,创建一个代表您运行 OpenTofu 的平台的附加目录,例如,对于 AMD64/x64 处理器上的 Linux,创建一个linux_amd64目录,然后将提供者插件可执行文件和任何其他所需文件放置在该目录中。

因此,在 Windows 系统上,提供者插件可执行文件可能位于以下路径

代码块
tofu.example.com/examplecorp/ourcloud/1.0.0/windows_amd64/tofu-provider-ourcloud.exe

如果您稍后决定改用真实的私有提供者注册表,而不是带外分发二进制文件,则可以在tofu.example.com处部署注册表服务器并保留相同的命名空间和类型名称,在这种情况下,您现有的模块将不需要进行任何更改即可使用您的注册表服务器找到相同的提供者。