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

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.

解决方案

问题核心在于:

  1. 磁盘资源需为每个磁盘单独创建实例,而非每个实例对应一个磁盘资源
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:22:04