Installing the Middleware agent on Azure Virtual Machine Scale Set (VMSS)

The Middleware Infrastructure Agent monitors Linux virtual machines in Azure Virtual Machine Scale Sets (VMSS). Deployment through the Azure Custom Script Extension helps keep agent installation consistent as the scale set adds instances.

After the extension is added to the VMSS model, the installation script can be applied to existing instances and automatically runs on new instances created during scale-out.

Use this setup when you want to:

  • Install the Middleware Agent across an existing Linux VM scale set without manually connecting to each VM.
  • Keep Agent installation consistent across VMSS instances.
  • Automatically install the Agent on new instances created during scale-out.

How it works#

The Middleware Agent is installed on each VM using the Azure Custom Script Extension.

The installation process consists of the following steps:

1. Prepare the installation script#

  • Detects the Linux distribution.
  • Selects the appropriate package manager and installation method.
  • Waits for active package manager operations to complete.
  • Installs the Middleware Agent using your API key and target URL.

2. Attach the script to the VMSS#

  • Adds the Custom Script Extension to the VMSS model.
  • Configures the extension to execute the Middleware installation script.

3. Roll out the configuration#

  • Apply the updated VMSS model to existing instances.
  • New instances created after the extension is configured receive the extension automatically.

If an extension deployment fails or you change the underlying VM image, you may need to update, reimage, or recreate the affected instances to apply the current VMSS configuration.

Prerequisites#

Before installing the Middleware Infrastructure Agent, make sure you have the following:

Middleware

  • A Middleware account.
  • Your Middleware API key (MW_API_KEY).
  • Your Middleware target URL (MW_TARGET).

Azure

  • An existing Linux Azure Virtual Machine Scale Set (VMSS).
  • Azure CLI installed and authenticated.
  • Azure permissions to:
    • Read and update the VMSS.
    • Add, update, and remove VMSS extensions.

Supported distributions

  • This installation supports Linux distributions that use one of the following package managers: apt ,yum , dnf , zypper

Installation#

1 Prepare the installation script#

Create a file named install-middleware-agent.sh on the machine where you run Azure CLI.

1#!/bin/bash
2
3# Detect OS and package manager
4
5echo "Detecting operating system..."
6
7if [ -f /etc/os-release ]; then
8    . /etc/os-release
9    OS=$ID
10    echo "Detected OS: $OS"
11else
12    echo "ERROR: Cannot detect OS"
13    exit 1
14fi
15
16# Determine package manager and installation script
17
18if command -v apt-get >/dev/null 2>&1; then
19    # Debian/Ubuntu
20    PKG_MGR="apt"
21    INSTALL_SCRIPT="https://install.middleware.io/scripts/deb-install.sh"
22    LOCK_FILES="/var/lib/dpkg/lock-frontend /var/lib/apt/lists/lock /var/lib/dpkg/lock"
23elif command -v yum >/dev/null 2>&1; then
24    # RHEL/CentOS/Amazon Linux
25    PKG_MGR="yum"
26    INSTALL_SCRIPT="https://install.middleware.io/scripts/rpm-install.sh"
27    LOCK_FILES="/var/run/yum.pid"
28elif command -v dnf >/dev/null 2>&1; then
29    # Fedora/RHEL 8+
30    PKG_MGR="dnf"
31    INSTALL_SCRIPT="https://install.middleware.io/scripts/rpm-install.sh"
32    LOCK_FILES="/var/cache/dnf/metadata_lock.pid"
33elif command -v zypper >/dev/null 2>&1; then
34    # SUSE/openSUSE
35    PKG_MGR="zypper"
36    INSTALL_SCRIPT="https://install.middleware.io/scripts/rpm-install.sh"
37    LOCK_FILES="/var/run/zypp.pid"
38else
39    echo "ERROR: Unsupported package manager"
40    exit 1
41fi
42
43echo "Using package manager: $PKG_MGR"
44echo "Installation script: $INSTALL_SCRIPT"
45
46# Wait for package manager locks to be released
47
48echo "Checking for package manager locks..."
49
50timeout=300
51elapsed=0
52
53while true; do
54    locked=false
55    for lock_file in $LOCK_FILES; do
56        if [ -f "$lock_file" ] && fuser "$lock_file" >/dev/null 2>&1; then
57            locked=true
58            break
59        fi
60    done
61
62    if [ "$locked" = false ]; then
63        break
64    fi
65
66    if [ $elapsed -ge $timeout ]; then
67        echo "ERROR: Timeout waiting for package manager locks (waited ${timeout}s)"
68        exit 1
69    fi
70
71    echo "$PKG_MGR is busy, waiting... (${elapsed}s elapsed)"
72    sleep 10
73    elapsed=$((elapsed + 10))
74done
75
76echo "Package manager available. Installing Middleware agent..."
77
78# Install Middleware agent
79
80MW_API_KEY="<MW_API_KEY>" \
81MW_TARGET="https://<MW_UID>.middleware.io:443" \
82bash -c "$(curl -L $INSTALL_SCRIPT)"
83
84if [ $? -eq 0 ]; then
85    echo "Middleware agent installed successfully"
86    exit 0
87else
88    echo "ERROR: Middleware agent installation failed"
89    exit 1
90fi

Save the file and make it executable:

1chmod +x install-middleware-agent.sh

What this script does:

  • Detects the operating system using /etc/os-release.
  • Selects the appropriate package manager (apt, yum, dnf, or zypper) and Middleware installation script.
  • Waits for package manager locks to clear to avoid conflicts with ongoing system updates.
  • Runs the Middleware installer with MW_API_KEY and MW_TARGET set as environment variables.
  • Returns a non-zero exit code if the installation fails, allowing the Azure extension to report the failure.

2 Attach the Custom Script Extension to the VMSS#

From the directory containing install-middleware-agent.sh, run:

1az vmss extension set \
2  --resource-group <your-resource-group> \
3  --vmss-name <your-vmss-name> \
4  --name CustomScript \
5  --publisher Microsoft.Azure.Extensions \
6  --version 2.1 \
7  --protected-settings "{\"script\": \"$(base64 -w 0 install-middleware-agent.sh)\"}"

What this command does:

  • Adds the Custom Script Extension to the VMSS model.
  • Embeds the Base64-encoded install-middleware-agent.sh script in the extension configuration.
  • Ensures the script runs automatically when new VM instances are created.

Existing instances do not run the script automatically. You must update, reimage, or recreate them in the next step. If you run the command from a non-Linux environment, use the equivalent Base64 command that produces a single-line output without line breaks.

3 Roll out the agent to existing VM instances#

After attaching the extension to the VMSS model, roll out the change to existing instances.Choose the rollout strategy that best fits your environment.

Try this first. It refreshes the configuration of all instances and triggers the extension without recreating VMs.

1az vmss update-instances \
2  --resource-group <your-resource-group> \
3  --name <your-vmss-name> \
4  --instance-ids "*"

Use this when:

  • You are fine with instances being updated in place
  • You want the change to apply across the scale set with minimal disruption

If this succeeds, the Custom Script Extension runs, the agent installs and you can move to verification.

Use a rolling upgrade when you want to apply the new extension configuration gradually across the scale set to reduce impact on production workloads.

1az vmss rolling-upgrade start \
2  --resource-group <your-resource-group> \
3  --name <your-vmss-name>

During a rolling upgrade, Azure:

  • Updates a subset of instances at a time
  • Waits for the instances to become healthy
  • Proceeds to the next batch

Even with a rolling upgrade, VMs are restarted. Any state that is not externalised will be lost on upgraded instances.

If you see errors like PropertyChangeNotAllowed or configuration drift, reimage the instances so they boot from the base image and apply the latest extension settings.

1az vmss reimage \
2  --resource-group <your-resource-group> \
3  --name <your-vmss-name> \
4  --instance-ids "*"

This action:

  • Recreates the OS disk for each selected instance
  • Keeps the scale set configuration and networking
  • Causes the instance to run the Custom Script Extension on first boot

Reimaging discards any local data that is not stored on external disks or shared storage. Make sure application data is persisted outside the OS disk.

As a last resort, you can delete all existing instances and scale back up so that all new instances start with a clean state and the agent is installed.

1# Delete existing instances
2az vmss delete-instances \
3  --resource-group <your-resource-group> \
4  --name <your-vmss-name> \
5  --instance-ids "*"
6
7# Scale back up (new instances will have the agent)
8az vmss scale \
9  --resource-group <your-resource-group> \
10  --name <your-vmss-name> \
11  --new-capacity <desired-number-of-vms>

Only use this approach when you can safely recreate all instances from the base image.

Note : Use an in-place update when you want the change applied across the scale set with minimal disruption. Once the rollout succeeds, the Custom Script Extension runs on the instances and installs the Middleware Agent.

4 Verify the agent installation#

After the rollout, connect to a VM instance and verify that the Middleware Agent is running:

  1. Sign in to the Middleware platform.
  2. Go to the Infra tab.
  3. Confirm that your Azure VMSS instances appear in the list of virtual machines or hosts.

New VMs may take a few minutes to show up after the agent starts.

You can also verify the service on a VM directly:

1sudo systemctl status mw-agent

The service should show an active (running) state. If the service is not running or fails to start, check the agent logs under /var/log for more details.

Verify data collection#

After the Agent is running, go to Infrastructure Monitoring → Hosts and verify that the VMSS instances are reporting data.

After data collection starts, you can:

Troubleshooting#

If the extension fails, first check the status at the VMSS level:

1az vmss extension list \
2  --resource-group <your-resource-group> \
3  --vmss-name <your-vmss-name>

Look for the CustomScript extension and review:

  • Provisioning state
  • Any error messages returned by the platform

For per instance status, you can also use az vmss get-instance-view to inspect a specific VM.

If the extension reports failure, SSH into one of the affected instances and check the handler logs:

1cat /var/log/azure/custom-script/handler.log

This log usually contains:

  • The command that was executed
  • Script output and errors
  • Exit code of the script

Common issues:

  • Missing or invalid MW_API_KEY or MW_TARGET
  • Network connectivity problems when curl tries to download the install script
  • The package manager is locked for longer than 300 seconds, which triggers the timeout in the script

If the extension configuration is corrupted or you want to start from a clean state, remove it and add it again.

1az vmss extension delete \
2  --resource-group <your-resource-group> \
3  --vmss-name <your-vmss-name> \
4  --name CustomScript

Then repeat Step 2 to re-add the extension

After re-adding, repeat the rollout steps for existing instances.

If you deleted instances and no new VMs are created, confirm the scale set capacity and adjust it.

1# Check current capacity
2az vmss show \
3  --resource-group <your-resource-group> \
4  --name <your-vmss-name> \
5  --query '{capacity:sku.capacity, instanceCount:instanceCount}'
6
7# Scale up if capacity is 0
8az vmss scale \
9  --resource-group <your-resource-group> \
10  --name <your-vmss-name> \
11  --new-capacity 3

Once new instances are created, they will use the VMSS model that already contains the Custom Script Extension and will install the Middleware agent automatically.

Need assistance or want to learn more about Middleware? Get in touch with us via our Contact Us or join our Slack channel.

What did you think of this content?