首页 > 解决方案 > Terraform Azure:从打包程序映像和外部数据磁盘创建 Linux VM

问题描述

我一直在尝试在 Azure 中对 Terraform 进行以下设置,但无济于事:

来自 Packer 创建的自定义 VM 映像的 Linux VM,附加了一个附加到所述 VM 的持久、托管和加密的数据磁盘,但它位于外部,以防我想使用更新(更新、安全)版本的自定义重新创建 VM图像,而不会丢失保存到外部磁盘的任何数据(想象数据库集群中的一个节点)。并继续执行以下操作:

  1. 最初,我尝试将azurerm_managed_diskand aazurerm_virtual_machine_data_disk_attachment与 VM 资源一起使用,但问题是,如果您只是创建这样的磁盘(create_option设置为Empty),则该磁盘将未格式化、未分区和卸载。除非在 VM 上运行某些脚本,否则基本上无法使用。
  2. 我的想法是:好的,我将运行一个cloud-init或配置块的东西来分区/安装磁盘,就是这样。但是:如果我这样做,当我旋转虚拟机时,脚本将再次运行并重新格式化/分区磁盘,从而删除我可能保存的所有数据。
  3. 我还尝试使用 Packer 创建带有附加数据磁盘的自定义图像,并FromImageazurerm_managed_disk's中使用create_option,但事实证明它仅在引用市场图像且不支持自定义图像时才有效

我现在能想到的唯一可行的事情是回到方法2并制作一个更智能的脚本,该脚本仅在附加磁盘分区时运行。

有没有我没有看到的替代方法?有人可以帮我验证这个想法吗?

我另外担心的是上述磁盘中的加密,因为我不知道在采用任何一种方法时这是否会成为一个问题。

标签: azureterraformpackerterraform-provider-azureinfrastructure-as-code

解决方案


首先,您可以通过 Terraform 从自定义镜像创建 Azure VM,无论您如何创建镜像、Packer 或其他方式,更多详细信息请参阅在 Terraform 中配置自定义镜像

但是当你使用自定义镜像并想加密数据盘时,问题就来了。

当前不支持在使​​用自定义 Linux 映像时进行磁盘加密。

更多详细信息,请参阅加密的要求和限制

另外,要将数据盘挂载到虚拟机上,我想你可以使用虚拟机扩展来实现。并将托管数据磁盘附加到 VM,您只需storage_data_disk在 Terraform 代码的 VM 配置中添加块,如下所示:

resource "azurerm_virtual_machine" "main" {
  name                  = "${var.prefix}-vm"
  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"

  # Uncomment this line to delete the OS disk automatically when deleting the VM
  # delete_os_disk_on_termination = true


  # Uncomment this line to delete the data disks automatically when deleting the VM
  # delete_data_disks_on_termination = true

  ...

  storage_data_disk {
    name          = "datadisk0"
    vhd_uri       = "${azurestack_storage_account.test.primary_blob_endpoint}${azurestack_storage_container.test.name}/datadisk0.vhd"
    disk_size_gb  = "1023"
    create_option = "Empty"
    lun           = 0
  }

  ...

  tags {
    environment = "staging"
  }
}

编辑

恐怕您需要使用 vm storage_image_reference 中的自定义图像 id。您可以使用数据 azurerm_image 在您的组中引用您的自定义图像。像这样的代码:

data "azurerm_image" "custom" {
    name = "your_custom_image_name"
    resource_group_name = "your_group"
}

resource "azurerm_virtual_machine" "main" {
    ...

    storage_image_reference {
        id = "${data.azurerm_image.custom.id}"
    }

    ...
}

推荐阅读