【问题标题】:how do you prevent terraform from upgrading a provider?您如何防止 terraform 升级提供程序?
【发布时间】:2021-11-04 19:26:53
【问题描述】:

您如何防止 terraform 升级其提供程序?

我已经构建了一个安装了 terraform 1.0.5 和特定版本的 aws 提供程序的 docker 映像:

# terraform -version
Terraform v1.0.5
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v3.55.0

我用这个简单的 docker 文件构建了这个 terraform docker 镜像:

FROM hashicorp/terraform:1.0.5 as terraform-provider

COPY provider.tf .

RUN terraform init

RUN mv .terraform/providers/registry.terraform.io/hashicorp/aws/3.55.0/linux_amd64/* /bin/

docker build 所需的 provider.tf 在这里:

terraform {
  required_providers {
    aws = {
      version = "3.55.0"
      source = "hashicorp/aws"
    }
  }
}

当我针对本地 terraform 代码运行此 docker 映像时,terraform init 命令坚持将 aws 提供程序升级到最新版本。

这是我的运行方式:

TERRAFORM_BASE_IMAGE 是我刚刚通过 docker build . 构建的 terraform 图像

我在$CURRENT_DIR/terraform/ 文件夹中有一个 main.tf,其中仅包含:

terraform {
  backend "s3" {}
}

provider "aws" {
  default_tags {
    tags = {
      Owner = "foo@example.com"
      Description = "Demo"
    }
  }

}

当我运行命令时:

docker run -v $CURRENT_DIR:$CURRENT_DIR --workdir $CURRENT_DIR/terraform \
${TERRAFORM_BASE_IMAGE} \
init -get=false \
     -reconfigure \
     -backend-config="bucket=XXX-tf-remote-state" \
     -backend-config="key=${ENVIRONMENT}/${PROJECT_NAME}" \
     -backend-config="region=us-west-2" \
     -backend=true

我在输出中看到:

Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v3.57.0...
- Installed hashicorp/aws v3.57.0 (signed by HashiCorp)

我根本不希望 terraform 升级任何提供程序。 docker 镜像已经有 3.55.0 版本的 aws 提供程序。

如何防止terraform init 升级任何提供程序?

【问题讨论】:

    标签: docker terraform


    【解决方案1】:

    我认为您的问题中有两个相关的问题:

    • 如何使 Terraform在本地目录中查找以查找提供程序。
    • 如何锁定 Terraform 以仅使用特定的提供程序版本。

    无需特殊配置,Terraform 将遵循Implied Local Mirror Directories 过程,搜索每个隐含目录以查看安装了哪些提供程序。然后,它的行为就像您在 CLI 配置中编写了一个 provider_installation 块,该块将任何本地可用的提供程序排除在直接安装之外。

    例如,如果您的容器映像中的/usr/local/share/terraform/plugins 下至少有一个hashicorp/aws 版本,Terraform 将推断出a provider installation configuration,就像您以这种方式配置它一样:

    provider_installation {
      filesystem_mirror {
        # The contents of this directory must match one of
        # the two supported directory layouts, described in
        # the documentation:
        # https://www.terraform.io/docs/cli/config/config-file.html#filesystem_mirror
        path    = "/usr/local/share/terraform/plugins"
        include = ["hashicorp/aws"]
      }
      direct {
        exclude = ["hashicorp/aws"]
      }
    }
    

    上述配置的一个结果——从“直接”安装方法中排除了hashicorp/aws——Terraform 将只能找到您已经安装在给定目录中的该提供程序的插件包。即使注册表中有更新的版本,Terraform 的提供程序安装程序也不会知道它,因为它根本不会询问注册表。

    但是,此隐含策略并不排除您在本地镜像目录中还没有的提供程序。如果你想强制 Terraform从不在网络上安装新的提供者——即使是你尚未包含的提供者——你可以编写更严格的配置并将你的图像构建过程放在 @ 987654323@:

    provider_installation {
      filesystem_mirror {
        path = "/usr/local/share/terraform/plugins"
      }
      # note: no "direct" here at all, so the normal registry
      # installer is totally deactivated
    }
    

    以上内容可能足以满足您的需求,因为实际上它创建了一个封闭的插件环境,Terraform 只能选择您已包含在图像中的包。即使 Terraform 配置根本没有版本限制,Terraform 也只能选择映像中可用的最新版本。

    但是,Terraform 的 provider requirementsdependency lock file 机制在这种情况下仍然适用,因此如果您的配置选择了未包含在映像中的版本,那么 terraform init 将由于无法而失败解决依赖关系。

    您可能会认为这是一种优势,在这种情况下问题就解决了。

    如果您希望容器镜像成为使用哪个提供程序版本的唯一决定者,那么编写您的 Terraform 配置时仅使用最少的版本约束并从您的版本控制中排除依赖锁定文件可能是合理的这样 Terraform 就不会尝试将可用包与先前记录的校验和进行匹配。在您的情况下,您的容器映像可以有效替代依赖锁定文件通常提供的保证,只要您的构建映像过程以某种方式确保您包含的提供程序包都是值得信赖。

    【讨论】:

      猜你喜欢
      • 2019-06-06
      • 1970-01-01
      • 2022-08-08
      • 2020-05-16
      • 2021-02-04
      • 2022-07-08
      • 1970-01-01
      • 2018-12-14
      • 2021-03-14
      相关资源
      最近更新 更多