Terraform中的for_each和count
通过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的更多相关文章
- 列表中的index,extend,count方法
列表中的index,extend,count方法 #_author:Administrator#date:2019/10/24#1.index方法l=['blue','red','white','bl ...
- Django ORM中,如何使用Count来关联对象的子集数量
示例models 解决方法 有时候,我们想要获取一个对象关联关系的数量,但是我们不要所有的关联对象,我们只想要符合规则的那些关联对象的数量. 示例models # models.py from dja ...
- mysql中MAX()函数和count()函数的技巧使用
1.max()函数 在考虑提高数据库io的情况下,可以创建索引 ===>create index 索引名称 on 表名(列名); 2.count()函数 问题:count(*)与count(某列 ...
- SQL中关于不能显示count为0的行的问题
今天在写自己一个博客项目时遇到了一个数据库问题,因为对于数据库自己所知道的还是很浅显的,对一些查询语句不怎么熟悉. 我目前有一个文章表和评论表,评论表里面有个post_id对应文章表里面的id,想查询 ...
- stl中的for_each() 函数的注意事项
#include<iostream> using namespace std; #include"vector" #include"algorithm&quo ...
- 批量查询hive库中所有表的count
一.准备文件 mkdir /query_hive_table_count touch query_db_name_table touch query_table_result.txt 二.编辑文件 2 ...
- 关于MySQL中查询结果的count和from后的条件与where后的条件对比
啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦 ...
- mysql中count(),group by使用
count()统计表中或数组中记录 count(*)返回检索行的数目,且不论其值中是否包含NULL count(column_name)返回的是对列中column_name不为NULL的行的统计 例如 ...
- mysql中的count(primary_key)、count(1)、count(*)的区别
表结构如下: mysql> show create table user\G; *************************** 1. row ********************** ...
- 关于数据库优化1——关于count(1),count(*),和count(列名)的区别,和关于表中字段顺序的问题
1.关于count(1),count(*),和count(列名)的区别 相信大家总是在工作中,或者是学习中对于count()的到底怎么用更快.一直有很大的疑问,有的人说count(*)更快,也有的人说 ...
随机推荐
- git clone 时拉取子模块
git clone 时拉取子模块 对还未下载的项目: git clone --recursive 对已下载的项目: git submodule sync git submodule update -- ...
- 【FAQ】HarmonyOS SDK 闭源开放能力 —Ads Kit
1.问题描述: 开屏广告效果最好的实现方式? 解决方法: 1.动画效果和开发者的实现方式有关,和开屏广告页面本身没什么关系的: 2.示例代码中使用Router跳转的方式展示广告,主要是用于演示广告接口 ...
- Log4Net配置详解及输出自定义消息类示例
1.简单使用实例 1.1 添加log4net.dll的引用. 在NuGet程序包中搜索log4net并添加,此次我所用版本为2.0.17.如下图: 1.2 添加配置文件 右键项目,添加新建项, ...
- 数据结构—包(Bag)
数据结构中的包,其实是对现实中的包的一种抽象. 想像一下现实中的包,比如书包,它能做什么?有哪些功能?首先它用来装东西,里面的东西可以随便放,没有规律,没有顺序,当然,可以放多个相同的东西.其次,东西 ...
- Babel 7 初探
Babel有两大功能,转译和polyfill.转译就是把新的JS的语法,转化成旧的JS的语法.polyfill则是针对JS中新增的一些对象(Map, Set)和实例方法,这些对象和方法,在旧的浏览器中 ...
- C++中的引用(Reference)
1. 引用(Reference) 在 C++ 中,引用(Reference)是一个变量的别名. 它允许你通过不同的名字访问同一个变量. 与指针不同,引用在定义时必须被初始化,并且一旦绑定到某个变量,之 ...
- [Unity] Dreamteck Splines实现沿路径移动功能
Dreamteck Splines实现沿路径移动功能 最近有一个"让物体沿固定路径移动"的需求,因此接触到了Dreamteck Splines插件. Dreamteck Splin ...
- 如何在.NET Framework,或NET8以前的项目中使用C# 12的新特性
前两天发了一篇关于模式匹配的文章,链接地址,有小伙伴提到使用.NET6没法体验 C#新特性的疑问, 其实呢只要本地的SDK源代码编译器能支持到的情况下(直接下载VS2022或者VS的最新preview ...
- 2024NOI联合省选游记
人生当中成功只是一时的,而失败却是主旋律. 不太好的的阅读体验 本文作者:xxxalq 所谓游记,顾名思义就是指游玩所记,所以重点在玩而不在省选. 由于没有参加 \(\text{NOIP}\),导致我 ...
- 奇怪的回溯增加了 | leetcode131分割回文串
题目要求:给你一个字符串 s,请你将s分割成一些子串,使每个子串都是回文串.返回 s 所有可能的分割方案 示例 1: 输入:s = "aab" 输出:[["a" ...