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

Terraform从S3加载JSON文件并注入变量的实现方案问询

Terraform:解析S3存储的模板JSON并注入变量

场景说明

本地模板正常工作

我们有一个包含变量占位符的JSON文件:

// fruits.json
{ 
   "fruits" : 
      {
          "apples": 3,
          "bananas": 4,
          "pears": "${pears}"
      }
} 

本地环境下,使用templatefile函数可以直接注入变量:

# main.tf
variable "pears" {
    type    = number
    default = 2
}

locals { 
      fruits = templatefile("fruits.json", { pears = var.pears })
}

S3存储后的问题

将该JSON文件上传到S3后,通过aws_s3_bucket_object数据源获取内容时,无法直接用templatefile解析占位符,得到的pears字段是字面量${pears},直接替换也无效:

data "aws_s3_bucket_object" "fruits" {
    bucket = "fruits"
    key    = "subdir/fruits.json"
}

locals {    
    data = jsondecode(data.aws_s3_bucket_object.fruits.body)  
}

解决方案

方法1:单占位符用replace直接替换

如果只有少量占位符,直接用replace函数替换后再解析JSON:

data "aws_s3_bucket_object" "fruits" {
    bucket = "fruits"
    key    = "subdir/fruits.json"
}

variable "pears" {
    type    = number
    default = 2
}

locals {
    templated_body = replace(
        data.aws_s3_bucket_object.fruits.body,
        "${pears}",
        tostring(var.pears)
    )
    fruits = jsondecode(local.templated_body)
}

方法2:多占位符用foldl批量替换

如果有多个变量占位符,用foldl遍历变量映射表批量替换:

data "aws_s3_bucket_object" "fruits" {
    bucket = "fruits"
    key    = "subdir/fruits.json"
}

variable "pears" {
    type    = number
    default = 2
}

variable "oranges" {
    type    = number
    default = 5
}

locals {
    var_mapping = {
        pears = tostring(var.pears)
        oranges = tostring(var.oranges)
    }

    templated_body = foldl(
        data.aws_s3_bucket_object.fruits.body,
        [for key, val in local.var_mapping : { k = key, v = val }],
        (current_body, item) => replace(current_body, "${${item.k}}", item.v)
    )

    fruits = jsondecode(local.templated_body)
}

方法3:临时文件配合templatefile(不推荐)

这种方法依赖本地执行环境,兼容性差,仅作备选:

data "aws_s3_bucket_object" "fruits" {
    bucket = "fruits"
    key    = "subdir/fruits.json"
}

variable "pears" {
    type    = number
    default = 2
}

# 生成临时模板文件
resource "null_resource" "temp_template" {
    triggers = {
        s3_content = data.aws_s3_bucket_object.fruits.body
        pears_val  = var.pears
    }

    provisioner "local-exec" {
        command = "echo '${data.aws_s3_bucket_object.fruits.body}' > ./temp_fruits.json"
    }
}

locals {
    fruits = templatefile("./temp_fruits.json", { pears = var.pears })
}

# 清理临时文件
resource "null_resource" "clean_temp" {
    depends_on = [null_resource.temp_template]
    provisioner "local-exec" {
        command = "rm ./temp_fruits.json"
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 13:18:09