5

I'm trying to run a bash script on an Azure VM after deploying it with Terraform. I've tried different approaches but none of them have worked. With "custom_data", I assumed that the file will be uploaded and executed, however I'm not even seeing the file inside the VM.

I've also looked at "azurerm_virtual_machine_extension", but this does not give me the option to upload the file, only to execute commands or download from remote location (can't use fileUris due to requirements):

resource "azurerm_virtual_machine_extension" "test" {
  name                 = "hostname"
  location             = "${azurerm_resource_group.test.location}"
  resource_group_name  = "${azurerm_resource_group.test.name}"
  virtual_machine_name = "${azurerm_virtual_machine.test.name}"
  publisher            = "Microsoft.Azure.Extensions"
  type                 = "CustomScript"
  type_handler_version = "2.0"

  settings = <<SETTINGS
    {
        "commandToExecute": "sh my_script.sh"
    }
SETTINGS

  tags = {
    environment = "Production"
  }
}
resource "azurerm_virtual_machine" "middleware_vm" {
    name                  = "${var.middleware_vm}"
    location              = "${var.location}"
    resource_group_name   = "${azurerm_resource_group.middleware.name}"
    network_interface_ids = ["${azurerm_network_interface.middleware.id}"]
    vm_size               = "Standard_DS4_v2"        

    storage_os_disk {
        name              = "centos_os_disk"
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Premium_LRS"
    }

    storage_data_disk {
        name                 = "managed_backup_disk"
        create_option        = "Empty"
        caching              = "ReadWrite"
        disk_size_gb         = "256"  
        managed_disk_type    = "Premium_LRS"
        lun                  = 0
    }

    storage_image_reference {
        publisher = "OpenLogic"
        offer     = "CentOS"
        sku       = "7.5"
        version   = "latest"
    }

    os_profile {
        computer_name  = "${var.middleware_vm}"
        admin_username = "middlewareadmin"
        custom_data    = "${file("scripts/middleware_disk.sh")}"
  }

2 Answers 2

5

In azurerm_virtual_machine_extension, you can use:

protected_settings = <<PROTECTED_SETTINGS
{
    "script": "${base64encode(file(var.scfile))}"
}
PROTECTED_SETTINGS

Please refer to my answer

Sign up to request clarification or add additional context in comments.

Comments

1

First, the VM extension will just execute the script and do not copy the file to the VM. If you want to copy the script into the VM and then execute it. I will suggest you the Terraform provisioner file and remote-exec.

Here is the example that copies the file into the existing VM and executes the script:

resource "null_resource" "example" {

    connection {
        type = "ssh"
        user = "azureuser"
        password = "azureuser@2018"
        host = "13.92.255.50"
        port = 22
    }
    provisioner "file" {
        source = "script.sh"
        destination = "/tmp/script.sh"
    }

    provisioner "remote-exec" {
        inline = [
            "/bin/bash /tmp/script.sh"
        ]
    }
}

Note: the script should be created in the current directory.

9 Comments

thanks, however this won't work for us. the VMs cannot be exposed to the internet, that's why I wanted to use "custom_data" or ""azurerm_virtual_machine_extension"
@MarioJacobo First, there is nothing shows the VM does not expose to the Internet. And you also do not show the exact requirement and which error you got.
@MarioJacobo If you do not expose the VM to the internet, how do you use the VM?
there is no error whatsoever, it's just that nothing is ran or uploaded to the VM, using custom_data = "${file("scripts/middleware_disk.sh")}". I was hoping to use "custom_data" to upload the file and then "azurerm_virtual_machine_extension" to execute the script. The VM just performs some cron tasks internally and does not need to be exposed to the internet at all, due to sensitive data on disk. I may need to use an ARM template (where I encoded the script to base64) and inject that with Terraform. It's not ideal as but it's the only option I see
after a bit more testing, I decided to use ARM template with "azurerm_template_deployment" as "azurerm_virtual_machine_extension" or "custom_data" didnt work. The ARM template can process all bash scripts base64-encoded.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.