You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Azure Terraform中优雅使用azurerm_virtual_machine_extension执行多命令

优雅地在Azure VM扩展中执行多行Linux命令

你可以通过以下几种方式替代&&堆砌命令的写法,让代码更易读和维护:

方法1:在HCL中拆分命令行(保留JSON字符串格式)

利用HCL的多行字符串特性,将命令拆分为多行,同时用\连接HCL中的行(确保JSON字符串是连续的),bash会正确识别命令链:

resource "azurerm_virtual_machine_extension" "run_command" {
  for_each             = var.vm_template
  name                 = "${each.value.vm_name}-run_command"
  virtual_machine_id   = azurerm_linux_virtual_machine.vm[each.key].id
  publisher            = "Microsoft.Azure.Extensions"
  type                 = "CustomScript"
  type_handler_version = "2.0"
  timeouts {
    create = "1h" # VM数量多的话耗时更长
  }
  settings = <<SETTINGS
 {
  "commandToExecute": "bash -c 'hostnamectl set-hostname --static ${each.value.hostname} && \\
sleep 60 && \\
sh /tmp/for_image.sh > /tmp/installed.log 2>&1'"
 }
SETTINGS
}

方法2:嵌入临时脚本(通过bash here-doc)

将多行命令写入临时脚本文件再执行,避免长命令串:

resource "azurerm_virtual_machine_extension" "run_command" {
  for_each             = var.vm_template
  name                 = "${each.value.vm_name}-run_command"
  virtual_machine_id   = azurerm_linux_virtual_machine.vm[each.key].id
  publisher            = "Microsoft.Azure.Extensions"
  type                 = "CustomScript"
  type_handler_version = "2.0"
  timeouts {
    create = "1h"
  }
  settings = <<SETTINGS
 {
  "commandToExecute": "bash -c 'cat <<EOF > /tmp/setup.sh && chmod +x /tmp/setup.sh && /tmp/setup.sh
hostnamectl set-hostname --static ${each.value.hostname}
sleep 60
sh /tmp/for_image.sh > /tmp/installed.log 2>&1
EOF'"
 }
SETTINGS
}

这里利用HCL heredoc特性保留换行,bash会将here-doc内容写入临时脚本并执行。

方法3:使用外部脚本文件(最推荐)

将命令写入独立的shell脚本,上传到Azure Blob Storage,通过CustomScript扩展拉取执行。这种方式适合复杂命令集,便于版本控制和维护:

步骤1:创建外部脚本(setup.sh)

#!/bin/bash
TARGET_HOSTNAME=$1

hostnamectl set-hostname --static $TARGET_HOSTNAME
sleep 60
sh /tmp/for_image.sh > /tmp/installed.log 2>&1

步骤2:更新Terraform配置

resource "azurerm_virtual_machine_extension" "run_command" {
  for_each             = var.vm_template
  name                 = "${each.value.vm_name}-run_command"
  virtual_machine_id   = azurerm_linux_virtual_machine.vm[each.key].id
  publisher            = "Microsoft.Azure.Extensions"
  type                 = "CustomScript"
  type_handler_version = "2.0"
  timeouts {
    create = "1h"
  }

  settings = <<SETTINGS
 {
  "fileUris": ["https://your-storage-account.blob.core.windows.net/scripts/setup.sh"],
  "commandToExecute": "bash setup.sh ${each.value.hostname}"
 }
SETTINGS

  protected_settings = <<PROTECTED_SETTINGS
 {
  "storageAccountName": "your-storage-account-name",
  "storageAccountKey": "${azurerm_storage_account.your_sa.primary_access_key}"
 }
PROTECTED_SETTINGS
}

这种方式将命令逻辑与Terraform配置分离,脚本可单独编辑、测试,大幅提升可维护性。

内容的提问来源于stack exchange,提问作者gotothesky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 04:17:14