Deploying Python Agents VMSS through Azure Portal

Deploying Python Agents VMSS through Azure Portal

This documentation is for Kyvos 2026.8.x. To view documentation for other Kyvos versions, click here.

This documentation is for Kyvos 2026.8.x. To view documentation for other Kyvos versions, click here.

What you will end up with

After completing this deployment, the following resources will be created in your Azure resource group:

  • 1 × Dialogs Agent Virtual Machine Scale Set (a group of identical VMs managed as one unit)

  • Optionally, 1 × Code Executor (Python) Agent Virtual Machine Scale Set

  • 1 or 2 × user-assigned Managed Identities (one per agent VMSS), plus a short-lived ACL-setter identity when ACLs are applied automatically

  • Trusted Launch (Secure Boot + vTPM) on the VMSS — only if 'Is Encryption enabled' is checked

  • Network Security Groups (firewalls) for each VMSS — only if you keep 'Create Network Security Groups' set to Yes

  • ADLS Gen2 ACLs on your storage account giving each agent access to its working directories (applied automatically when the storage firewall is off; applied by you when it is on)

  • Key Vault access policy entries for the agent identities (only if 'Is Encryption enabled' is checked)

The VMSS is created with 0 running instances by default — that means it costs nothing until you scale it up. The final section of this guide tells you how to start the first agent.

Before you begin

What you need

Requirement

Details

An Azure subscription

You should already have one. Note its name and ID.

A resource group

Existing or new. This is where all the agent resources will live.

Permissions on the resource group

Owner or Contributor. If you do not have these, ask your Azure admin.

A storage account

An Azure Data Lake Storage Gen2 (ADLS Gen2) account where Kyvos stores its data. The container inside it should already exist.

A Virtual Network and Subnet

Existing VNet + subnet where the agent VMs will live.

An SSH public key

Used to log in to the VMs if you ever need to. If you don't have one, ask your team or generate one (instructions on the Basics tab section below).

A Key Vault (only if 'Is Encryption enabled' is on)

Used to hold encryption keys. Must exist before deployment.

A Disk Encryption Set (only if 'Is Encryption enabled' is on)

A customer-managed-key Disk Encryption Set used to encrypt the VMSS OS and data disks. Must exist before deployment.

Files in this folder

File

What it is

When you use it

PostCreationDialogsAndPythonAgents.json

The ARM template — the recipe Azure follows.

Selected automatically by the portal when you start the deployment.

DialogsAndPythonAgentsUiDefinition.json

The form definition — the friendly UI on top of the template.

Selected automatically by the portal when you start the deployment.

apply-agent-acls.sh

A shell script for applying storage account permissions (ACLs).

ONLY if 'Firewall enabled on Storage account' is ON and you prefer scripts over the portal. Optional.

A decision before you start

Before you open the Azure portal, decide the answers to two independent questions. Each maps to a checkbox on the Basics tab. These are now SEPARATE — you can enable either one, both, or neither.

Question

If YES (check the box)

If NO (leave unchecked)

Is your Kyvos storage account locked behind a firewall or private endpoint?

Check 'Firewall enabled on Storage account'. You will apply ACLs manually after deployment.

Leave it unchecked. The deployment will apply ACLs automatically.

Do you want VM disks + Key Vault encryption (Trusted Launch + customer-managed keys)?

Check 'Is Encryption enabled'. You will be asked to select a Key Vault and a Disk Encryption Set.

Leave it unchecked. No Trusted Launch, no Key Vault access policy added.

Note

  • If you are unsure, ask your team: “Is the Kyvos storage account locked behind a firewall or private endpoint?” If they say yes, check 'Firewall enabled on Storage account'. If they say no, leave it unchecked.

  • 'Is Encryption enabled' also turns on Trusted Launch (Secure Boot + virtual TPM) on the VMs. It is decoupled from 'Firewall enabled on Storage account' — you can enable encryption on a public storage account, or firewall a storage account without enabling encryption.

Deploying through the Azure portal

Open the custom deployment page

  1. Log in to your Azure Portal, with the user having sufficient permissions.

  2. On the Home page, click Cloud Shell.  

  3. Upload the DialogsAndCodeExecutorAgentsUiDefinition.json and DialogsAndCodeExecutorAgents.json templates (Available in Azure Installation Files) by clicking the Upload button.

  4. After uploading the template, in the Cloud Shell Area, execute the following command to create Template Specs.
    az ts create --name <TemplateSpecName> --version <“VersionNumber”> --resource-group <Resource Group name> --location <“Location”> --template-file "MainTemplatePath" --ui-form-definition "FormFilePath"

    For example,

    az ts create --name kyvosspec --version "v1.0.33" --resource-group Kyvos_RG2 --location "Central US" --template-file "./DialogsAndCodeExecutorAgents.json" --ui-form-definition "./DialogsAndCodeExecutorAgentsUiDefinition.json"  

  5. Close the Cloud Shell and in the Search box, click Template Specs. The Template Specs page is displayed.

  6. On the Template Specs page, search the Template Specs that you have created in Step 4, as mentioned above.

  7. Browse the selected Template Spec and then click the Deploy option to open the deployment form.

  8. Enter details as:

  1. After completing the information on the Tags tab, click Next, and this displays the Review + Create page. The system validates your inputs and displays a summary of the provided inputs. 

  2. Review the summary. The portal will run a final validation.

  3. Click Create. The deployment usually finishes in 5–10 minutes. You can leave the page open or come back later (the status persists in Resource group → Deployments).

Note

If the deployment fails with a validation error like "Tenant must have Microsoft.Insights namespace registered" or "Quota exceeded", note the error message and contact your Azure admin — these are environment-level issues, not template issues.

After deployment — both toggles OFF (the easy path)

If you left BOTH 'Firewall enabled on Storage account' AND 'Is Encryption enabled' unchecked — and you let the deployment create the managed identities (the default) — no manual steps are required. The deployment has already:

  • Created the managed identities.

  • Granted each managed identity a self-scoped role assignment so the VM can resolve its own client ID at boot.

  • Applied ADLS Gen2 ACLs on the storage paths automatically (via a temporary ACL-setter identity that removes its own access when finished).

  • Created the VMSS resources with 0 instances.

Skip to Section 6 (Starting the agents).

After deployment — manual setup (when either toggle is ON)

Two manual procedures may be needed depending on which toggles you enabled. They are INDEPENDENT — if only one toggle is on, you only need one procedure: (1) If 'Firewall enabled on Storage account' was ON, you must apply ADLS Gen2 ACLs manually (Section 5.1–5.3). (2) If 'Is Encryption enabled' was ON, you may need to grant the agent managed identities access on your Key Vault (Section 5.4). Without these, the affected feature(s) will fail — bundles won't download (ACL miss) or decryption won't work (Key Vault miss).

Without those, the agents will fail to download their bundles and fail to decrypt data. You will need to complete the applicable step(s) before scaling the VMSS up.

Decide how to apply ACLs

You have two options. Pick the one that matches your environment:

Option

What it is

Best for

Option A — Shell script

Run apply-agent-acls.sh on a jumpbox or VM that has VNet connectivity to the locked-down storage account.

You have a jumpbox / dev VM in the same VNet, you are comfortable opening a terminal.

Option B — Azure portal

Click through Storage browser → Manage ACL in the Azure portal, path by path. No scripts needed.

You only have portal access, no jumpbox. You prefer GUI over command line.

Note

Both options achieve exactly the same result. The shell script is faster (about 1 minute) but requires a machine with network access. The portal approach takes 10–15 minutes of clicking but works from anywhere.

Option A: Using the shell script

Use this option if you have a jumpbox / dev VM that can reach your storage account.

  1. Open apply-agent-acls.sh in a text editor (Notepad, VS Code, vim, anything).

  2. Fill in the five variables at the top of the file:

    1. STORAGE_ACCOUNT — the name of your Kyvos storage account.

    2. CONTAINER — the name of the container inside it.

    3. KYVOS_WORK_DIR_RAW — usually /user/engine_work/

    4. DIALOGS_PRINCIPAL_ID — the object ID of the Dialogs Agent managed identity.

    5. CODE_EXECUTOR_PRINCIPAL_ID — the object ID of the Code Executor managed identity (leave empty if you didn't deploy Python Agents).

To find a managed identity's object ID:

  1. In the Azure portal, navigate to your resource group.

    • Find the user-assigned managed identity (named like kyvos-dialogs-agent-mi-XXXX).

    • On its Overview blade, copy the Object (Principal) ID.

  2. Copy apply-agent-acls.sh to your jumpbox (any way: SCP, RDP+copy, OneDrive, etc.).

  3. On the jumpbox, run:
    chmod +x apply-agent-acls.sh
    az login
    ./apply-agent-acls.sh

  4. Watch the output. The script ends with: Agent ACL configuration complete.

Important

The signed-in identity on the jumpbox (the one you used with az login) needs the Storage Blob Data Owner role on the storage account. Without that, the script cannot write ACLs. If you see permission errors, ask your Azure admin to grant you that role on the storage account, then re-run.

Option B: Using the Azure portal

Use this option if you do not have a jumpbox. The detailed click-by-click instructions are in MANUAL_SETUP.docx — Section 1.2. Open that document and follow it.

Note

MANUAL_SETUP.docx has a complete ACL model table and a verification step. Tick off each path as you go to avoid missing one. The order matters — start with /user (the shallowest path) and work down.

Configure Key Vault access

Regardless of whether you used Option A or B for ACLs, you may also need to grant the agent managed identities access to your Key Vault. Note: if your Key Vault uses the legacy "Vault access policy" model, the deployment already added these access-policy entries automatically — this manual step is then only needed if that automatic step was skipped or failed. If your Key Vault uses the modern "Azure RBAC" model, the automatic step does not apply and you must grant access manually.

Open MANUAL_SETUP.docx — Section 2 and follow it. It covers both modes.

Note

If you do not know which model your Key Vault uses, MANUAL_SETUP.docx Section 2.1 explains how to check in 3 clicks.

Starting the agents

The deployment created the VMSS resources with 0 instances. You need to scale up to 1 to actually start an agent. Do this for each VMSS you deployed.

  1. In the Azure portal, navigate to your resource group.

  2. Click on the agent VMSS (named like kyvos-dialogs-agent-XXXX).

  3. In the left blade, click Scaling.

  4. Make sure Manual scale is selected (it is the default — no autoscale rules are configured).

  5. Set the instance count to 1.

  6. Click Save at the top.

  7. Wait 3–5 minutes. Azure will provision a VM and the bootstrap script will run automatically: install Python 3.12, mount the data disk, download the agent bundle, extract the Python venv, and launch the agent.

  8. Repeat for the Code Executor VMSS if you deployed it.

Note

To watch the bootstrap progress: navigate to the VMSS → Instances → click the VM instance → on its left blade open "Boot diagnostics" → click "Settings" to view the serial log, which streams the bootstrap output as it happens.

Verifying the deployment

Use these quick checks to confirm everything is up:

What to check

Where

What you should see

VMSS exists

Resource group → kyvos-dialogs-agent-XXXX

Status: Succeeded

Managed identities exist

Resource group → User-assigned managed identities

kyvos-dialogs-agent-mi-XXXX (and code-executor-mi-XXXX if Python Agents)

NSGs exist (if Create NSG = Yes)

Resource group → Network security groups

kyvos-dialogs-agent-XXXX-nsg (and codeexec-nsg if applicable)

VM instance is running

VMSS → Instances

1 running instance, Status: Running, Provisioning state: Succeeded

Agent process is running

SSH into the VM and run: ps -ef | grep dialogsagent (or codeexecutor)

A Java/Python process owned by the kyvos user

Bootstrap completed

On the VM: cat /tmp/bootstrap_logs.out | tail -20

Last line: Bootstrap completed for <agent> at <timestamp>

Troubleshooting

The deployment itself failed

Error message contains

Likely cause / fix

Quota exceeded

Your subscription doesn't have enough vCPU quota in the chosen region. Ask your Azure admin to raise the quota, or choose a smaller VM size.

The subscription is not registered to use namespace 'Microsoft.…'

A resource provider isn't enabled. The error tells you which one. Azure admin → Subscriptions → Resource providers → Register.

does not have authorization to perform action

You don't have enough permissions on the resource group. Ask for Contributor or Owner.

InvalidTemplate

Rare; contact your Kyvos contact and share the deployment ID.

 

The deployment succeeded but the agent doesn't start

Symptom

Likely cause / fix

Bootstrap log shows azcopy 401 / 403 errors when downloading the agent bundle

ACLs are not in place. If 'Firewall enabled on Storage account' is ON, go back to Section 5 of this guide.

Bootstrap log shows "Key Vault access denied"

Key Vault permissions are missing. Follow MANUAL_SETUP.docx Section 2.

Bootstrap log shows "USER_ASSIGNED_CLIENT_ID does not have authorization to perform action Microsoft.ManagedIdentity/userAssignedIdentities/read"

RBAC propagation lag right after deployment. Wait 1–2 minutes and reimage the VM (VMSS → Instances → select VM → Reimage).

VM provisioning succeeded but ps -ef shows no agent process

Open /tmp/bootstrap_logs.out and read it bottom-up — the last error message tells you what went wrong.

How to get into the VM to check logs

  1. Navigate to the VMSS → Instances → click an instance. Note its private IP address (the VM doesn't have a public IP by default).

  2. From a jumpbox or VPN-connected machine: ssh adminuser@<private-ip> using the SSH key you provided on the Basics tab.

  3. Useful files once you're in:

    • /tmp/bootstrap_logs.out — full bootstrap log.

    • /data/kyvos/app/kyvos/<agent-name>/logs/ — agent runtime logs.

    • /data/kyvos/app/kyvos/<agent-name>/bin/start-<agent>.sh — startup script (useful to verify USER_ASSIGNED_CLIENT_ID was substituted correctly).

Copyright Kyvos, Inc. 2026. All rights reserved.