
在基础设施即代码(IaC)实践中,经常需要基于表格数据批量创建云资源。本文介绍一种通过 Terraform 结合 Excel 表格数据批量创建资源的完整方案,适用于需要根据结构化表格数据快速生成标准化基础设施的场景。
该方案通过 "数据转换 - 动态配置 - 模块化管理" 的流程实现实现批量资源创建,核心步骤包括:
以云服务器(CVM)配置为例,Excel 表格需包含资源创建的关键参数(可根据实际需求扩展):
Instance Name | Instance Type | Image ID | Subnet ID | Security Groups | SystemDiskSize | Availability Zone |
|---|---|---|---|---|---|---|
xuel-web-server-01 | SA5.MEDIUM2 | img-l8og963d | subnet-aosdz1ku | sg-1olrbu1b | 50 | ap-guangzhou-6 |
xuel-app-server-01 | SA5.MEDIUM2 | img-l8og963d | subnet-aosdz1ku | sg-1olrbu1b | 50 | ap-guangzhou-6 |
xuel-db-server-01 | SA5.MEDIUM2 | img-l8og963d | subnet-aosdz1ku | sg-1olrbu1b | 50 | ap-guangzhou-6 |
使用 Python 脚本将 Excel 数据转换为 Terraform 可识别的 JSON 格式,实现自动化数据处理。
python体验AI代码助手代码解读复制代码import pandas as pd
import json
import os
import argparse
import traceback
def excel_to_terraform_vars(excel_file, output_file):
# 处理文件路径为绝对路径
excel_file = os.path.abspath(excel_file)
output_file = os.path.abspath(output_file)
# 校验输入文件是否存在
if not os.path.exists(excel_file):
raise FileNotFoundError(f"Excel文件不存在: {excel_file}")
# 识别文件类型(CSV或Excel)
file_extension = os.path.splitext(excel_file)[1].lower()
try:
if file_extension == '.csv':
# 读取CSV文件
df = pd.read_csv(
excel_file,
header=0,
names=['Instance Name', 'Instance Type', 'Image ID', 'Subnet ID',
'Security Groups', 'SystemDiskSize', 'Availability Zone']
)
else:
# 尝试多种引擎读取Excel文件
engines_to_try = ['openpyxl', 'xlrd', 'odf', 'pyxlsb']
df = None
for engine in engines_to_try:
try:
df = pd.read_excel(excel_file, engine=engine)
break
except Exception as e:
print(f"使用{engine}引擎读取失败: {e}")
if df is None:
raise ValueError(f"无法读取Excel文件 {excel_file},尝试了所有可用引擎")
# 校验必填列
required_columns = ['Instance Name', 'Instance Type', 'Image ID', 'Subnet ID',
'Security Groups', 'SystemDiskSize', 'Availability Zone']
missing_columns = [col for col in required_columns if col not in df.columns]
if missing_columns:
raise ValueError(f"缺少必填列: {missing_columns},可用列: {list(df.columns)}")
# 移除全为空的行
df = df.dropna(how='all')
resources = {}
for index, row in df.iterrows():
# 跳过无效行(标题行、分隔行或空行)
if (pd.isna(row['Instance Name']) or
row['Instance Name'] in ['---', ''] or
row['Instance Name'].startswith(('---', '|'))):
continue
# 校验系统盘大小(必须为数字)
try:
system_disk_size = int(row['SystemDiskSize'])
except (ValueError, TypeError):
print(f"跳过无效行(系统盘大小非数字): {row['SystemDiskSize']}")
continue
# 组装资源数据
instance_name = row['Instance Name']
resources[instance_name] = {
'instance_type': str(row['Instance Type']).strip(),
'image_id': str(row['Image ID']).strip(),
'subnet_id': str(row['Subnet ID']).strip(),
'security_groups': [sg.strip() for sg in str(row['Security Groups']).split(',') if sg.strip()],
'system_disk_size': system_disk_size,
'availability_zone': str(row['Availability Zone']).strip()
}
# 确保输出目录存在
os.makedirs(os.path.dirname(output_file), exist_ok=True)
# 写入JSON文件
with open(output_file, 'w') as f:
json.dump(resources, f, indent=2)
print(f"数据转换完成: {excel_file} -> {output_file}")
except Exception as e:
print(f"处理失败: {e}")
raise
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Excel转Terraform变量工具')
parser.add_argument('excel_file', help='输入Excel/CSV文件路径')
parser.add_argument('--output', default=None, help='输出tfvars.json文件路径')
args = parser.parse_args()
# 自动生成输出文件名(默认与输入文件同路径,后缀为.tfvars.json)
output_file = args.output or f"{os.path.splitext(args.excel_file)[0]}.tfvars.json"
excel_to_terraform_vars(args.excel_file, output_file)安装依赖包:
arduino体验AI代码助手代码解读复制代码pip install pandas openpyxl xlrd # openpyxl支持xlsx,xlrd支持xlsbash体验AI代码助手代码解读复制代码# 转换CSV文件(Excel文件同理)
python excel_to_tfvars.py resources.csv --output resources.tfvars.jsonjson体验AI代码助手代码解读复制代码{
"xuel-web-server-01": {
"instance_type": "SA5.MEDIUM2",
"image_id": "img-l8og963d",
"subnet_id": "subnet-aosdz1ku",
"security_groups": ["sg-1olrbu1b"],
"system_disk_size": 50,
"availability_zone": "ap-guangzhou-6"
},
"xuel-app-server-01": {
"instance_type": "SA5.MEDIUM2",
"image_id": "img-l8og963d",
"subnet_id": "subnet-aosdz1ku",
"security_groups": ["sg-1olrbu1b"],
"system_disk_size": 50,
"availability_zone": "ap-guangzhou-6"
},
"xuel-db-server-01": {
"instance_type": "SA5.MEDIUM2",
"image_id": "img-l8og963d",
"subnet_id": "subnet-aosdz1ku",
"security_groups": ["sg-1olrbu1b"],
"system_disk_size": 50,
"availability_zone": "ap-guangzhou-6"
}
}bash体验AI代码助手代码解读复制代码.
├── modules/ # 资源模块目录
│ └── instance/ # 云服务器实例模块
│ ├── main.tf # 资源定义
│ ├── variables.tf # 模块变量
│ └── outputs.tf # 模块输出
├── main.tf # 主配置(调用模块)
├── providers.tf # 云厂商配置
└── resources.tfvars.json # 转换后的资源数据ini体验AI代码助手代码解读复制代码terraform {
required_providers {
tencentcloud = {
source = "tencentcloudstack/tencentcloud"
version = "~> 1.81.0"
}
}
}
provider "tencentcloud" {
# 可通过环境变量配置:TENCENTCLOUD_SECRET_ID、TENCENTCLOUD_SECRET_KEY
# secret_id = "your-secret-id"
# secret_key = "your-secret-key"
region = "ap-guangzhou" # 地域
}ini体验AI代码助手代码解读复制代码variable "instance_name" {
description = "实例名称"
type = string
}
variable "instance_type" {
description = "实例类型"
type = string
}
variable "image_id" {
description = "镜像ID"
type = string
}
variable "subnet_id" {
description = "子网ID"
type = string
}
variable "security_groups" {
description = "安全组ID列表"
type = list(string)
}
variable "system_disk_size" {
description = "系统盘大小(GB)"
type = number
default = 50
}
variable "availability_zone" {
description = "可用区"
type = string
}ini体验AI代码助手代码解读复制代码resource "tencentcloud_instance" "this" {
instance_name = var.instance_name
instance_type = var.instance_type
image_id = var.image_id
subnet_id = var.subnet_id
security_groups = var.security_groups
availability_zone = var.availability_zone
# 系统盘配置
system_disk_size = var.system_disk_size
system_disk_type = "CLOUD_PREMIUM" # 高性能云硬盘
# 其他可选配置(根据需求添加)
# internet_charge_type = "TRAFFIC_POSTPAID_BY_HOUR"
# internet_max_bandwidth_out = 100
}ini体验AI代码助手代码解读复制代码output "instance_id" {
description = "实例ID"
value = tencentcloud_instance.this.id
}
output "public_ip" {
description = "公网IP"
value = tencentcloud_instance.this.public_ip
}
output "private_ip" {
description = "内网IP"
value = tencentcloud_instance.this.private_ip
}ini体验AI代码助手代码解读复制代码# 读取JSON数据
locals {
instances = jsondecode(file("${path.module}/resources.tfvars.json"))
}
# 循环调用模块创建实例
module "instances" {
source = "./modules/instance"
for_each = local.instances
# 传递变量(与JSON字段对应)
instance_name = each.key
instance_type = each.value.instance_type
image_id = each.value.image_id
subnet_id = each.value.subnet_id
security_groups = each.value.security_groups
system_disk_size = each.value.system_disk_size
availability_zone = each.value.availability_zone
}
# 全局输出所有实例信息
output "all_instances" {
description = "所有实例信息"
value = {
for name, instance in module.instances :
name => {
id = instance.instance_id
public_ip = instance.public_ip
private_ip = instance.private_ip
}
}
}csharp体验AI代码助手代码解读复制代码terraform init # 下载Provider和模块bash体验AI代码助手代码解读复制代码terraform plan # 检查配置并预览将要创建的资源bash体验AI代码助手代码解读复制代码terraform apply # 确认后输入yes执行创建bash体验AI代码助手代码解读复制代码terraform output # 显示所有实例的ID和IP信息

本方案通过 "Excel 表格→Python 转换→Terraform 批量创建" 的流程,实现了基于表格数据的标准化资源部署,核心优势包括:
除 Python 转换外,Terraform 官方提供csvdecode函数可直接解析 CSV 文件(无需 Python 脚本),示例:
ini体验AI代码助手代码解读复制代码locals {
# 直接解析CSV文件
instances = csvdecode(file("${path.module}/resources.csv"))
}
# 后续使用方式与JSON方案一致选择哪种方式取决于需求:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。