infrastructure 也可以 for each 之三
课程内容与代码会放在 Github 上: https://github.com/chechiachang/terraform-30-days
赛後文章会整理放到个人的部落格上 http://chechia.net/
要管理重复的 resource block ,Terrafrom 还提供另一个 meta-argument count。范例
azurerm_virtual_machine
resource "azurerm_virtual_machine" "main" {
count = 3
name = "${var.prefix}-vm-${count.index}"
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
network_interface_ids = [azurerm_network_interface.main.id]
vm_size = "Standard_DS1_v2"
...
}
实际 output 会类似
azurerm_virtual_machine.main
,这边会是一组 collection,可以使用 index 存取azurerm_virtual_machine.main[0]
azurerm_virtual_machine.main[1]
azurerm_virtual_machine.main[2]
resource "azurerm_virtual_machine" "main[0]" {
name = "${var.prefix}-vm-0"
...
}
resource "azurerm_virtual_machine" "main[1]" {
name = "${var.prefix}-vm-1"
...
}
resource "azurerm_virtual_machine" "main[2]" {
name = "${var.prefix}-vm-2"
...
}
Count 与 for each 是互斥的,意思是 resource block 中只能使用其中一个 meta-argument,一起使用的话会在 validate 出 syntax error
for each 使用 input variable 的 key 作为 key,count 使用则搭配 count.index,在 collection 取得参数值
首先是 node pool 范例,使用 for each meta-argument
# modules/kubernetes_cluster/node_pool.tf
resource "azurerm_kubernetes_cluster_node_pool" "main" {
for_each = var.node_pools
name = each.value.name
...
}
var.node_pools
# modules/kubernetes_cluster/node_pool.tf
resource "azurerm_kubernetes_cluster_node_pool" "main" {
count = length(var.node_pools)
name = var.node_pools[count.index].name
...
}
展开变成
# modules/kubernetes_cluster/node_pool.tf
resource "azurerm_kubernetes_cluster_node_pool" "main[0]" {
name = var.node_pools[0].name
...
}
resource "azurerm_kubernetes_cluster_node_pool" "main[1]" {
name = var.node_pools[1].name
...
}
注意:上面使用 count 与 for each 的取值方式不同,这里会可能造成 count.index 的错乱
var.node_pools
有改变, plan 的时候重新计算 resource block,便有可能导致顺序错乱Terraform 官方在 When to use count and for each 说明 count 与 for each 建议的使用时机,已经不建议如此使用 count 了
那为何 count 还是会存在?是历史缘故 resource 中的 count 支援版本很早,for each 要到 0.12 之後的 terraform 版本才支援。也就是说,古人没有 for each 可以用被迫使用 count + count.index
count 历史悠久,可以分享一些常见的用法
variable "vm_names" {
default = ["vm-1", "vm-2", "vm-3"]
type = list
}
variable "vm_sizes" {
default = ["Standard_DS1_v2", "Standard_DS2_v2", "Standard_DS4_v2"]
type = list
}
resource "azurerm_virtual_machine" "main" {
count = length(var.vm_names)
name = var.vm_names[count.index]
vm_size = var.vm_sizes[count.index]
}
上面这个用法的问题
新版 terraform 请使用
vm_names
与 vm_sizes
合并成为单一 variablecount 可以接受 0 为参数,意思是就产生 0 个 resource block
resource "azurerm_virtual_machine" "main" {
count = 0
name = "${var.prefix}-vm-${count.index}"
...
}
这又产生了另外一个用法,来有条件的控制 resource block 与 module
variable "enable_azurerm_virtual_machine" {
type = bool
default = false
}
resource "azurerm_virtual_machine" "main" {
count = var.enable_azurerm_virtual_machine ? 1 : 0
name = "${var.prefix}-vm-${count.index}"
...
}
上面这个范例
enable_azurerm_virtual_machine
== true 的时候,会产生 count = 1,也就是产生一个 azurerm_virtual_machine
enable_azurerm_virtual_machine
== false 的时候,会产生 count = 0,也就是产生一个 azurerm_virtual_machine
实务上这样子的使用情境还算蛮多的,一个 resource / module 启用或不启用
for_each
的 argument literate 下去是 empty 的话,for each 出来就会产生 0 个 resource / moduleTerraform 官方在 When to use count and for each 说明 count 与 for each 建议的使用时机
能用 for each 的时候就用 for each
熟 golang 的不妨看一下 source code
在进入正题之前先让大家看看在 Reactive Programming 中的一种使用案例: val ...
什麽是 Google Apps Script ??。 今日要点: 》Google Apps Scr...
接下来,开始看看如何着手进行 Vue 的开发吧 这边都是透过最原始、最简单的网页开发模式进行,所以不...
学习内容 资料型态、取得资料 简介 资料型态(Data Type),又称资料类型或资料型别,是用来约...
来到了第四天,我们一起来看看RDS是什麽。 RDS是Relational Database Serv...