跳至主要内容

OpenTofu 1.8 新特性

本页面将引导您了解 OpenTofu 1.8 中最重要的更改

早期变量/局部变量评估

此功能允许您使用变量和局部变量用于 **后端**、**模块源** 和 **加密配置**,只要它们不依赖于资源、数据源或模块输出。例如,即使局部变量引用了一个变量,此功能也适用。这只是一系列改进中的第一步,这些改进将使 .tf 代码更加灵活,未来版本将带来更多改进。

tofu init 命令现在将使用您的 .tfvars 文件,并允许您使用 -var-var-file 选项指定变量。请注意,此 Alpha 版本 *不会* 提示您输入缺少的变量,此功能将在稍后添加。请注意,如果缺少静态评估所需的变量,tofu init 将失败。

例如,如果您希望对 S3 后端和 AWS 提供程序使用相同的配置,您现在可以这样做

代码块
variable "aws_region" {
default = "us-east-1"
}

terraform {
backend "s3" {
region = var.aws_region
}
}

provider "aws" {
region = var.aws_region
}

您还可以使用此功能来管理模块版本,包括注册表引用和 Git URL。

代码块
locals {
aws_module_version = "5.6.1"
}

module "webserver" {
source = "terraform-aws-modules/ec2-instance/aws"
version = local.aws_module_version

// Other ec2_instance options
}

module "db" {
source = "https://github.com/terraform-aws-modules/terraform-aws-ec2-instance?ref=v${local.aws_module_version}"

// Other ec2_instance options
}

最后,以下是如何使用变量设置使用密码短语的加密

代码块
variable "passphrase" {
type = string
}

terraform {
encryption {
key_provider "pbkdf2" "my_passphrase" {
passphrase = var.passphrase
}

method "aes_gcm" "my_method" {
keys = key_provider.pbkdf2.my_passphrase
}

state {
method = method.aes_gcm.my_method
}
}
}

tofu test 中模拟提供程序

基于现有的覆盖特定数据源、资源和模块调用的能力,tofu test 现在支持模拟整个提供程序定义。此新功能允许您基于每个提供程序自动生成资源和数据源的模拟值。例如,考虑以下在 AWS 上启动 m6i.2xlarge 实例的代码

代码块
provider "aws" {
region = "us-east-1"
}

data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-24.04-amd64-server-*"]
}
owners = ["099720109477"]
}

resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "m6i.2xlarge"
}

无需查询 AMI ID 并启动实例,我们可以编写如下测试代码

代码块
// This block will prevent OpenTofu from configuring aws provider.
// All provider's resources and data sources will be mocked.
mock_provider "aws" {
mock_data "aws_ami" {
defaults = {
id = "ami-12345"
}
}
}

run "test" {
assert {
condition = aws_instance.web.ami == "ami-12345"
error_message = "Incorrect AMI ID passed to aws_instance.web: ${aws_instance.web.ami}"
}
}

虽然这不会完全测试整个供应过程,但它将突出显示可能由资源错误连接导致的错误,而无需实际的 AWS 账户。

tofu test 中覆盖资源

您现在可以从测试中覆盖资源、数据源和整个模块,从而允许您创建类似于传统软件测试中模拟的行为。例如,考虑以下在 AWS 上启动 m6i.2xlarge 实例的代码

代码块
provider "aws" {
region = "us-east-1"
}

data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-24.04-amd64-server-*"]
}
owners = ["099720109477"]
}

resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "m6i.2xlarge"
}

无需查询 AMI ID 并启动实例,我们可以编写如下测试代码

代码块
provider "aws" {
access_key = "foo"
secret_key = "bar"

skip_credentials_validation = true
skip_region_validation = true
skip_metadata_api_check = true
skip_requesting_account_id = true
}

# This block disables refreshing the aws_ami.ubuntu data source
# and lets you manually specify the values:
override_data {
target = data.aws_ami.ubuntu
values = {
id = "ami-12345"
}
}

run "test" {
# This block disables provisioning the aws_instance.web resource:
override_resource {
target = aws_instance.web
values = {
# You can add values here.
}
}

assert {
condition = aws_instance.web.ami == "ami-12345"
error_message = "Incorrect AMI ID passed to aws_instance.web: ${aws_instance.web.ami}"
}
}

虽然这不会完全测试整个供应过程,但它将突出显示可能由资源错误连接导致的错误,而无需实际的 AWS 账户。同样,您可以使用 override_module 覆盖整个模块。

OpenTofu 的覆盖文件:保持兼容性

由于我们现在正在为 OpenTofu 添加 Terraform 中不存在的功能,因此我们希望为模块作者提供编写适用于 OpenTofu 和 Terraform 的代码的能力,而无需维护两个模块副本。您现在可以创建名为 .tofu 的文件,这些文件专用于 OpenTofu。如果您创建了一个名为 foo.tofu 的文件,OpenTofu 将忽略同名文件 foo.tf。您可以使用此功能将 Terraform 特定的代码放在 .tf 文件中,然后在 .tofu 文件中将其覆盖为 OpenTofu。

以下替换文件可用

  • foo.tffoo.tofu
  • foo.tf.jsonfoo.tofu.json
  • foo.tftest.hclfoo.tofutest.hcl
  • foo.tftest.jsonfoo.tofutest.json
  • foo_override.tffoo_override.tofu
  • foo_override.tf.jsonfoo_override.tofu.json

您仍然可以使用 .tf 扩展名编写所有代码,此功能旨在用于希望为 OpenTofu 和 Terraform 提供兼容代码并在使用新 OpenTofu 功能时提供兼容代码的模块作者。

错误修复、改进和弃用

弃用:S3 后端已移除 use_legacy_workflow

use_legacy_workflow 选项现已从 S3 后端配置中移除。

其他改进

  • 机器可读的 UI 文档现在包含 tofu test -json 类型。
  • tofu plan 现在在使用 generate-config-out 时生成 jsonencode()
  • 状态持久化间隔现在可以通过 TF_STATE_PERSIST_INTERVAL 环境变量进行配置。
  • 使用紧凑的 JSON 编码提高了写入状态文件和减少状态文件大小的性能。
  • 您现在可以在测试文件的 variables 块内引用变量。
  • 提供程序函数现在包含在 tofu providers schema 命令中。

错误修复

  • 修复了加密配置中 enforced 标志的验证问题。(#1711
  • 修复了在使用某些命令时 gcs 后端崩溃的问题。(#1618
  • 修复了由于缺少结构体字段导致的 inmem 后端崩溃问题。(#1619
  • tofu test 中添加了一个检查,以验证测试运行块的名称不包含空格。(#1489
  • tofu test 现在支持在模块没有资源时访问模块输出。(#1409
  • 修复了测试中对提供程序函数的支持 (#1603)
  • 仅在对一组资源进行计划时隐藏计划详细信息中的敏感属性 (#1313)

  • 为 `for_each` 块添加了更好的错误消息,该块包含类型不合适的敏感值。(#1485)
  • 修复了 gcs 后端锁定中的竞争条件 (#1342)
  • 修复了变量和输出中无法使用提供程序函数的错误 (#1689)
  • 修复了 S3 后端不再支持小写 `http_proxy` / `https_proxy` 环境变量的错误 (#1594)
  • 修复了版本之间迁移时,即使不需要更改也会导致资源就地更新的问题。(#1640)
  • 为“功能块不足”错误添加源上下文 (#1777)
  • 从自动完成中删除加密诊断 (#1793)
  • 确保使用敏感路径作为模板文件时不会出现 panic(#1801)