You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform编写CloudFront模块时origin_config变量默认值不兼容报错如何解决?

问题原因

Terraform 对变量的类型校验优先级远高于变量值加载逻辑:

  • 你定义的 origin_config 是固定结构的 object 类型,其中明确声明了 domain_name 是必填的 string 属性,未标记为可选。
  • Terraform 会在加载 tfvars、环境变量等外部传入的变量值之前,先校验变量的默认值是否完全匹配类型约束。你的默认值缺少必填的 domain_name 字段,校验直接失败,根本走不到读取 tfvars 的步骤,并非 tfvars 配置未被读取。
解决方案

根据你使用的 Terraform 版本选择对应方案即可:

方案1:使用 optional 修饰符(推荐,Terraform v0.14 及以上版本支持)

将 object 中不需要用户必填的属性标记为 optional,可以直接在修饰符中指定默认值,用户仅需传入必填的 domain_name 即可,Terraform 会自动补全其他属性的默认值:

variable "origin_config" {
  type = object({
    domain_name      = string          # 必填属性,用户必须传入
    protocol_policy  = optional(string, "https-only") # 可选,默认值为 https-only
    ssl_protocol     = optional(list(string), ["TLSv1.2"])
    http_port        = optional(number, 80)
    https_port       = optional(number, 443)
  })
  # 无需再写 default 块,可选属性已自带默认值
}

注意:如果使用 Terraform v0.14 ~ v1.2 版本,需要先在根模块的 Terraform 配置中启用实验特性:

terraform {
  experiments = [module_variable_optional_attrs]
}

Terraform v1.3 及以上版本 optional 已正式 GA,不需要额外配置。

方案2:兼容旧版本 Terraform

如果你的 Terraform 版本低于 0.14 不支持 optional,可以用以下两种方式处理:

方式A:补全默认值占位

在变量默认值中补一个无意义的 domain_name 占位值,用户在 tfvars 中传入的 origin_config 会完整覆盖默认值,占位值不会实际生效:

variable "origin_config" {
  type = object({
    domain_name = string
    protocol_policy = string
    ssl_protocol = list(string)
    http_port = number
    https_port = number
    })
  default = {
     domain_name = "placeholder.example.com" # 新增占位默认值,会被用户传入值覆盖
     protocol_policy = "https-only"
     ssl_protocol = ["TLSv1.2"]
     http_port = 80
     https_port = 443
  }
}

方式B:手动合并默认值

如果不想要求用户传入所有属性,可以调整变量类型为 map,通过本地值合并默认配置和用户配置:

# variables.tf
variable "origin_config" {
  type = map(any)
  default = {}
}

# 本地值合并配置
locals {
  origin_config_default = {
    protocol_policy = "https-only"
    ssl_protocol = ["TLSv1.2"]
    http_port = 80
    https_port = 443
  }
  origin_config = merge(local.origin_config_default, var.origin_config)
}

修改 CloudFront 资源中的引用为本地值即可:

resource "aws_cloudfront_distribution" "this" {
  origin {
    domain_name = local.origin_config.domain_name
    origin_id   = local.origin_id
    custom_origin_config  {
        origin_protocol_policy = local.origin_config.protocol_policy
        origin_ssl_protocols = local.origin_config.ssl_protocol
        http_port = local.origin_config.http_port
        https_port = local.origin_config.https_port
    }
  }
}

内容的提问来源于stack exchange,提问作者yossarian2004

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 08:36:04