Terraform为OCI多实例挂载多磁盘报错求助
问题:OCI平台Terraform部署多实例挂载多磁盘失败
问题背景
当前Terraform配置可实现单实例挂载单磁盘,但配置多磁盘(如disks: ["50","100"])时无法生效,报错提示size_in_gbs参数类型错误。
现有配置代码
变量定义
configuration = [ { "display_name": "test3", "Owner_name" : "rajini.l@oracle.com", "no_of_instances" : "2", "disks" : ["50"] }, { "display_name": "test2", "Owner_name" : "rajini.2@oracle.com", "no_of_instances" : "1", "disks" : ["50"] }, { "display_name": "test1", "Owner_name" : "rajini.3@oracle.com", "no_of_instances" : "1", "disks" : ["50"] } ]
实例创建代码
locals { serverconfig = [ for srv in var.configuration : [ for i in range(1, tonumber(srv.no_of_instances)+1) : { instance_name = "${srv.display_name}-${i}" Owner_name = srv.Owner_name disks = srv.disks } ] ] } locals { instances = flatten(local.serverconfig) } resource "oci_core_instance" "test_instance" { for_each = {for server in local.instances: server.instance_name => server} availability_domain = var.ad compartment_id = data.oci_identity_compartments.test_compartments.compartments[0].id shape = var.shape source_details { source_id = data.oci_core_images.test_images.images[0].id source_type = "image" } freeform_tags = {"Owner" = each.value.Owner_name} create_vnic_details { subnet_id = var.subnet_ociid assign_public_ip = false } display_name = each.value.instance_name metadata = { user_data = base64encode(templatefile("user_data.sh", {user_email=var.user_email})) } preserve_boot_volume = false }
失效的磁盘创建代码
resource "oci_core_volume" "test_volume" { for_each = {for server in local.instances: server.instance_name => server} compartment_id = data.oci_identity_compartments.test_compartments.compartments[0].id size_in_gbs = each.value.disks[*] availability_domain = var.ad }
报错信息
Error: Incorrect attribute value type on instance.tf line 59, in resource "oci_core_volume" "test_volume": 59: size_in_gbs = each.value.disks[*] Inappropriate value for attribute "size_in_gbs": string required.
解决方案
问题核心在于:
- 磁盘资源需为每个磁盘单独创建实例,而非每个实例对应一个磁盘资源
size_in_gbs要求数字类型,需将配置中的字符串转成数字
步骤1:构造实例-磁盘映射列表
添加local变量,将每个实例的多块磁盘拆分为单独条目,同时转换磁盘大小为数字:
locals { instance_disks = flatten([ for server in local.instances : [ for idx, disk_size_str in enumerate(server.disks) : { instance_name = server.instance_name disk_size = tonumber(disk_size_str) disk_key = "${server.instance_name}-disk-${idx+1}" # 唯一标识每块磁盘 owner_name = server.Owner_name } ] ]) }
步骤2:创建多块磁盘资源
基于上面的映射列表,为每块磁盘创建独立资源:
resource "oci_core_volume" "test_volume" { for_each = {for disk in local.instance_disks : disk.disk_key => disk} compartment_id = data.oci_identity_compartments.test_compartments.compartments[0].id size_in_gbs = each.value.disk_size availability_domain = var.ad freeform_tags = {"Owner" = each.value.owner_name} }
步骤3:挂载磁盘到对应实例
添加磁盘挂载资源,将每块磁盘绑定到目标实例:
resource "oci_core_volume_attachment" "test_volume_attach" { for_each = oci_core_volume.test_volume instance_id = oci_core_instance.test_instance[each.value.instance_name].id volume_id = each.value.id availability_domain = var.ad attachment_type = "paravirtualized" # 根据实例类型选择,可选iscsi/paravirtualized }
关键说明
- 使用
flatten和嵌套循环拆分实例与磁盘的一对多关系,确保每块磁盘对应一个Terraform资源 - 通过
tonumber将配置中的字符串磁盘大小转为数字,匹配size_in_gbs参数要求 - 用
disk_key作为资源唯一键,避免同实例同大小磁盘出现资源冲突 - 必须添加
oci_core_volume_attachment资源才能完成磁盘与实例的绑定
内容的提问来源于stack exchange,提问作者user24224675
相关产品推荐
相关产品推荐

