Unable to execute custom data in azure VM from ter

2019-08-16 03:53发布

问题:

I'm trying to create azure vm using terraform . But unable to execute custom data from terraform. Customdata.bin file is created on server . Also tried provisioner resource but no luck .

main.tf file azure vm resource syntax :

resource "azurerm_virtual_machine" "avmweb0" {
  name                  = "${var.env}-${var.bu}-${var.company_name}-media-vm"
  location              = "${var.region}"
  resource_group_name   = "${module.network.resource-grp-name}"
  network_interface_ids = ["${azurerm_network_interface.nicweb0.id}"]
  vm_size               = "${var.vm_size}"


  storage_image_reference {
    publisher       = "${var.vm_publisher}"
    offer           = "${var.vm_offer}"
    sku             = "${var.vm_sku}"
    version         = "${var.vm_version}"

  }

  storage_os_disk {
    name              = "${var.env}-${var.bu}-${var.company_name}-media-osdisk"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Standard_LRS"
  }



  os_profile {
    computer_name  = "${var.env}-${var.vm_computer_name}"
    admin_username = "${var.vm_admin_username}"
    admin_password = "${var.vm_admin_password}"
    custom_data    = "${data.template_file.userdata.rendered}" 
  }

   os_profile_windows_config{
     winrm {
       protocol="http"
     }

    }

   /* 
     connection {
      type     = "winrm"
      user     = "${var.vm_admin_username}"
      password = "${var.vm_admin_password}"
      host     = "${azurerm_public_ip.mediapubip.ip_address}"
      port     = 5985
      https    = false
      insecure = true
      timeout      = "15m"
      # cacert       = ""
    } */

   /* provisioner "file" {
    content      = "${data.template_file.userdata.rendered}"
    destination = "C:\\AzureData\\initdata.ps1"

    connection {
      type     = "winrm"
      user     = "${var.vm_admin_username}"
      password = "${var.vm_admin_password}"
    }
  }
   provisioner "remote-exec" {


    inline = [ "powershell.exe -ExecutionPolicy unrestricted -NoProfile -NonInteractive -File \"C:\\AzureData\\initdata.ps1\""]


  }  */

  /* provisioner "file" {
    content      = "${data.template_file.userdata.rendered}"
    destination = "C:\\AzureData\\initdata.ps1"
  }

   provisioner "local-exec" {
    command = "powershell.exe -ExecutionPolicy RemoteSigned -File \"C:\\AzureData\\initdata.ps1\" -NoProfile -NonInteractive "
  } */

  tags {
        Name            = "${var.env}-${var.bu}-${var.company_name}-media"
        BussinessUnit   = "${var.bu}"
        Environment     = "${var.env}"
        CompanyName     = "${var.company_name}"
        Application     = "${var.appname}"
   }
}

------------custom data file ---------------------------------

Set-ExecutionPolicy unrestricted
netsh advfirewall firewall add rule name="http" dir=in action=allow protocol=TCP localport=80

write-host "running init script"
if(!(test-path -Path "c:\temp"))
  {    
    New-Item -ItemType directory -Path "C:\temp"
    write-host "created temp directory"
  }
$client = new-object System.Net.WebClient
$client.DownloadFile("https://downloads.puppetlabs.com/windows/puppet5/puppet-agent-5.0.0-x64.msi","c:\temp\puppet.msi")
cd "c:\temp"
pwd
echo "`nx.x.x.x puppet"  | Out-File -FilePath "C:\Windows\System32\drivers\etc\hosts" -Append -Encoding ascii
msiexec /qn /norestart /i "c:\temp\puppet.msi" 
if(test-path -path "C:\ProgramData\PuppetLabs\facter\facts.d")
  {
    echo "`nhello"  | Out-File -FilePath "C:\ProgramData\PuppetLabs\facter\facts.d\facts.yaml" -Encoding ascii
    echo "`nconsolename : ${consolename}" | Out-File -FilePath "C:\ProgramData\PuppetLabs\facter\facts.d\facts.yaml" -Append -Encoding ascii
    echo "`nbu : ${bu}" | Out-File -FilePath "C:\ProgramData\PuppetLabs\facter\facts.d\facts.yaml" -Append -Encoding ascii
    echo "`nenv : ${env}" | Out-File -FilePath "C:\ProgramData\PuppetLabs\facter\facts.d\facts.yaml" -Append -Encoding ascii            
    echo "`ncompany_name : ${company_name}" | Out-File -FilePath "C:\ProgramData\PuppetLabs\facter\facts.d\facts.yaml" -Append -Encoding ascii
    echo "`napplication : ${application}" |  Out-File -FilePath "C:\ProgramData\PuppetLabs\facter\facts.d\facts.yaml" -Append -Encoding ascii
    echo "`nservertype : ${servertype}" |  Out-File -FilePath "C:\ProgramData\PuppetLabs\facter\facts.d\facts.yaml" -Append -Encoding ascii
 }

Error when using provisioner resource : 1 error(s) occurred:

  • azurerm_virtual_machine.avmweb0: 1 error(s) occurred:

  • unknown error Post http://x.x.x.x:5985/wsman: dial tcp x.x.x.x:5985: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

Terraform does not automatically rollback in the face of errors. Instead, your Terraform state file has been partially updated with any resources that successfully completed. Please address the error above and apply again to incrementally change your infrastructure.[0m[0m

code :

resource "azurerm_virtual_machine_extension" "avmme0" {
  name                 = "${var.env}-${var.vm_computer_name}-config"
  location             = "West US"
  resource_group_name  = "${module.network.resource-grp-name}"
  virtual_machine_name = "${azurerm_virtual_machine.avmweb0.name}"
  publisher            = "Microsoft.Compute"
  type                 = "CustomScriptExtension"
  type_handler_version = "1.8"

  settings = <<SETTINGS
    {
        "fileUris": ["https://raw.githubusercontent.com/saveshnshetty/devops/master/userdata.ps1"],
        "commandToExecute": "powershell.exe -ExecutionPolicy unrestricted -NoProfile -NonInteractive -File userdata.ps1"
    }
SETTINGS

  tags {
        Name            = "${var.env}-${var.bu}-${var.company_name}-media"
        BussinessUnit   = "${var.bu}"
        Environment     = "${var.env}"
        CompanyName     = "${var.company_name}"
        Application     = "${var.appname}"
   }
}

error : [0m[1mazurerm_virtual_machine_extension.avmme0: Still creating... (25m20s elapsed)[0m[0m [31mError applying plan:

1 error(s) occurred:

  • azurerm_virtual_machine_extension.avmme0: 1 error(s) occurred:

  • azurerm_virtual_machine_extension.avmme0: compute.VirtualMachineExtensionsClient#CreateOrUpdate: Failure sending request: StatusCode=200 -- Original Error: Long running operation terminated with status 'Failed': Code="VMAgentStatusCommunicationError" Message="VM 'dev-it-mactores-media-vm' has not reported status for VM agent or extensions. Please verify the VM has a running VM agent, and can establish outbound connections to Azure storage."

I'm able to download from server with below commands : $client = new-object System.Net.WebClient $client.DownloadFile("https://raw.githubusercontent.com/saveshnshetty/devops/master/userdata.ps1","c:\temp\userdata.ps1")

Inbound and outbound rule is open for 5985 .

Tf var file  details :
region                  ="West US"
storage_account_type    =""
vm.size                 ="Standard_DS1_v2"
location                ="West US"
appname                 ="xxx"
bu                      ="it"
company_name            ="xxxx"
env                     ="dev"
tenant_id               =""
client_secret           =""
client_id               =""
storage_account_type    ="Standard_LRS"
vm_size                 = "Standard_DS1_v2"
vm_publisher            = "MicrosoftWindowsServer"
vm_offer                = "WindowsServer"
vm_sku                  = "2012-R2-Datacenter"
vm_version              = "latest"
vm_computer_name        = "web-media"
vm_admin_username       = "xxxx"
vm_admin_password       = "xxxx"

回答1:

The reason for the error log is you don't open port 5985 on Azure NSG. So, your script could not connect to Azure VM. For a Azure VM, I suggest you could use Custom Script Extension instead winrm your VM.

The Custom Script Extension downloads and executes scripts on Azure virtual machines. This extension is useful for post deployment configuration, software installation, or any other configuration / management task.

Terraform also support custom script extension. Please refer to this link. According to your scenario, I suggest you save your custom data as a ps1 file and upload it to GitHub or Azure storage account. You could refer to my answer. Windows Custom Script extension should use like below:

resource "azurerm_virtual_machine_extension" "test" {
  name                 = "hostname"
  location             = "West US"
  resource_group_name  = "${azurerm_resource_group.test.name}"
  virtual_machine_name = "${azurerm_virtual_machine.test.name}"
  publisher            = "Microsoft.Compute"
  type                 = "CustomScriptExtension"
  type_handler_version = "1.8"

   settings = <<SETTINGS
    {
        "fileUris": ["https://raw.githubusercontent.com/saveshnshetty/devops/master/userdata.ps1"],
        "commandToExecute": "powershell.exe -ExecutionPolicy unrestricted -NoProfile -NonInteractive -File userdata.ps1"
    }
SETTINGS

You could check my vm.tf.