强制 Terraform 仅从本地磁盘安装提供程序,禁用 Terraform Registry

Force Terraform to install providers from local disk only, disabling Terraform Registry

自 1995 年以来,我们使用了一种更新机制,

虽然我们知道 Terraform 已经开始接触注册表,勇敢地重新发明那个没有任何这些功能的轮子,但我们希望完全禁用它。我们当前的套件仅包含一个插件:

terraform-0.13.0-1.el7.harbottle.x86_64
golang-github-terraform-provider-vsphere-1.13.0-0.1.x86_64

目标是

  1. 从不检查注册表
  2. return 如果没有安装给定的模块则出错

如果您为此提出好的建议,我将不胜感激。有没有我忽略的设置,或者我们可以通过告诉它看起来空的地方来伪造它吗?有“留在你的车道上”的开关吗?

澄清:

更新:这些事情失败了:

$ terraform init -get-plugins=false

Initializing the backend...

Initializing provider plugins...
- Finding latest version of -/vsphere...
- Finding latest version of hashicorp/vsphere...

更新:我还有点不对劲:

rpm -qlp golang-github-terraform-provider-vsphere
/usr/share/terraform/plugins/registry.terraform.io/hashicorp/vsphere/1.14.0/linux_amd64/terraform-provider-vsphere

我觉得我真的很接近。 /usr/share/ 在 XDG 默认搜索路径中,它似乎确实找到了位置,但它似乎检查了注册表 first/at-all,这是意外的。

Initializing provider plugins...
- Finding latest version of hashicorp/vsphere...
- Finding latest version of -/vsphere...
- Installing hashicorp/vsphere v1.14.0...
- Installed hashicorp/vsphere v1.14.0 (unauthenticated)

Error: Failed to query available provider packages

我们确定它会停止检查是否有本地内容,并且默认情况下会这样做吗?我没看错吗?

您在这里描述的内容听起来像 the Provider Installation settings in Terraform's CLI configuration file 的意图。

具体来说,您可以将您的提供程序文件放在您选择的本地文件系统目录中——为了这个例子,我将任意选择 /usr/local/lib/terraform,然后在CLI 配置文件:

provider_installation {
  filesystem_mirror {
    path = "/usr/local/lib/terraform"
  }
}

如果您还没有 CLI 配置文件,可以将其放入文件 ~/.terraformrc

使用上述配置,您的 golang-github-terraform-provider-vsphere-1.13.0-0.1.x86_64 包需要将提供程序的可执行文件放置在以下路径(假设您使用的是 Linux 系统):

/usr/local/lib/terraform/registry.terraform.io/hashicorp/vsphere/1.30.0/linux_amd64/terraform-provider-vsphere_v1.13.0_x4

(上面的文件名是官方 vSphere 提供程序版本中的文件名,但如果您是从源代码自己构建它,那么只要它以 terraform-provider-vsphere 开头,它到底叫什么并不重要.)

您似乎正在完成从 Terraform v0.12 的升级,因此 Terraform 也在尝试安装此提供程序 -/vsphere 的旧版 (un-namespaced) .由于您不会在本地目录中安装它,因此安装会失败,但是知道该提供程序现在发布在 hashicorp/vsphere 上,我们可以通过在状态下手动迁移它来避免这种情况,从而避免需要让 Terraform 在下一个 terraform apply:

时自动推断这一点
terraform state replace-provider 'registry.terraform.io/-/vsphere' 'registry.terraform.io/hashicorp/vsphere'

执行 运行 此命令后,您的最新状态快照将不再与 Terraform 0.12 兼容,因此如果您选择中止升级并 return 到 0.12,您将需要恢复之前的状态来自备份的版本。如果您的状态未存储在自然保留历史版本的位置,获得此类备份的一种方法是 运行 terraform state pull 使用 Terraform 0.12 可执行文件并将结果保存到文件中。 (默认情况下,Terraform 推迟到 terraform apply 才执行此操作,以避免升级状态格式,直到它无论如何都会进行其他更改。)


上面的 provider_installation 配置是一个答案,如果你想让 Terraform 的所有未来使用都如此,这似乎是你的目标,但为了完整起见,我还想注意以下命令如果您只想为 terraform init:

的一次特定调用强制本地目录,则应该以与上述配置的结果相同的方式运行

terraform init -plugin-dir=/usr/local/lib/terraform


由于您似乎是从 Terraform 0.12 升级,您可能还想知道 Terraform 0.13's default installation behavior(没有任何特殊配置)与 Terraform 0.12 相同,只是现在需要一个不同的本地目录结构比以前更能代表层次化的提供者命名空间。 (也就是为了区分hashicorp/vsphere和假设的othernamespace/vsphere。)

具体来说,Terraform 0.13(与 Terraform 0.12 一样)将跳过与远程注册表联系的任何提供程序,它可以在本地文件系统中发现至少一个可用版本。

听起来你的包代表提供者之前放置了一个 terraform-provider-vsphere 可执行文件,Terraform 0.12 可以找到并使用它。您可以通过将可执行文件放在以下位置来使该策略适应 Terraform 0.13:

/usr/local/share/terraform/plugins/registry.terraform.io/hashicorp/vsphere/1.30.0/linux_amd64/terraform-provider-vsphere_v1.13.0_x4

(同样,这里的确切文件名并不重要,只要它以 terraform-provider-vsphere 开头即可。)

/usr/local/share 这里假设来自 the XDG Base Directory specification 的默认数据目录之一,但是如果您在系统上覆盖了 XDG_DATA_HOME/XDG_DATA_DIRS,那么 Terraform 应该尊重它并查看您列出的其他位置。

假设您没有使用显式 provider_installation 块覆盖默认行为,这样一个文件的存在将导致 Terraform 的行为就像您在 CLI 配置中编写了以下内容一样:

provider_installation {
  filesystem_mirror {
    path    = "/usr/local/share/terraform/plugins"
    include = ["hashicorp/vsphere"]
  }
  direct {
    exclude = ["hashicorp/vsphere"]
  }
}

这种形式的配置强制本地安装 hashicorp/vsphere 提供程序,因此模仿了 Terraform 0.12 使用本地插件文件所做的事情 terraform-provider-vsphere.您可以获得更彻底的 never 联系远程注册表的行为,其配置类似于我打开此答案时使用的配置,它根本不包含 direct {} 块。