Terraform部署Azure虚拟机时自定义主机名不生效问题求助
Azure Terraform部署自定义镜像VM时主机名不生效的解决方法
问题描述
使用自定义Rocky Linux镜像通过Terraform部署Azure虚拟机,已在azurerm_linux_virtual_machine的computer_name字段设置自定义主机名(如test-vm),但部署后VM主机名仍固定为镜像中的rockylinuximage01,无法生效。
相关代码
var.tf
variable "vm_template" { type = map(any) default = { vm1 = { source_image_id = "/subscriptions/00000/resourceGroups/image/providers/Microsoft.Compute/images/new-image-rocky8" vm_name = "test-vm" hostname = "test-vm" os_publisher = "resf" os_offer = "rockylinux-x86_64" os_sku = "8-base" os_version = "8.9.20231119" osdisk_type = "StandardSSD_LRS" osdisk_size = "32" vm_type = "Standard_D2s_v5" nic = "nic01" os_disk = "osdisk01" } } }
vm.tf
data "azurerm_key_vault" "kv" { name = var.kv_name resource_group_name = var.kv_rg } data "azurerm_key_vault_secret" "password" { name = var.kv_secret_name key_vault_id = data.azurerm_key_vault.kv.id } data "azurerm_resource_group" "system_rg_name" { name = var.system_rg } data "azurerm_subnet" "network_subnet" { name = var.network_subnet virtual_network_name = var.network_vnet resource_group_name = var.network_rg } resource "azurerm_network_interface" "nic" { for_each = var.vm_template name = "${each.value.vm_name}-${each.value.nic}" location = var.location resource_group_name = data.azurerm_resource_group.system_rg_name.name enable_accelerated_networking = true ip_configuration { name = "internal" subnet_id = data.azurerm_subnet.network_subnet.id private_ip_address_allocation = var.private-ip-type private_ip_address = each.value.private_ip } } resource "azurerm_linux_virtual_machine" "vm" { for_each = var.vm_template name = each.value.vm_name location = var.location resource_group_name = data.azurerm_resource_group.system_rg_name.name source_image_id = each.value.source_image_id zone = each.value.zone #### VM Instance Type size = each.value.vm_type network_interface_ids = [ azurerm_network_interface.nic[each.key].id, ] identity { type = "SystemAssigned" } os_disk { name = "${each.value.vm_name}-${each.value.os_disk}" caching = "ReadWrite" # ReadOnly, ReadWrite storage_account_type = each.value.osdisk_type disk_size_gb = each.value.osdisk_size } plan { name = each.value.os_sku publisher = each.value.os_publisher product = each.value.os_offer } computer_name = each.value.hostname admin_username = var.adminid admin_password = data.azurerm_key_vault_secret.password.value disable_password_authentication = false lifecycle { ignore_changes = [ admin_password, ] } }
解决方案
核心原因
Azure Linux VM的computer_name参数需要依赖cloud-init读取Azure实例元数据服务的配置来生效。如果自定义镜像未正确配置cloud-init,或镜像中硬编码了主机名,就会导致Terraform设置的主机名无法覆盖镜像原有值。
具体修复步骤
1. 修复自定义镜像的cloud-init配置
在制作自定义镜像的源VM上执行以下操作:
- 安装cloud-init及Azure相关依赖:
sudo dnf install -y cloud-init cloud-utils-growpart - 配置Azure为cloud-init的数据源:
创建/编辑/etc/cloud/cloud.cfg.d/90-azure.cfg,写入以下内容:datasource_list: [ Azure ] datasource: Azure: metadata_urls: [ 'http://169.254.169.254/metadata/instance?api-version=2021-02-01' ] wait_for_metadata_service: True - 清理旧主机名残留:
sudo rm -f /etc/hostname sudo sed -i '/rockylinuximage01/d' /etc/hosts - 重置cloud-init状态,准备制作镜像:
sudo cloud-init clean --logs --seed sudo poweroff - 基于该关机状态的VM重新生成自定义镜像。
2. Terraform代码兜底优化(可选)
如果暂时无法重新制作镜像,可以在azurerm_linux_virtual_machine资源中添加custom_data,强制cloud-init启动时设置主机名:
resource "azurerm_linux_virtual_machine" "vm" { # 原有配置... computer_name = each.value.hostname # 添加以下custom_data配置 custom_data = base64encode(<<-EOF #cloud-config hostname: ${each.value.hostname} preserve_hostname: false EOF ) # 原有配置... }
验证方法
部署完成后,登录VM执行hostname命令,确认输出为Terraform中设置的test-vm。
内容的提问来源于stack exchange,提问作者gotothesky
相关产品推荐
相关产品推荐

