通过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

简而言之,就是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
}

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

Terraform中的for_each和count的更多相关文章

  1. 列表中的index,extend,count方法

    列表中的index,extend,count方法 #_author:Administrator#date:2019/10/24#1.index方法l=['blue','red','white','bl ...

  2. Django ORM中,如何使用Count来关联对象的子集数量

    示例models 解决方法 有时候,我们想要获取一个对象关联关系的数量,但是我们不要所有的关联对象,我们只想要符合规则的那些关联对象的数量. 示例models # models.py from dja ...

  3. mysql中MAX()函数和count()函数的技巧使用

    1.max()函数 在考虑提高数据库io的情况下,可以创建索引 ===>create index 索引名称 on 表名(列名); 2.count()函数 问题:count(*)与count(某列 ...

  4. SQL中关于不能显示count为0的行的问题

    今天在写自己一个博客项目时遇到了一个数据库问题,因为对于数据库自己所知道的还是很浅显的,对一些查询语句不怎么熟悉. 我目前有一个文章表和评论表,评论表里面有个post_id对应文章表里面的id,想查询 ...

  5. stl中的for_each() 函数的注意事项

    #include<iostream> using namespace std; #include"vector" #include"algorithm&quo ...

  6. 批量查询hive库中所有表的count

    一.准备文件 mkdir /query_hive_table_count touch query_db_name_table touch query_table_result.txt 二.编辑文件 2 ...

  7. 关于MySQL中查询结果的count和from后的条件与where后的条件对比

    啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦 ...

  8. mysql中count(),group by使用

    count()统计表中或数组中记录 count(*)返回检索行的数目,且不论其值中是否包含NULL count(column_name)返回的是对列中column_name不为NULL的行的统计 例如 ...

  9. mysql中的count(primary_key)、count(1)、count(*)的区别

    表结构如下: mysql> show create table user\G; *************************** 1. row ********************** ...

  10. 关于数据库优化1——关于count(1),count(*),和count(列名)的区别,和关于表中字段顺序的问题

    1.关于count(1),count(*),和count(列名)的区别 相信大家总是在工作中,或者是学习中对于count()的到底怎么用更快.一直有很大的疑问,有的人说count(*)更快,也有的人说 ...

随机推荐

  1. Netty(一)IO模型

    1. Netty介绍 Netty 是由JBOSS提供的一个Jave开源框架,是一个异步地.基于事件驱动的网络应用框架,用以快速开发高性能.高可靠的网络IO程序. Netty主要针对在TCP协议下,面向 ...

  2. RK3588J + 麒麟系统,“软硬件”全国产——让您的产品更具竞争力!

    银河麒麟嵌入式操作系统简介 银河麒麟嵌入式操作系统V10是面向物联网及工业互联网场景的安全实时嵌入式操作系统,具备信息安全.多域隔离.云边端协同.多样性算力支持等特点,可满足嵌入式场景对操作系统小型化 ...

  3. 【创龙全国产T3核心板】赋能工业领域新发展

    在工业5.0时代浪潮持续推进并具备确定性的时代背景下,工业领域创新升级的需求日益增长,为满足各种工业环境下的应用需求,面向工业领域,创龙科技推出了基于全志T3处理器的元器件全国产化工业级核心板--SO ...

  4. ARM+DSP!全志T113-i+玄铁HiFi4开发板硬件说明书(1)

    前 言 本文档主要介绍开发板硬件接口资源以及设计注意事项等内容,测试板卡为全志T113-i+玄铁HiFi4开发板.由于篇幅问题,本篇文章共分为上下两集,点击账户可查看更多内容详情,开发问题欢迎留言,感 ...

  5. 自动化车间3D可视化设计思路

    自动化车间3D可视化设计思路 随着国内制造业企业的高速发展,再加上政策支持,高效的生产模式和先进的管理方式越来越受到企业重视.更多的企业将工业信息化技术进行广泛的应用,比如MES系统.数字孪生以及生产 ...

  6. PHP易混淆函数的区别及用法汇总(函数和方法的区别)

    1.echo和print的区别PHP中echo和print的功能基本相同(输出),但是两者之间还是有细微差别的.echo输出后没有返回值,但print有返回值,当其执行失败时返回flase.因此可以作 ...

  7. 如何在.NET Framework,或NET8以前的项目中使用C# 12的新特性

    前两天发了一篇关于模式匹配的文章,链接地址,有小伙伴提到使用.NET6没法体验 C#新特性的疑问, 其实呢只要本地的SDK源代码编译器能支持到的情况下(直接下载VS2022或者VS的最新preview ...

  8. 搭建lnmp环境-nginx关联php-fpm (第三步)

    永久关闭防火墙sudo systemctl stop firewalldsudo systemctl disable firewall 有两个防火墙!如果上面那个关闭还不行,就继续关这个后重启.   ...

  9. hadoop web界面

    通过界面监控大数据平台运行状态 通过界面查看大数据平台状态 通过大数据平台 Hadoop 的用户界面可以查看平台的计算资源和存储资源.打开 http://master:8088/cluster/nod ...

  10. 【郝斌C ST】01

    自学视频<郝斌C语言自学教程> 01 -  09: https://www.bilibili.com/video/BV1os411h77o 1.为什么学习C语言? - C的起源和发展 第一 ...