首页 > 解决方案 > 强制 Terraform 仅从本地磁盘安装提供程序,禁用 Terraform 注册表

问题描述

自 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. 如果未安装给定模块,则返回错误

我将非常感谢为此提供的好建议。有没有我忽略的设置,或者我们可以通过让它看起来空旷的地方来伪造它?是否有 -stay-in-your-lane 开关?

澄清:

更新:这些事情失败了:

$ 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 默认搜索路径中,它似乎确实找到了该位置,但似乎首先/根本检查注册表,这是出乎意料的。

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

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

标签: terraformautomatic-updatesout-of-band

解决方案


您在此处描述的内容听起来像是Terraform 的 CLI 配置文件中提供程序安装设置的意图。

具体来说,您可以将您的提供程序文件放在您选择的本地文件系统目录中——为了这个示例,我将任意选择/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. 由于您不会在本地目录中拥有它,因此安装会失败,但是知道该提供程序现在已发布在hashicorp/vsphere我们可以通过在状态中手动迁移它来避免这种情况,从而避免需要 Terraform 推断这一点自动在下一个terraform apply

terraform state replace-provider 'registry.terraform.io/-/vsphere' 'registry.terraform.io/hashicorp/vsphere'

运行此命令后,您的最新状态快照将不再与 Terraform 0.12 兼容,因此如果您选择中止升级并返回到 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 的默认安装行为(没有任何特殊配置)与 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这里假设XDG Base Directory 规范中的默认数据目录之一,但如果您的系统上有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。您可以获得更彻底的行为,即从不使用我打开此答案的配置(根本不包含direct {}块)联系远程注册表。


推荐阅读