通过Terraform创建云主机时如何处理多个云盘挂载的问题
扫描二维码随身看资讯
使用手机 二维码应用 扫描右侧二维码,您可以
1. 在手机上细细品读~
2. 分享给您的微信好友或朋友圈~
在某些业务场景下,通过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的日志后,发现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,简而言之,就是for_each要求他的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
}
终于圆满解决了问题,新创建的实例可以使用新的模板。但是存量的实例无法调整,因此仍然需要忍受盘重新挂载的问题。
- 1
大富翁go 官网版
- 2
一战到底游戏
- 3
坏蛋冰淇淋
- 4
掘地求生2同人版
- 5
大家来找茬游戏
- 6
叫叫学院app官方版
- 7
couple game 正式版
- 8
couple game 免费下载
- 9
连连看消消乐游戏
- 10
罗斯方块游戏