Azure VirtualMachine

Azure VirtualMachine

Certified
Enterprise Edition

Task runner that executes a task natively on an Azure Virtual Machine

Enterprise Edition only.

Runs the task's commands on an Azure VM via the Azure Run Command API: no SSH, no container. containerImage is ignored.

The VM has no public IP and no inbound rules: Run Command reaches it through the Azure control plane.

To create a VM, set subnetId to an existing subnet. The runner never creates a virtual network.

vmName targets an existing VM, which is never stopped or deleted. stopVm/deleteVm (both default true) apply only to VMs the runner created, and are honored on success, failure, or kill. Deleting a created VM also removes its network interface and OS disk.

Staging inputFiles, outputFiles, namespaceFiles, or {{ outputDir }} needs blobStorage: the Worker stages files via Blob Storage and gives the VM a short-lived, container-scoped SAS token used with plain curl (no Azure CLI assumed). The subnet needs outbound access to Blob Storage or staging fails.

Run Command is synchronous with no reattachable command ID, so on a Worker restart resume re-issues the command against the same VM: commands should tolerate running more than once.

Command output is only returned once the command completes, there is no live log streaming, and Azure truncates captured stdout/stderr to about 4 KB per stream, so a very verbose task may lose part of its output.

yaml
type: io.kestra.plugin.ee.azure.runner.VirtualMachine

Run a Python script on a new Azure VM.

yaml
id: azure_vm_python_task
namespace: company.team

tasks:
  - id: run_python
    type: io.kestra.plugin.scripts.python.Script
    taskRunner:
      type: io.kestra.plugin.ee.azure.runner.VirtualMachine
      tenantId: "{{ secret('AZURE_TENANT_ID') }}"
      clientId: "{{ secret('AZURE_CLIENT_ID') }}"
      clientSecret: "{{ secret('AZURE_CLIENT_SECRET') }}"
      subscriptionId: "{{ secret('AZURE_SUBSCRIPTION_ID') }}"
      resourceGroupName: kestra-runners
      region: eastus
      vmSize: Standard_DS2_v2
      subnetId: "/subscriptions/{{ secret('AZURE_SUBSCRIPTION_ID') }}/resourceGroups/kestra-runners/providers/Microsoft.Network/virtualNetworks/kestra-vnet/subnets/kestra-subnet"
    script: |
      print("Hello from Azure VM!")

Reuse an existing VM and keep it running after the task completes.

yaml
id: azure_vm_reuse
namespace: company.team

tasks:
  - id: process
    type: io.kestra.plugin.scripts.shell.Commands
    taskRunner:
      type: io.kestra.plugin.ee.azure.runner.VirtualMachine
      tenantId: "{{ secret('AZURE_TENANT_ID') }}"
      clientId: "{{ secret('AZURE_CLIENT_ID') }}"
      clientSecret: "{{ secret('AZURE_CLIENT_SECRET') }}"
      subscriptionId: "{{ secret('AZURE_SUBSCRIPTION_ID') }}"
      resourceGroupName: kestra-runners
      vmName: my-existing-vm
      stopVm: false
      deleteVm: false
    commands:
      - echo "Processing on reused VM"

Pass input files to the task, execute a Shell command, then retrieve the output files.

yaml
id: azure_vm_with_input_files
namespace: company.team

inputs:
  - id: file
    type: FILE

tasks:
  - id: shell
    type: io.kestra.plugin.scripts.shell.Commands
    inputFiles:
      data.txt: "{{ inputs.file }}"
    outputFiles:
      - out.txt
    taskRunner:
      type: io.kestra.plugin.ee.azure.runner.VirtualMachine
      tenantId: "{{ secret('AZURE_TENANT_ID') }}"
      clientId: "{{ secret('AZURE_CLIENT_ID') }}"
      clientSecret: "{{ secret('AZURE_CLIENT_SECRET') }}"
      subscriptionId: "{{ secret('AZURE_SUBSCRIPTION_ID') }}"
      resourceGroupName: kestra-runners
      region: eastus
      vmSize: Standard_DS1_v2
      subnetId: "/subscriptions/{{ secret('AZURE_SUBSCRIPTION_ID') }}/resourceGroups/kestra-runners/providers/Microsoft.Network/virtualNetworks/kestra-vnet/subnets/kestra-subnet"
      blobStorage:
        connectionString: "{{ secret('AZURE_CONNECTION_STRING') }}"
        containerName: kestra-vm-staging
    commands:
      - cp {{ workingDir }}/data.txt {{ workingDir }}/out.txt
Properties

Resource group containing the virtual machine

Used both to look up an existing VM (vmName) and to create a new one.

Azure subscription ID

The subscription that owns resourceGroupName and the virtual machine.

Blob storage used to stage inputFiles, outputFiles, namespaceFiles, and {{ outputDir }}

Mandatory to set if you want to use these properties.

Definitions
containerName*Requiredstring

The URL of the blob container the compute node should use.

Mandatory if you want to use namespaceFiles, inputFiles or outputFiles properties.

connectionStringstring

Connection string of the Storage Account.

endpointstring

The blob service endpoint.

sharedKeyAccountAccessKeystring

Shared Key access key for authenticating requests.

sharedKeyAccountNamestring

Shared Key account name for authenticating requests.

Service principal client (application) ID

Required together with tenantId and clientSecret for service-principal authentication.

Service principal client secret

Required together with tenantId and clientId for service-principal authentication.

DefaultPT5S

Determines how often Kestra polls while waiting for the VM to become ready and for the Run Command to complete

By default, every 5 seconds. Lower it for quick tasks, raise it (e.g. PT1M) for long-running ones to reduce API calls.

Defaulttrue

Whether to delete the VM once the task finishes

Defaults to true. Set to false (together with stopVm: false) to keep a shared/reusable VM alive across runs.

DefaultCanonical:0001-com-ubuntu-server-jammy:22_04-lts-gen2

Linux image to provision the VM from

Format publisher: offer: sku; the latest version of that image is used. Defaults to Ubuntu 22.04 LTS. Ignored when reusing an existing VM.

DefaultPT5M

VM readiness timeout

The maximum duration to wait for a newly created or restarted VM to reach the running power state before failing the task. Defaults to PT5M.

Reference (ref) of the pluginDefaults to apply to this task runner.

Azure region to create the virtual machine in

For example eastus. Required unless vmName refers to an already existing VM.

Defaulttrue

Whether to reconnect to an already running Kestra-created VM instead of creating a new one

Only applies when vmName is not set: on a Worker restart mid-run, the task runner looks for a VM it previously created for this same task run (matched by tags) and reuses it rather than launching a duplicate. The command itself is always re-issued against the resumed VM regardless (see the class description).

Defaulttrue

Whether to stop (deallocate) the VM once the task finishes

Deallocating stops compute billing (a plain "power off" alone does not, since Azure still reserves the compute capacity). Defaults to true. Honored whether the task succeeds, fails, or is killed.

Subnet the virtual machine's network interface joins

Full resource ID of an existing subnet, for example /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Network/virtualNetworks/<vnet>/subnets/<subnet>. Required to create a new VM, ignored when reusing one via vmName. The runner never creates a virtual network, so the subnet must already provide any outbound network path the VM needs (see blobStorage).

Defaultfalse

Whether to download the whole working directory back from Blob Storage instead of just the declared outputFiles

Defaults to false. Useful when the set of files produced by the task isn't known in advance.

Azure Active Directory tenant ID

Required together with clientId and clientSecret for service-principal authentication. When all three are left unset, the task runner falls back to DefaultAzureCredential (e.g. a managed identity attached to the Kestra Worker).

Plugin Version

Defines the version of the plugin to use.

The version must follow the Semantic Versioning (SemVer) specification:

  • A single-digit MAJOR version (e.g., 1).
  • A MAJOR.MINOR version (e.g., 1.1).
  • A MAJOR.MINOR.PATCH version, optionally with any qualifier (e.g., 1.1.2, 1.1.0-SNAPSHOT).

Name of an already existing virtual machine to run the task on

Must reference a VM that already exists in resourceGroupName. The runner never creates a VM when vmName is set, and fails if none is found. Since it didn't create the VM, stopVm and deleteVm are ignored for it. Leave unset to have the runner provision a new VM, or resume one it created earlier.

Virtual machine size

For example Standard_DS1_v2. See the Azure documentation for available sizes. Required unless vmName refers to an already existing VM.

DefaultPT1H

The maximum duration to wait for the Run Command completion unless the task timeout property is set which will take precedence over this property

The task will be marked as failed if the command has not completed by the time this duration elapses.