从 Terraform 中的范围函数中排除数字列表
Exclude list of numbers from Range function in Terraform
我正在尝试使用 for_each 循环在 Azure 中创建多个 VM。假设虚拟机 1-100。但是,会有删除请求,即 VM 编号 50。
我有两个问题:
terraform_azure> terraform state list
module.edit_vms.azurerm_linux_virtual_machine.test_seat["test-vm-1"]
terraform state rm module.edit_vms.azurerm_linux_virtual_machine.test_seat["test-vm-1"]
zsh: no matches found: module.edit_vms.azurerm_linux_virtual_machine.test_seat[test-vm-1]
当我尝试从 Terraform 状态中删除 VM 50 时,出现上述错误。我不明白为什么当资源列在 terraform state list command
下时我没有看到匹配项
有没有办法删除 50 号 VM 并将 VM 计数设置为 1 -> 101 并防止 terraform 重新创建 50 号 VM?如果从状态文件中删除 VM 不是一个好的做法,那么如果我可以在代码中指定我希望它被销毁而不是在将来应用时重新创建,那就更好了。
这是我的variables.tf
variable "edit_seat_spec" {
description = "VM details"
type = list
default = [{
resource_group_name = "my_rg"
server_name = "test-vm"
server_size = "Standard_B2s"
location = "East US"
vnet = "test_vnet"
subnet_name = "default"
username = "username"
password = "password"
vm_count = "4"
}]
}
和main.tf
locals{
edit_seat = [
for edit in var.edit_seat_spec : [
for i in range(1, edit.vm_count) : {
name = "${edit.server_name}-${i}"
resource_group = edit.resource_group_name
vnet = edit.vnet
nic = "${edit.server_name}-${i}-nic"
location = edit.location
subnet_name = edit.subnet_name
size = edit.server_size
admin_username = edit.username
admin_password = edit.password
}
]
]
}
locals {
edit_vm = flatten(local.edit_seat)
}
resource "azurerm_linux_virtual_machine" "vm" {
for_each = {for edit in local.edit_vm: edit.name => edit}
name = each.value.name
resource_group_name = each.value.resource_group
location = each.value.location
size = each.value.size
admin_username = each.value.admin_username
admin_password = each.value.admin_password
disable_password_authentication = false
network_interface_ids = [azurerm_network_interface.edit_seat_nic[each.key].id]
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
}
您可以过滤 for
、with the help of if
statement.
中的元素
另请注意,range
不会包括上限:
The interpretation of limit
depends on the direction of step
: for a positive step, the sequence is complete when the next number is greater than or equal to limit
.
因此,如果您想要 1 到 100 的范围,则需要 range(1, var.variable_that_contains_100 + 1)
。
因此,如果你想跳过从 1 到 100 的步进中的一个元素,你需要将上限设置为 102。
这里是一个示例,请求 5 个元素,跳过 3 个,为简洁起见:
variable "vm_count" {
default = 5
}
output "test" {
value = [for i in range(1, var.vm_count + 2) : {
name = "some-server-${i}"
} if i != 3]
}
这产生:
Changes to Outputs:
+ test = [
+ {
+ name = "some-server-1"
},
+ {
+ name = "some-server-2"
},
+ {
+ name = "some-server-4"
},
+ {
+ name = "some-server-5"
},
+ {
+ name = "some-server-6"
},
]
如果你想排除一个列表,正如问题的标题所述,你可以使用排除列表的 contains
instead in the condition, then increase the upper limit based on the length
加一。
variable "vm_count" {
default = 5
}
variable "exclusion" {
default = [2,4,5]
}
output "test" {
value = [for i in range(1, var.vm_count + length(var.exclusion) + 1) : {
name = "some-server-${i}"
} if !contains(var.exclusion, i)]
}
这给出:
Changes to Outputs:
+ test = [
+ {
+ name = "some-server-1"
},
+ {
+ name = "some-server-3"
},
+ {
+ name = "some-server-6"
},
+ {
+ name = "some-server-7"
},
+ {
+ name = "some-server-8"
},
]
当然,在这里,您开始遇到边缘情况,如果排除列表包含超出范围的数字,您可能会有太多 VM,但这完全取决于您的用例的复杂性。
我正在尝试使用 for_each 循环在 Azure 中创建多个 VM。假设虚拟机 1-100。但是,会有删除请求,即 VM 编号 50。
我有两个问题:
terraform_azure> terraform state list
module.edit_vms.azurerm_linux_virtual_machine.test_seat["test-vm-1"]
terraform state rm module.edit_vms.azurerm_linux_virtual_machine.test_seat["test-vm-1"]
zsh: no matches found: module.edit_vms.azurerm_linux_virtual_machine.test_seat[test-vm-1]
当我尝试从 Terraform 状态中删除 VM 50 时,出现上述错误。我不明白为什么当资源列在 terraform state list command
下时我没有看到匹配项有没有办法删除 50 号 VM 并将 VM 计数设置为 1 -> 101 并防止 terraform 重新创建 50 号 VM?如果从状态文件中删除 VM 不是一个好的做法,那么如果我可以在代码中指定我希望它被销毁而不是在将来应用时重新创建,那就更好了。
这是我的variables.tf
variable "edit_seat_spec" {
description = "VM details"
type = list
default = [{
resource_group_name = "my_rg"
server_name = "test-vm"
server_size = "Standard_B2s"
location = "East US"
vnet = "test_vnet"
subnet_name = "default"
username = "username"
password = "password"
vm_count = "4"
}]
}
和main.tf
locals{
edit_seat = [
for edit in var.edit_seat_spec : [
for i in range(1, edit.vm_count) : {
name = "${edit.server_name}-${i}"
resource_group = edit.resource_group_name
vnet = edit.vnet
nic = "${edit.server_name}-${i}-nic"
location = edit.location
subnet_name = edit.subnet_name
size = edit.server_size
admin_username = edit.username
admin_password = edit.password
}
]
]
}
locals {
edit_vm = flatten(local.edit_seat)
}
resource "azurerm_linux_virtual_machine" "vm" {
for_each = {for edit in local.edit_vm: edit.name => edit}
name = each.value.name
resource_group_name = each.value.resource_group
location = each.value.location
size = each.value.size
admin_username = each.value.admin_username
admin_password = each.value.admin_password
disable_password_authentication = false
network_interface_ids = [azurerm_network_interface.edit_seat_nic[each.key].id]
os_disk {
caching = "ReadWrite"
storage_account_type = "Standard_LRS"
}
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "16.04-LTS"
version = "latest"
}
}
您可以过滤 for
、with the help of if
statement.
另请注意,range
不会包括上限:
The interpretation of
limit
depends on the direction ofstep
: for a positive step, the sequence is complete when the next number is greater than or equal tolimit
.
因此,如果您想要 1 到 100 的范围,则需要 range(1, var.variable_that_contains_100 + 1)
。
因此,如果你想跳过从 1 到 100 的步进中的一个元素,你需要将上限设置为 102。
这里是一个示例,请求 5 个元素,跳过 3 个,为简洁起见:
variable "vm_count" {
default = 5
}
output "test" {
value = [for i in range(1, var.vm_count + 2) : {
name = "some-server-${i}"
} if i != 3]
}
这产生:
Changes to Outputs:
+ test = [
+ {
+ name = "some-server-1"
},
+ {
+ name = "some-server-2"
},
+ {
+ name = "some-server-4"
},
+ {
+ name = "some-server-5"
},
+ {
+ name = "some-server-6"
},
]
如果你想排除一个列表,正如问题的标题所述,你可以使用排除列表的 contains
instead in the condition, then increase the upper limit based on the length
加一。
variable "vm_count" {
default = 5
}
variable "exclusion" {
default = [2,4,5]
}
output "test" {
value = [for i in range(1, var.vm_count + length(var.exclusion) + 1) : {
name = "some-server-${i}"
} if !contains(var.exclusion, i)]
}
这给出:
Changes to Outputs:
+ test = [
+ {
+ name = "some-server-1"
},
+ {
+ name = "some-server-3"
},
+ {
+ name = "some-server-6"
},
+ {
+ name = "some-server-7"
},
+ {
+ name = "some-server-8"
},
]
当然,在这里,您开始遇到边缘情况,如果排除列表包含超出范围的数字,您可能会有太多 VM,但这完全取决于您的用例的复杂性。