从 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]
  1. 当我尝试从 Terraform 状态中删除 VM 50 时,出现上述错误。我不明白为什么当资源列在 terraform state list command

    下时我没有看到匹配项
  2. 有没有办法删除 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"
      }
    }

您可以过滤 forwith 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,但这完全取决于您的用例的复杂性。