Blog Post

Linux and Open Source Blog
8 MIN READ

Run OpenClaw Agents on Azure Linux VMs (with Secure Defaults)

johnsonshi_msft's avatar
Mar 22, 2026

Deploy self-hosted, always-on OpenClaw AI agents on Azure with NSG hardening and Bastion-secured access

Many teams want an enterprise-ready personal AI assistant, but they need it on infrastructure they control, with security boundaries they can explain to IT. That is exactly where OpenClaw fits on Azure.

OpenClaw is a self-hosted, always-on personal agent runtime you run in your enterprise environment and Azure infrastructure. Instead of relying only on a hosted chat app from a third-party provider, you can deploy, operate, and experiment with an agent on an Azure Linux VM you controlusing your existing GitHub Copilot licenses, Azure OpenAI deployments, or API plans from OpenAI, Anthropic Claude, Google Gemini, and other model providers you already subscribe to. Once deployed on Azure, you can interact with an OpenClaw agent through familiar channels like Microsoft Teams, Slack, Telegram, WhatsApp, and many more!

For Azure users, this gives you a practical middle ground: modern personal-agent workflows on familiar Azure infrastructure.

What is OpenClaw, and how is it different from ChatGPT/Claude/chat apps?

OpenClaw is a self-hosted personal agent runtime that can be hosted on Azure compute infrastructure.

How it differs:

  • ChatGPT/Claude apps are primarily hosted chat experiences tied to one provider's models
  • OpenClaw is an always-on runtime you operate yourself, backed by your choice of model provider — GitHub Copilot, Azure OpenAI, OpenAI, Anthropic Claude, Google Gemini, and others
  • OpenClaw lets you keep the runtime boundary in your own Azure VM environment within your Azure enterprise subscription

In practice, OpenClaw is useful when you want a persistent assistant for operational and workflow tasks, with your own infrastructure as the control point. You bring whatever model provider and API plan you already have — OpenClaw connects to it.

Why Azure Linux VMs?

Azure Linux VMs are a strong fit because they provide:

  • A suitable host machine for the OpenClaw agent to run on
  • Enterprise-friendly infrastructure and identity workflows
  • Repeatable provisioning via the Azure CLI
  • Network hardening with NSG rules
  • Managed SSH access through Azure Bastion instead of public SSH exposure

How to Set Up OpenClaw on an Azure Linux VM

This guide sets up an Azure Linux VM, applies NSG (Network Security Group) hardening, configures Azure Bastion for managed SSH access, and installs an always-on OpenClaw agent within the VM that you can interact with through various messaging channels.

What you'll do

  • Create Azure networking (VNet, subnets, NSG) and compute resources with the Azure CLI
  • Apply Network Security Group rules so VM SSH is allowed only from Azure Bastion
  • Use Azure Bastion for SSH access (no public IP on the VM)
  • Install OpenClaw on the Azure VM
  • Verify OpenClaw installation and configuration on the VM

What you need

  • An Azure subscription with permission to create compute and network resources
  • Azure CLI installed (install steps)
  • An SSH key pair (the guide covers generating one if needed)
  • ~20–30 minutes

Configure deployment

Step 1: Sign in to Azure CLI

az login                     # Select a suitable Azure subscription during Azure login
az extension add -n ssh      # SSH extension is required for Azure Bastion SSH

The ssh extension is required for Azure Bastion native SSH tunneling.

Step 2: Register required resource providers (one-time)

Register required Azure Resource Providers (one time registration):

az provider register --namespace Microsoft.Compute
az provider register --namespace Microsoft.Network

Verify registration. Wait until both show Registered.

az provider show --namespace Microsoft.Compute --query registrationState -o tsv
az provider show --namespace Microsoft.Network --query registrationState -o tsv

Step 3: Set deployment variables

Set the deployment environment variables that will be needed throughout this guide.

RG="rg-openclaw"
LOCATION="westus2"
VNET_NAME="vnet-openclaw"
VNET_PREFIX="10.40.0.0/16"
VM_SUBNET_NAME="snet-openclaw-vm"
VM_SUBNET_PREFIX="10.40.2.0/24"
BASTION_SUBNET_PREFIX="10.40.1.0/26"
NSG_NAME="nsg-openclaw-vm"
VM_NAME="vm-openclaw"
ADMIN_USERNAME="openclaw"
BASTION_NAME="bas-openclaw"
BASTION_PIP_NAME="pip-openclaw-bastion"

Adjust names and CIDR ranges to fit your environment. The Bastion subnet must be at least /26.

Step 4: Select SSH key

Use your existing public key if you have one:

SSH_PUB_KEY="$(cat ~/.ssh/id_ed25519.pub)"

If you don't have an SSH key yet, generate one:

ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519 -C "you@example.com"
SSH_PUB_KEY="$(cat ~/.ssh/id_ed25519.pub)"

Step 5: Select VM size and OS disk size

VM_SIZE="Standard_B2as_v2"
OS_DISK_SIZE_GB=64

Choose a VM size and OS disk size available in your subscription and region:

  • Start smaller for light usage and scale up later
  • Use more vCPU/RAM/disk for heavier automation, more channels, or larger model/tool workloads
  • If a VM size is unavailable in your region or subscription quota, pick the closest available SKU

List VM sizes available in your target region:

az vm list-skus --location "${LOCATION}" --resource-type virtualMachines -o table

Check your current vCPU and disk usage/quota:

az vm list-usage --location "${LOCATION}" -o table

Deploy Azure resources

Step 1: Create the resource group

The Azure resource group will contain all of the Azure resources that the OpenClaw agent needs.

az group create -n "${RG}" -l "${LOCATION}"

Step 2: Create the network security group

Create the NSG and add rules so only the Bastion subnet can SSH into the VM.

az network nsg create \
  -g "${RG}" -n "${NSG_NAME}" -l "${LOCATION}"

# Allow SSH from the Bastion subnet only
az network nsg rule create \
  -g "${RG}" --nsg-name "${NSG_NAME}" \
  -n AllowSshFromBastionSubnet --priority 100 \
  --access Allow --direction Inbound --protocol Tcp \
  --source-address-prefixes "${BASTION_SUBNET_PREFIX}" \
  --destination-port-ranges 22

# Deny SSH from the public internet
az network nsg rule create \
  -g "${RG}" --nsg-name "${NSG_NAME}" \
  -n DenyInternetSsh --priority 110 \
  --access Deny --direction Inbound --protocol Tcp \
  --source-address-prefixes Internet \
  --destination-port-ranges 22

# Deny SSH from other VNet sources
az network nsg rule create \
  -g "${RG}" --nsg-name "${NSG_NAME}" \
  -n DenyVnetSsh --priority 120 \
  --access Deny --direction Inbound --protocol Tcp \
  --source-address-prefixes VirtualNetwork \
  --destination-port-ranges 22

The rules are evaluated by priority (lowest number first): Bastion traffic is allowed at 100, then all other SSH is blocked at 110 and 120.

Step 3: Create the virtual network and subnets

Create the VNet with the VM subnet (NSG attached), then add the Bastion subnet.

az network vnet create \
  -g "${RG}" -n "${VNET_NAME}" -l "${LOCATION}" \
  --address-prefixes "${VNET_PREFIX}" \
  --subnet-name "${VM_SUBNET_NAME}" \
  --subnet-prefixes "${VM_SUBNET_PREFIX}"

# Attach the NSG to the VM subnet
az network vnet subnet update \
  -g "${RG}" --vnet-name "${VNET_NAME}" \
  -n "${VM_SUBNET_NAME}" --nsg "${NSG_NAME}"

# AzureBastionSubnet — name is required by Azure
az network vnet subnet create \
  -g "${RG}" --vnet-name "${VNET_NAME}" \
  -n AzureBastionSubnet \
  --address-prefixes "${BASTION_SUBNET_PREFIX}"

Step 4: Create the Virtual Machine

Create the VM with no public IP. SSH access for OpenClaw configuration will be exclusively through Azure Bastion.

az vm create \
  -g "${RG}" -n "${VM_NAME}" -l "${LOCATION}" \
  --image "Canonical:ubuntu-24_04-lts:server:latest" \
  --size "${VM_SIZE}" \
  --os-disk-size-gb "${OS_DISK_SIZE_GB}" \
  --storage-sku StandardSSD_LRS \
  --admin-username "${ADMIN_USERNAME}" \
  --ssh-key-values "${SSH_PUB_KEY}" \
  --vnet-name "${VNET_NAME}" \
  --subnet "${VM_SUBNET_NAME}" \
  --public-ip-address "" \
  --nsg ""

--public-ip-address "" prevents a public IP from being assigned.

--nsg "" skips creating a per-NIC NSG (the subnet-level NSG created earlier handles security).

Reproducibility: The command above uses latest for the Ubuntu image. To pin a specific version, list available versions and replace latest:

az vm image list \
  --publisher Canonical --offer ubuntu-24_04-lts \
  --sku server --all -o table

Step 5: Create Azure Bastion

Azure Bastion provides secure-managed SSH access to the VM without exposing a public IP.

Bastion Standard SKU with tunneling is required for CLI-based "az network bastion ssh" command.

az network public-ip create \
  -g "${RG}" -n "${BASTION_PIP_NAME}" -l "${LOCATION}" \
  --sku Standard --allocation-method Static

az network bastion create \
  -g "${RG}" -n "${BASTION_NAME}" -l "${LOCATION}" \
  --vnet-name "${VNET_NAME}" \
  --public-ip-address "${BASTION_PIP_NAME}" \
  --sku Standard --enable-tunneling true

Bastion provisioning typically takes 5–10 minutes but can take up to 15–30 minutes in some regions.

Step 6: Verify Deployments

After all resources are deployed, your resource group should look like the following:

Install OpenClaw

Step 1: SSH into the VM through Azure Bastion

VM_ID="$(az vm show -g "${RG}" -n "${VM_NAME}" --query id -o tsv)"

az network bastion ssh \
  --name "${BASTION_NAME}" \
  --resource-group "${RG}" \
  --target-resource-id "${VM_ID}" \
  --auth-type ssh-key \
  --username "${ADMIN_USERNAME}" \
  --ssh-key ~/.ssh/id_ed25519

Step 2: Install OpenClaw (in the Bastion SSH shell)

curl -fsSL https://openclaw.ai/install.sh | bash

The installer installs Node LTS and dependencies if not already present, installs OpenClaw, and launches the OpenClaw onboarding wizard. For more information, see the open source OpenClaw install docs.

OpenClaw Onboarding: Choosing an AI Model Provider

During OpenClaw onboarding, you'll choose the AI model provider for the OpenClaw agent. This can be GitHub Copilot, Azure OpenAI, OpenAI, Anthropic Claude, Google Gemini, or another supported provider. See the open source OpenClaw install docs for details on choosing an AI model provider when going through the onboarding wizard.

Most enterprise Azure teams already have GitHub Copilot licenses. If that is your case, we recommend choosing the GitHub Copilot provider in the OpenClaw onboarding wizard. See the open source OpenClaw docs on configuring GitHub Copilot as the AI model provider.

OpenClaw Onboarding: Setting up Messaging Channels

During OpenClaw onboarding, there will be an optional step where you can set up various messaging channels to interact with your OpenClaw agent.

For first time users, we recommend setting up Telegram due to ease of setup. Other messaging channels such as Microsoft Teams, Slack, WhatsApp, and others can also be set up.

To configure OpenClaw for messaging through chat channels, see the open source OpenClaw chat channels docs.

Step 3: Verify OpenClaw Configuration

To validate that everything was set up correctly, run the following commands within the same Bastion SSH session:

openclaw status
openclaw gateway status

If there are any issues reported, you can run the onboarding wizard again with the steps above. Alternatively, you can run the following command:

openclaw doctor

Message OpenClaw

Once you have configured the OpenClaw agent to be reachable via various messaging channels, you can verify that it is responsive by messaging it.

Enhancing OpenClaw for Use Cases

There you go! You now have a 24/7, always-on personal AI agent, living on its own Azure VM environment.

Cleanup

To delete all resources created by this guide:

az group delete -n "${RG}" --yes --no-wait

This removes the resource group and everything inside it (VM, VNet, NSG, Bastion, public IP). This also deletes the OpenClaw agent running within the VM.

If you'd like to dive deeper about deploying OpenClaw on Azure, please check out the open source OpenClaw on Azure docs.

Updated Mar 22, 2026
Version 1.0
No CommentsBe the first to comment