通过Shell脚本生成Terraform HCL格式变量文件的问题
解决API/CSV转Terraform HCL变量文件的Shell脚本方案
输入输出示例
CSV输入示例 (input.csv)
env,region,vpc_id,subnet_ids dev,us-east-1,vpc-12345,"subnet-67890,subnet-abcde" prod,eu-west-1,vpc-xyzab,"subnet-cdefg,subnet-hijkl"
目标HCL变量文件 (variables.tfvars)
environment_config = { dev = { region = "us-east-1" vpc_id = "vpc-12345" subnet_ids = ["subnet-67890", "subnet-abcde"] } prod = { region = "eu-west-1" vpc_id = "vpc-xyzab" subnet_ids = ["subnet-cdefg", "subnet-hijkl"] } }
API JSON输入示例
[ { "env": "dev", "region": "us-east-1", "vpc_id": "vpc-12345", "subnet_ids": ["subnet-67890", "subnet-abcde"] }, { "env": "prod", "region": "eu-west-1", "vpc_id": "vpc-xyzab", "subnet_ids": ["subnet-cdefg", "subnet-hijkl"] } ]
方案1:CSV转HCL的Shell脚本
直接用awk处理CSV,解析表头和数据行,生成符合HCL语法的变量文件:
#!/bin/bash awk -F ',' ' BEGIN { print "environment_config = {" } NR == 1 { # 提取表头字段,去除引号 for (i=1; i<=NF; i++) { gsub(/"/, "", $i) headers[i] = $i } next } { # 提取环境名,清理引号 env_name = $1 gsub(/"/, "", env_name) printf " %s = {\n", env_name # 遍历每个字段生成HCL属性 for (i=2; i<=NF; i++) { field = headers[i] value = $i gsub(/^"|"$/, "", value) # 移除字段首尾的引号 # 处理数组类型字段(比如subnet_ids) if (field == "subnet_ids") { split(value, subnets, /,/) printf " %s = [", field for (j=1; j<=length(subnets); j++) { gsub(/^ +| +$/, "", subnets[j]) # 清理子网ID前后空格 printf "%s\"%s\"", (j>1 ? ", " : ""), subnets[j] } printf "]\n" } else { printf " %s = \"%s\"\n", field, value } } printf " }\n" } END { print "}" }' input.csv > variables.tfvars
方案2:API JSON转HCL的Shell脚本
先用jq将JSON转成结构化CSV,再复用上述awk逻辑处理,避免直接解析复杂JSON:
#!/bin/bash # 替换成你的API请求命令,比如 curl https://api.example.com/env-config curl https://api.example.com/env-config | jq -r ' .[] | [.env, .region, .vpc_id, ([.subnet_ids[]] | join(","))] | @csv ' | awk -F ',' ' BEGIN { print "environment_config = {" } { env_name = $1 gsub(/"/, "", env_name) printf " %s = {\n", env_name printf " region = \"%s\"\n", $2 printf " vpc_id = \"%s\"\n", $3 # 处理subnet_ids数组 split($4, subnets, /,/) printf " subnet_ids = [" for (j=1; j<=length(subnets); j++) { gsub(/^"|"$/, "", subnets[j]) printf "%s\"%s\"", (j>1 ? ", " : ""), subnets[j] } printf "]\n" printf " }\n" } END { print "}" }' > variables.tfvars
脚本关键说明
- 自动处理字段的引号和空格,避免HCL语法错误
- 针对数组类型字段做特殊解析,生成HCL列表格式
- CSV脚本支持动态表头,新增字段无需修改核心逻辑
- JSON脚本依赖
jq工具,需提前安装(apt install jq/brew install jq)
Terraform引用示例
variable "environment_config" { type = map(object({ region = string vpc_id = string subnet_ids = list(string) })) description = "Environment-specific infrastructure config" } # 示例:按环境创建VPC标签 resource "aws_vpc" "main" { for_each = var.environment_config cidr_block = "10.${index(keys(var.environment_config), each.key)}.0.0/16" tags = { Name = "${each.key}-main-vpc" } }
内容的提问来源于stack exchange,提问作者L_sama
相关产品推荐
相关产品推荐

