Terraform中的for_each和count

打印 上一主题 下一主题

主题 572|帖子 572|积分 1720

通过Terraform创建云主机时,在某些业务场景下,一个机器需要挂载多个云盘,一般云厂商都是单独创建云主机和云硬盘然后通过attachment的资源去挂载,因此我们的模板大致如下:
  1. resource "tencentcloud_instance" "basic" {
  2.   instance_name     = var.instance_name
  3.   password = "xxx"
  4. }
  5. resource "tencentcloud_cbs_storage" "storage" {
  6.   for_each          = var.data_disks
  7.   storage_name      = each.key
  8.   storage_type      = each.value.disk_type
  9.   storage_size      = each.value.size
  10. }
  11. resource "tencentcloud_cbs_storage_attachment" "attachment" {
  12.   count       = length(tencentcloud_cbs_storage.storage)
  13.   storage_id  = element(values(tencentcloud_cbs_storage.storage)[*].id, count.index)
  14.   instance_id = tencentcloud_instance.basic.id
  15. }
  16. variable "data_disks" {
  17.   type = map(object({
  18.     disk_type = string
  19.     size      = number
  20.   }))
  21.   description = "Instance Data Disks"
  22.   default     = {}
  23. }
复制代码
这个模板我们不停用了很久,完全满足多盘的需求,也具有一定机动性,但是随着全方位降本的需求,在服务优化等措施下,业务方评估可以考虑减少云盘数量,因为机型的特殊性,机器也不能回收重新创建。
因为之前不停没有减盘的场景,所以不停没关注,直到最近业务方评估需要减盘,发现在减盘时盘的attachment会销毁重新创建,腾讯云这个资源的操作会伴随unmount动作,导致减盘之后盘没有被挂载上
这个征象是不在我的预期当中的,分析Terraform的日记:
  1.   # tencentcloud_cbs_storage_attachment.attachment[0] must be replaced
  2. -/+ resource "tencentcloud_cbs_storage_attachment" "attachment" {
  3.       ~ id          = "disk-mcklmp5z" -> (known after apply)
  4.       ~ storage_id  = "disk-mcklmp5z" -> "disk-rspjpenh" # forces replacement
  5.         # (1 unchanged attribute hidden)
  6.     }
  7.   # tencentcloud_cbs_storage_attachment.attachment[1] must be replaced
  8. -/+ resource "tencentcloud_cbs_storage_attachment" "attachment" {
  9.       ~ id          = "disk-rspjpenh" -> (known after apply)
  10.       ~ storage_id  = "disk-rspjpenh" -> "disk-k9c5lg1v" # forces replacement
  11.         # (1 unchanged attribute hidden)
  12.     }
  13.   # tencentcloud_cbs_storage_attachment.attachment[2] must be replaced
  14. -/+ resource "tencentcloud_cbs_storage_attachment" "attachment" {
  15.       ~ id          = "disk-k9c5lg1v" -> (known after apply)
  16.       ~ storage_id  = "disk-k9c5lg1v" -> "disk-jl5g1u7f" # forces replacement
  17.         # (1 unchanged attribute hidden)
  18.     }
  19.   # tencentcloud_cbs_storage_attachment.attachment[3] must be replaced
  20. -/+ resource "tencentcloud_cbs_storage_attachment" "attachment" {
  21.       ~ id          = "disk-jl5g1u7f" -> (known after apply)
  22.       ~ storage_id  = "disk-jl5g1u7f" -> "disk-mytvnnif" # forces replacement
  23.         # (1 unchanged attribute hidden)
  24.     }
复制代码
发现attachment的索引是index,减盘的时候索引会重新计算,这就是attachment资源被销毁重建,导致云盘被卸载的原因。
原因明确了,那就好解决了,可以用for_each来解决这个问题,如下:
  1. resource "tencentcloud_cbs_storage_attachment" "attachment" {
  2.   for_each = toset(values(tencentcloud_cbs_storage.storage)[*].id)
  3.   storage_id  = each.key
  4.   instance_id = tencentcloud_instance.foo.id
  5. }
复制代码
事情每每没那么顺遂:
  1. │ Error: Invalid for_each argument
  2. │   on main.tf line 61, in resource "tencentcloud_cbs_storage_attachment" "attachment":
  3. │   61:   for_each = toset(values(tencentcloud_cbs_storage.storage)[*].id)
  4. │     ├────────────────
  5. │     │ tencentcloud_cbs_storage.storage is object with 6 attributes
  6. │ The "for_each" value depends on resource attributes that cannot be
  7. │ determined until apply, so Terraform cannot predict how many instances will
  8. │ be created. To work around this, use the -target argument to first apply
  9. │ 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必须是已知明确的值,不能是依赖其他资源的值,所以会有如上错误。知道限制了调整下模板:
  1. resource "tencentcloud_cbs_storage_attachment" "attachment" {
  2.   for_each = var.data_disks
  3.   storage_id  = tencentcloud_cbs_storage.storage[each.key].id
  4.   instance_id = tencentcloud_instance.basic.id
  5. }
复制代码
圆满解决,新创建的实例用上新的模板,但是存量的实例无法调整还是得忍受下盘重新挂载的问题。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王國慶

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表