Terraform v1.0.0发布后,terraform-bundle的开发已经结束,需要寻找替代方法
背景的解释
Terraform自版本0.10开始引入了基于插件的架构,当执行terraform init时,从外部注册表中安装Provider成为了规范。由于这个规范,当组织或地区的防火墙无法访问外部注册表时,就无法使用Terraform,这就产生了一个问题。为了解决这个问题,我们开发了与Terraform CLI独立的terraform-bundle。
为了解决上述问题,在v0.13中,Terraform CLI还提供了从本地文件系统中安装Provider的功能。此外,还提供了类似于terraform-bundle的功能的terraform providers mirror命令。借助这些功能,Terraform CLI能够独自解决最初的问题,因此terraform-bundle的开发已经结束,并从v1.0.0的发布中移除。
terraform-bundle的文档中提到可以使用terraform-bundle,并参考以往的版本,但由于开发已经终止,因此可以理解为已不推荐使用。另一方面,文档中也提到正在使用Terraform Enterprise作为Terraform Cloud的自托管分发方式的用户仍然可以使用terraform-bundle来构建自己的Terraform包。因此,我对Terraform Enterprise的用户来说,依然是一个有用的工具。有关更详细的信息,请参阅在Terraform Enterprise中安装捆绑的内容。
从terraform-bundle切换到替代方案
在这里,我们将介绍如何使用 terraform providers mirror 命令来创建与 terraform-bundle 生成的捆绑压缩文件等效的文件。
土壤供应商镜像命令
Terraform Providers Mirror 命令是一个从当前配置中下载所需的 Provider 并保存到本地文件系统的命令。此外,生成的目录结构将按照 <主机名>/<命名空间>/<类型>/terraform-provider-<类型>_<版本>_<目标>.zip 的形式创建,可以立即使用 filesystem_mirror 方式来指定这个目录作为 Provider 的安装方式。
$ terraform --version
Terraform v1.0.2
on darwin_amd64
$ terraform providers mirror --help
Usage: terraform [global options] providers mirror [options] <target-dir>
Populates a local directory with copies of the provider plugins needed for
the current configuration, so that the directory can be used either directly
as a filesystem mirror or as the basis for a network mirror and thus obtain
those providers without access to their origin registries in future.
The mirror directory will contain JSON index files that can be published
along with the mirrored packages on a static HTTP file server to produce
a network mirror. Those index files will be ignored if the directory is
used instead as a local filesystem mirror.
Options:
-platform=os_arch Choose which target platform to build a mirror for.
By default Terraform will obtain plugin packages
suitable for the platform where you run this command.
Use this flag multiple times to include packages for
multiple target systems.
Target names consist of an operating system and a CPU
architecture. For example, "linux_amd64" selects the
Linux operating system running on an AMD64 or x86_64
CPU. Each provider is available only for a limited
set of target platforms.
创建与bundle archive相等的东西。
在这里,我们将使用terraform providers mirror命令创建一个与打包的bundle archive中的Terraform CLI v1.0.2和AWS Provider v3.49.0等效的东西。
$ unzip terraform_1.0.2-bundle2021071506_darwin_amd64.zip
$ tree .
.
├── plugins
│ └── registry.terraform.io
│ └── hashicorp
│ └── aws
│ └── 3.49.0
│ └── darwin_amd64
│ └── terraform-provider-aws_v3.49.0_x5
└── terraform
$ ./terraform --version
Terraform v1.0.2
on darwin_amd64
请准备一个要求安装 AWS Provider v3.49.0 的 main.tf 文件。
terraform {
required_version = "= 1.0.2"
required_providers {
aws = {
source = "hashicorp/aws"
version = "= 3.49.0"
}
}
}
请指定一个下载 Provider 的目录,并执行 terraform providers mirror 命令。默认情况下,该命令会根据执行命令的主机操作系统和 CPU 架构下载可执行的 Provider。根据需求,您可以添加类似于 -platform=linux_amd64 的选项。
$ terraform --version
Terraform v1.0.2
on darwin_amd64
$ terraform providers mirror plugins
- Mirroring hashicorp/aws...
- Selected v3.49.0 to meet constraints 3.49.0
- Downloading package for darwin_amd64...
- Package authenticated: signed by HashiCorp
Provider已根据在main.tf中设置的内容进行下载。
$ tree plugins
plugins
└── registry.terraform.io
└── hashicorp
└── aws
├── 3.49.0.json
├── index.json
└── terraform-provider-aws_3.49.0_darwin_amd64.zip
3 directories, 3 files
terraform-provider-aws_3.49.0_darwin_amd64.zip 是将提供者二进制文件压缩为ZIP格式的文件。
$ zipinfo plugins/registry.terraform.io/hashicorp/aws/terraform-provider-aws_3.49.0_darwin_amd64.zip
Archive: plugins/registry.terraform.io/hashicorp/aws/terraform-provider-aws_3.49.0_darwin_amd64.zip
Zip file size: 43084802 bytes, number of entries: 1
-rwxr-xr-x 3.0 unx 213013632 bx defN 21-Jul-09 06:37 terraform-provider-aws_v3.49.0_x5
1 file, 213013632 bytes uncompressed, 43084586 bytes compressed: 79.8%
与Provider一起生成的JSON文件对于实施Provider网络镜像协议非常有用,本文与此无关,因此省略了详细说明。
$ cat plugins/registry.terraform.io/hashicorp/aws/3.49.0.json
{
"archives": {
"darwin_amd64": {
"hashes": [
"h1:klBcGkbCZhDo95eRUz1c0Sj1J97RNfSceZLzbwaFVaQ="
],
"url": "terraform-provider-aws_3.49.0_darwin_amd64.zip"
}
}
}
$ cat plugins/registry.terraform.io/hashicorp/aws/index.json
{
"versions": {
"3.49.0": {}
}
}
从https://www.terraform.io/downloads.html提供的URL下载Terraform CLI。虽然本次设定了版本,操作系统和CPU架构,但如果要重复使用所介绍的方法,请根据需求进行修改。
$ wget https://releases.hashicorp.com/terraform/1.0.2/terraform_1.0.2_darwin_amd64.zip
$ unzip terraform_1.0.2_darwin_amd64.zip
$ ./terraform --version
Terraform v1.0.2
on darwin_amd64
由於Terraform CLI和提供程序已經下載完畢,我們將它們打包成一個ZIP文件。
$ ls -l
total 157992
-rw-r--r-- 1 ryysud staff 149B Jul 15 15:28 main.tf
drwxr-xr-x 3 ryysud staff 96B Jul 15 15:56 plugins
-rwxr-xr-x 1 ryysud staff 77M Jul 8 02:46 terraform
$ zip -r bundle_archive.zip terraform plugins
adding: terraform (deflated 59%)
adding: plugins/ (stored 0%)
adding: plugins/registry.terraform.io/ (stored 0%)
adding: plugins/registry.terraform.io/hashicorp/ (stored 0%)
adding: plugins/registry.terraform.io/hashicorp/aws/ (stored 0%)
adding: plugins/registry.terraform.io/hashicorp/aws/terraform-provider-aws_3.49.0_darwin_amd64.zip (stored 0%)
adding: plugins/registry.terraform.io/hashicorp/aws/3.49.0.json (deflated 24%)
adding: plugins/registry.terraform.io/hashicorp/aws/index.json (deflated 10%)
$ ls -l bundle_archive.zip
-rw-r--r-- 1 ryysud staff 73M Jul 15 16:00 bundle_archive.zip
由于创建了与bundle archive相等的东西,我们将进行差异确认。
# bundle archive
$ zipinfo terraform_1.0.2-bundle2021071506_darwin_amd64.zip
Archive: terraform_1.0.2-bundle2021071506_darwin_amd64.zip
Zip file size: 77860750 bytes, number of entries: 2
-rwxr-xr-x 2.0 unx 213013632 bX defN 21-Jul-15 15:24 plugins/registry.terraform.io/hashicorp/aws/3.49.0/darwin_amd64/terraform-provider-aws_v3.49.0_x5
-rwxr-xr-x 2.0 unx 80886784 bX defN 21-Jul-15 15:24 terraform
2 files, 293900416 bytes uncompressed, 77860296 bytes compressed: 73.5%
# 今回作成したもの
$ zipinfo bundle_archive.zip
Archive: bundle_archive.zip
Zip file size: 76586882 bytes, number of entries: 8
-rwxr-xr-x 3.0 unx 80886784 bx defN 21-Jul-08 02:46 terraform
drwxr-xr-x 3.0 unx 0 bx stor 21-Jul-15 15:56 plugins/
drwxr-xr-x 3.0 unx 0 bx stor 21-Jul-15 15:30 plugins/registry.terraform.io/
drwxr-xr-x 3.0 unx 0 bx stor 21-Jul-15 15:30 plugins/registry.terraform.io/hashicorp/
drwxr-xr-x 3.0 unx 0 bx stor 21-Jul-15 15:30 plugins/registry.terraform.io/hashicorp/aws/
-rw-r--r-- 3.0 unx 43084802 bx stor 21-Jul-15 15:30 plugins/registry.terraform.io/hashicorp/aws/terraform-provider-aws_3.49.0_darwin_amd64.zip
-rw-r--r-- 3.0 unx 198 tx defN 21-Jul-15 15:30 plugins/registry.terraform.io/hashicorp/aws/3.49.0.json
-rw-r--r-- 3.0 unx 40 tx defN 21-Jul-15 15:30 plugins/registry.terraform.io/hashicorp/aws/index.json
由于目录结构不同,可以看出它们不会以相同方式工作,但是bundle archive在提供程序二进制文件上的目录结构是 ////,而terraform providers mirror命令在提供程序二进制文件上将其压缩成ZIP并放置在 ///terraform-provider-__.zip 这个目录结构中,这仅是为了遵循 filesystem_mirror 安装提供程序的方式的规范,并且在功能上没有任何差异。
从以下内容可以看出,使用terraform提供商镜像命令创建的内容是有效的。
$ unzip bundle_archive.zip
Archive: bundle_archive.zip
inflating: terraform
creating: plugins/
creating: plugins/registry.terraform.io/
creating: plugins/registry.terraform.io/hashicorp/
creating: plugins/registry.terraform.io/hashicorp/aws/
extracting: plugins/registry.terraform.io/hashicorp/aws/terraform-provider-aws_3.49.0_darwin_amd64.zip
inflating: plugins/registry.terraform.io/hashicorp/aws/3.49.0.json
inflating: plugins/registry.terraform.io/hashicorp/aws/index.json
$ ls -l
total 322544
-rw-r--r-- 1 ryysud staff 73M Jul 15 16:00 bundle_archive.zip
-rw-r--r-- 1 ryysud staff 149B Jul 15 15:28 main.tf
drwxr-xr-x 3 ryysud staff 96B Jul 15 15:56 plugins
-rwxr-xr-x 1 ryysud staff 77M Jul 8 02:46 terraform
$ ./terraform --version
Terraform v1.0.2
on darwin_amd64
$ ./terraform init -plugin-dir plugins
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "3.49.0"...
- Installing hashicorp/aws v3.49.0...
- Installed hashicorp/aws v3.49.0 (unauthenticated)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
总结
本次介绍了一个替代 Terraform v1.0.0 中已开发完毕的 terraform-bundle 的方法。
虽然这是一个很小众的内容,但如果能对您有所帮助就是我的幸福了。
有關資料参考
https://github.com/hashicorp/terraform/tree/43f698dc9db36b722f3d60a7d6aca9b757c2e621/tools/terraform-bundle
2021-07-14 時点の main ブランチ
– [Terraform v0.11 更新日志](https://github.com/hashicorp/terraform/blob/v0.11/CHANGELOG.md#0100-august-2-2017)
– [Terraform 升级指南 0.10](https://www.terraform.io/upgrade-guides/0-10.html)
– 使用 terraform-bundle 打包必要的 Terraform 执行文件
– 理解 Terraform 中提供程序安装过程的详细信息(2021年2月版)
– [Terraform 提供程序镜像命令](https://www.terraform.io/docs/cli/commands/providers/mirror.html)
– 除了修复影响 Terraform Enterprise 用户的紧急 Bugfix,今后将不再进行维护(详见 hashicorp/terraform#29069)。