Terraform 从 Packer 中制作的托管磁盘映像创建 VM

Posted

技术标签:

【中文标题】Terraform 从 Packer 中制作的托管磁盘映像创建 VM【英文标题】:Terraform creating VM from managed disk image made in Packer 【发布时间】:2018-06-13 06:24:16 【问题描述】:

我已经使用 Packer 创建了一个自定义 VM 映像,现在我正在尝试使用 Terraform 基于此映像创建一个新 VM,但我对如何设置我的 .TF 文件感到困惑。我可以创建其余的基础设施。

我认为我的打包程序 json 文件创建了一个托管磁盘映像,但我不确定如何设置它并且无法在线找到示例。

我对基础设施即代码和 Azure ecco 系统很陌生

main.tf

    resource "azurerm_managed_disk" "managedDisk" 
  name                 = "managed_disk_test1"
  location             = "northeurope"
  resource_group_name  = "$azurerm_resource_group.packer.name"
  storage_account_type = "Standard_LRS"
  create_option        = "FromImage"
  image_reference_id   = "/subscriptions/33efe2dc-e7a0-4fb8-827d-8be939879420/resourceGroups/packerRG/providers/Microsoft.Compute/images/myPackerImage"
  disk_size_gb         = "1"



resource "azurerm_virtual_machine" "PackerVm_TEST" 
    name =  "$var.hostname"
    location = "northeurope"
    resource_group_name   = "$azurerm_resource_group.packer.name"
network_interface_ids = ["$azurerm_network_interface.packerNetInt_Test.id"]
    vm_size = "Standard_D2s_v3"


    storage_os_disk 
        name            = "FromPackerImageOsDisk"
        managed_disk_type = "Standard_LRS"
        caching           = "ReadWrite"
        create_option     = "FromImage"
    

        os_profile 
            computer_name  = "PackerVmTEST"
            admin_username = "packermakeradmin1"
            admin_password = "RMKRTest123"
          
            os_profile_windows_config 
                enable_automatic_upgrades = "true"
                provision_vm_agent ="true"
            


packer.json


  "builders": [
    "type": "azure-arm",

    "client_id": "",
    "client_secret": "",
    "tenant_id": "",
    "subscription_id": "",
    "object_id": "",

    "managed_image_resource_group_name": "packerRG",
    "managed_image_name": "myPackerImage",

    "os_type": "Windows",
    "image_publisher": "MicrosoftWindowsServer",
    "image_offer": "WindowsServer",
    "image_sku": "2016-Datacenter",

    "communicator": "winrm",
    "winrm_use_ssl": "true",
    "winrm_insecure": "true",
    "winrm_timeout": "3m",
    "winrm_username": "packer",

    "azure_tags": 
        "dept": "Engineering",
        "task": "Image deployment"
    ,

    "location": "northeurope",
    "vm_size": "Standard_DS2_v2"
  ],
  "provisioners": [
    "type": "powershell",
    "inline": [
      "Add-WindowsFeature Web-Server",
      "if( Test-Path $Env:SystemRoot\\windows\\system32\\Sysprep\\unattend.xml ) rm $Env:SystemRoot\\windows\\system32\\Sysprep\\unattend.xml -Force",
      "& $Env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /shutdown /quiet"
    ]
  ]

运行 terraform apply 时的输出

* azurerm_virtual_machine.PackerVm_TEST: compute.VirtualMachinesClient#CreateOrUpdate: Failure responding to request: StatusCode=400 -- Original Error: autorest/azure: Service returned an error. Status=400 Code="InvalidParameter" Message="Cannot specify user ima
ge overrides for a disk already defined in the specified image reference."

【问题讨论】:

【参考方案1】:

有两种方法可以将托管磁盘附加到 VM。

要么删除 azure_managed_disk 资源,要么在 azurerm_virtual_machine 资源中指定映像引用。托管磁盘将自动创建并附加到 VM。

resource "azurerm_virtual_machine" "PackerVm_TEST" 
name =  "$var.hostname"
location = "northeurope"
resource_group_name   = "$azurerm_resource_group.packer.name"
network_interface_ids = ["$azurerm_network_interface.packerNetInt_Test.id"]
vm_size = "Standard_D2s_v3"

storage_os_disk 
    name            = "FromPackerImageOsDisk"
    managed_disk_type = "Standard_LRS"
    caching           = "ReadWrite"
    create_option     = "FromImage"

storage_image_reference 
    id = "/subscriptions/33efe2dc-e7a0-4fb8-827d-8be939879420/resourceGroups/packerRG/providers/Microsoft.Compute/images/myPackerImage"


os_profile 
    computer_name  = "PackerVmTEST"
    admin_username = "packermakeradmin1"
    admin_password = "RMKRTest123"
  
os_profile_windows_config 
    enable_automatic_upgrades = "true"
    provision_vm_agent ="true"

或者您在 azurerm_virtual_machine 资源中添加托管磁盘 ID。

resource "azurerm_managed_disk" "managedDisk" 
  name                 = "managed_disk_test1"
  location             = "northeurope"
  resource_group_name  = "$azurerm_resource_group.packer.name"
  storage_account_type = "Standard_LRS"
  create_option        = "FromImage"
  image_reference_id   = "/subscriptions/33efe2dc-e7a0-4fb8-827d-8be939879420/resourceGroups/packerRG/providers/Microsoft.Compute/images/myPackerImage"
  disk_size_gb         = "1"


resource "azurerm_virtual_machine" "PackerVm_TEST" 
    name =  "$var.hostname"
    location = "northeurope"
    resource_group_name   = "$azurerm_resource_group.packer.name"
    network_interface_ids = ["$azurerm_network_interface.packerNetInt_Test.id"]
    vm_size = "Standard_D2s_v3"

    storage_os_disk 
        name            = "FromPackerImageOsDisk"
        managed_disk_id = "$azurerm_managed_disk.managedDisk.id"
        managed_disk_type = "Standard_LRS"
        caching           = "ReadWrite"
        create_option     = "Attach"
    
    os_profile 
        computer_name  = "PackerVmTEST"
        admin_username = "packermakeradmin1"
        admin_password = "RMKRTest123"
      
    os_profile_windows_config 
        enable_automatic_upgrades = "true"
        provision_vm_agent ="true"
    

来自 terraform 文档

managed_disk_id - (可选)指定一个现有的托管磁盘以按 id 使用。只能在 create_option 为 Attach 时使用。

【讨论】:

不幸的是,这种语法实际上不起作用。您目前不能引用除平台/市场图像之外的任何内容:github.com/terraform-providers/terraform-provider-azurerm/…【参考方案2】:

我在 .TF 文件中添加了以下代码,它工作正常。感谢您的帮助!

storage_image_reference 
    id = "/subscriptions/33efe2dc-e7a0-4fb8-827d-8be939879420/resourceGroups/packerRG/providers/Microsoft.Compute/images/myPackerImage"

【讨论】:

suresh,请不要添加 "thanks" 作为答案。它们实际上并没有提供问题的答案,并且可能被未来的访问者视为噪音。一旦你earn足够reputation,你将获得upvote answers你喜欢的特权。这样,问题的未来访问者将看到对该答案的更高投票数,并且回答者也将获得声誉积分奖励。见Why is voting important。

以上是关于Terraform 从 Packer 中制作的托管磁盘映像创建 VM的主要内容,如果未能解决你的问题,请参考以下文章

使用 Helm 而不是 Terraform 的困惑

Vagrant - 使用 Packer 制作 Box 虚拟机镜像

Terraform 学习总结—— 基于 AWS 云平台上的 Terraform 实战

Packer 自定义映像构建失败并出现 ssh 身份验证错误

Terraform:如何从数据类型中获取元素

如何使用服务托管标识在 Azure 中使用 Terraform 预配资源