首页 > 其他分享 >Terraform中的for_each和count

Terraform中的for_each和count

时间:2024-08-22 20:18:37浏览次数:7  
标签:count tencentcloud cbs storage Terraform attachment each id

通过Terraform创建云主机时,在某些业务场景下,一个机器需要挂载多个云盘,一般云厂商都是单独创建云主机和云硬盘然后通过attachment的资源去挂载,因此我们的模板大致如下:

resource "tencentcloud_instance" "basic" {
  instance_name     = var.instance_name
  password = "xxx"
}

resource "tencentcloud_cbs_storage" "storage" {
  for_each          = var.data_disks
  storage_name      = each.key
  storage_type      = each.value.disk_type
  storage_size      = each.value.size
}

resource "tencentcloud_cbs_storage_attachment" "attachment" {
  count       = length(tencentcloud_cbs_storage.storage)
  storage_id  = element(values(tencentcloud_cbs_storage.storage)[*].id, count.index)
  instance_id = tencentcloud_instance.basic.id
}


variable "data_disks" {
  type = map(object({
    disk_type = string
    size      = number
  }))
  description = "Instance Data Disks"
  default     = {}
}

这个模板我们一直用了很久,完全满足多盘的需求,也具有一定灵活性,但是随着全方位降本的需求,在服务优化等措施下,业务方评估可以考虑减少云盘数量,因为机型的特殊性,机器也不能回收重新创建。

因为之前一直没有减盘的场景,所以一直没关注,直到最近业务方评估需要减盘,发现在减盘时盘的attachment会销毁重新创建,腾讯云这个资源的操作会伴随unmount动作,导致减盘之后盘没有被挂载上

这个现象是不在我的预期当中的,分析Terraform的日志:

  # tencentcloud_cbs_storage_attachment.attachment[0] must be replaced
-/+ resource "tencentcloud_cbs_storage_attachment" "attachment" {
      ~ id          = "disk-mcklmp5z" -> (known after apply)
      ~ storage_id  = "disk-mcklmp5z" -> "disk-rspjpenh" # forces replacement
        # (1 unchanged attribute hidden)
    }

  # tencentcloud_cbs_storage_attachment.attachment[1] must be replaced
-/+ resource "tencentcloud_cbs_storage_attachment" "attachment" {
      ~ id          = "disk-rspjpenh" -> (known after apply)
      ~ storage_id  = "disk-rspjpenh" -> "disk-k9c5lg1v" # forces replacement
        # (1 unchanged attribute hidden)
    }

  # tencentcloud_cbs_storage_attachment.attachment[2] must be replaced
-/+ resource "tencentcloud_cbs_storage_attachment" "attachment" {
      ~ id          = "disk-k9c5lg1v" -> (known after apply)
      ~ storage_id  = "disk-k9c5lg1v" -> "disk-jl5g1u7f" # forces replacement
        # (1 unchanged attribute hidden)
    }

  # tencentcloud_cbs_storage_attachment.attachment[3] must be replaced
-/+ resource "tencentcloud_cbs_storage_attachment" "attachment" {
      ~ id          = "disk-jl5g1u7f" -> (known after apply)
      ~ storage_id  = "disk-jl5g1u7f" -> "disk-mytvnnif" # forces replacement
        # (1 unchanged attribute hidden)
    }

发现attachment的索引是index,减盘的时候索引会重新计算,这就是attachment资源被销毁重建,导致云盘被卸载的原因。

原因明确了,那就好解决了,可以用for_each来解决这个问题,如下:

resource "tencentcloud_cbs_storage_attachment" "attachment" {
  for_each = toset(values(tencentcloud_cbs_storage.storage)[*].id)
  storage_id  = each.key
  instance_id = tencentcloud_instance.foo.id
}

事情往往没那么顺利:

│ Error: Invalid for_each argument
│
│   on main.tf line 61, in resource "tencentcloud_cbs_storage_attachment" "attachment":
│   61:   for_each = toset(values(tencentcloud_cbs_storage.storage)[*].id)
│     ├────────────────
│     │ tencentcloud_cbs_storage.storage is object with 6 attributes
│
│ The "for_each" value depends on resource attributes that cannot be
│ determined until apply, so Terraform cannot predict how many instances will
│ be created. To work around this, use the -target argument to first apply
│ only the resources that the for_each depends on.

好吧,在Terraform论坛发现一个issue:
https://discuss.hashicorp.com/t/the-for-each-value-depends-on-resource-attributes-that-cannot-be-determined-until-apply/25016
file

简而言之,就是foreach要求他的map key必须是已知明确的值,不能是依赖其他资源的值,所以会有如上错误。知道限制了调整下模板:

resource "tencentcloud_cbs_storage_attachment" "attachment" {
  for_each = var.data_disks
  storage_id  = tencentcloud_cbs_storage.storage[each.key].id
  instance_id = tencentcloud_instance.basic.id
}

圆满解决,新创建的实例用上新的模板,但是存量的实例无法调整还是得忍受下盘重新挂载的问题。

标签:count,tencentcloud,cbs,storage,Terraform,attachment,each,id
From: https://www.cnblogs.com/leason001/p/18374650

相关文章

  • SAP Parallel Accounting(平行分类账业务)配置及操作手册【适用于多国家会计准则】
    1.配置准备1.1理解平行账概念平行账,也称为多分类账,是SAP系统中的一项功能,它允许企业按照不同的会计准则来维护各自的财务数据。这种设置特别适用于那些需要符合多种会计准则的跨国公司。通过平行账,企业可以在不同的分类账中记录相同的交易,但按照各自的会计政策进行处理。......
  • Langchain pandas agent - Azure OpenAI account
    Langchainpandasagent结合AzureOpenAI账户使用时,主要涉及到通过AzureOpenAI提供的自然语言处理能力,来操作pandasDataFrame或进行相关的数据处理任务。以下是关于这一结合使用的详细解析:一、Langchainpandasagent概述在LangChain中,Agent是一个核心概念,它代表了......
  • 面试题:在Java中,JVM(Java虚拟机)的内存模型是如何设计的?请详细解释堆(Heap)、栈(Stack)、方法
    面试题:在Java中,JVM(Java虚拟机)的内存模型是如何设计的?请详细解释堆(Heap)、栈(Stack)、方法区(MethodArea)以及程序计数器(ProgramCounterRegister)的作用和它们之间的关系。更多答案在这里,手机或电脑浏览器就可以打开,面霸宝典【全拼音】.com这里可以优化简历,模拟面试,企业项......
  • Let Me Teach You a Lesson (Easy Version)
    显然当\(n\)为偶数的时候比较好考虑,将互相交换的两组放在一起,无论什么情况,这两个组的最大值更小最小值更大是更优的,而且由于\((a+b)+(c+d)=(a+c)+(b+d)\),所以最大值更小当前仅当最小值更大,不会出现最大值更小最小值也更小的情况,所以直接枚举四种情况就好了然后来考虑当\(n\)为奇......
  • CountDownLatch
    importlombok.SneakyThrows;importjava.util.Date;importjava.util.concurrent.*;/*main上锁3线程1获得锁线程2获得锁线程3获得锁线程1释放锁2线程2释放锁1线程3释放锁0main解锁0**/publicclassT{@SneakyThrowspublicstaticvoidmain(String[......
  • 040_java.util.concurrent.CountDownLatch
    简单介绍CountDownLatch的通常用法和Thread.join()有点类似,等待其它线程都完成后再执行主任务。允许一个或多个线程等待其它线程的操作执行完毕后再执行后续的操作。先看看怎么用:publicclassCountDownLatchTest{publicstaticvoidmain(String[]args)throwsIn......
  • LeetCode 1359. Count All Valid Pickup and Delivery Options
    原题链接在这里:https://leetcode.com/problems/count-all-valid-pickup-and-delivery-options/description/题目:Given n orders,eachorderconsistsofapickupandadeliveryservice.Countallvalidpickup/deliverypossiblesequencessuchthatdelivery(i)isalw......
  • Odoo search、name_search、search_count、search_read、read_group
    主要包括以下几个方法及主要用途:search():搜索视图中调用search_count():视图中计算记录数时调用name_search():many2one字段搜索时调用search_read():many2one点开搜索更多时调用read_group():搜索视图分组时调用search()search方法中包含有几个子方法 根据domian取查......
  • 巧用Array.forEach:简化循环与增强代码可读性;Array.forEach怎么用;面对大量数据时怎么提
    目录Vue.js中的Array.forEach:简化循环与增强代码可读性一、引言二、Array.forEach()的使用与技巧1、基本语法2、返回值3、使用Array.forEach()的优势4、Array.forEachvsfor循环5、Array.forEach()使用技巧三、Array.forEach()的应用情景1、复杂数据处理2、实时更......
  • 在 SQL 中,怎样使用聚合函数(如 SUM、AVG、COUNT 等)来计算数据的总和、平均值和数量?
    在SQL中,可以使用聚合函数来计算数据的总和、平均值和数量。以下是一些常用的聚合函数的示例:SUM函数:计算指定列的总和。SELECTSUM(column_name)FROMtable_name;AVG函数:计算指定列的平均值。SELECTAVG(column_name)FROMtable_name;COUNT函数:计算指定列的数......