Azure
Manage Azure VMs, images, and containers
Azure takes its credentials from BeyondTrust Workload Credentials, so there is no
static key or .env value to fix here. Check the personal access token
and the dynamic-secret names under
Settings → Integrations →
BeyondTrust → Workload Credentials.
Complete the setup wizard, or set AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID, and AZURE_SUBSCRIPTION_ID in your .env file.
| Name / SKU | Publisher | OS | Actions |
|---|---|---|---|
Gallery images + standalone Managed Images in your resource group.
| Name | Source | OS | State | Actions | |
|---|---|---|---|---|---|
| Name | State | IP Addresses | Size | Location | Deployed By | Actions | |
|---|---|---|---|---|---|---|---|
|
|
—
|
Job |
Deploy Azure VM
Marketplace URN publisher:offer:sku:version or full ARM resource ID (managed image / Shared Image Gallery version).
Batch names are capped at 15 characters so each VM gets a distinct in-guest hostname — keep the base to 12 or fewer to avoid truncation.
No NSGs found.
Key retrieved from vault: — bound to this workstream
Asset group, Gateway and credential — the configured defaults unless changed
BeyondTrust PRA options — optional; fall back to the configured defaults.
No PRA Asset Groups/Gateways returned — the shell jump falls back to the configured defaults.
Overrides bt_client_secret for this deploy's shell jump.
Runs after deploy:
Advanced options — SSH key override, integrations, Windows identity
Bound to this workstream: — used when this is left at the default.
Any Key Vault secret. Must be JSON with a public_key — validated on launch.
Requires Entitle registration enabled; private VMs also need a provisioned Entitle agent.
Requires Password Safe registration enabled; onboards the image's adminuser account, SSH-key managed.
Onboards the local administrator as a password-managed account (needs a Windows functional account). Password Safe rotates it immediately, then owns it — check it out there or connect through the PRA Shell Jump (or RDP jump).
Adds a system identity and the AADLoginForWindows extension, and grants the Entra groups configured in Settings login on this VM. Needs Windows Server 2019+ and outbound HTTPS to Entra.
Windows servers get a PRA Shell Jump over OpenSSH (port 22, PowerShell), switched on at first boot. Tick this for a Remote RDP jump as well. If OpenSSH does not come up, the server gets an RDP jump anyway and the job says why.
Overrides the ACI Gateway deploy key for this deploy.
Starts at this time, and is marked missed if it has not started within the grace period — it will never run late.
No change windows are defined yet. An administrator can add them in Settings.
Next:
–
UTC
Bulk Deploy Azure VMs
images selected — one VM per image. To deploy several copies of a single image, use the Count field on the normal deploy form.
No NSGs found.
Key retrieved from vault:
Windows servers get a PRA Shell Jump over OpenSSH (port 22, PowerShell), switched on at first boot. Tick this for a Remote RDP jump as well. If OpenSSH does not come up, the server gets an RDP jump anyway and the job says why.
Starts at this time, and is marked missed if it has not started within the grace period — it will never run late.
No change windows are defined yet. An administrator can add them in Settings.
Next:
–
UTC
Capture VM Image
Starts at this time, and is marked missed if it has not started within the grace period — it will never run late.
No change windows are defined yet. An administrator can add them in Settings.
Next:
–
UTC
SSH key for
Retrieved from Azure Key Vault secret
— this is the canonical private key that pairs with the public key the
dashboard injected when the VM was deployed.
Keypair mismatch in Key Vault.
The stored public_key does not match the stored private_key. The VM
was provisioned with the public_key, so this private key WILL NOT
authenticate. Generate a new keypair (e.g.
ssh-keygen -t rsa -b 4096),
update both fields in the unified Key Vault secret, and redeploy.
Decode error:
Admin password for
Generated at deploy time and stored in the secrets backend
.
Build Azure Image with Packer
Provision a marketplace image with a shell or PowerShell script and register the result as a new Azure Managed Image. Runs as a tracked background job (typically 10–20 min; Windows builds run longer).
Shell script run before the Azure waagent deprovision step (which Packer always runs to generalize the image).
PowerShell script run (then a restart) before the Sysprep generalize step, which the build always runs last.
Loaded from .
BeyondTrust provisioner options — used by the bt-ready scripts; ignored by other provisioners.
Storage pins the version you synced and doesn't need BeyondTrust reachable from the build — sync it first on the Storage page. Not available on local-filesystem storage.
EPM-L is installed at build; activation runs post-deploy via the EPM-L integration.
Environment variables — passed to the provisioner script.
Secret refs are resolved at build start and passed via Packer sensitive variables — never written to the generated or archived template.
Starts at this time, and is marked missed if it has not started within the grace period — it will never run late.
No change windows are defined yet. An administrator can add them in Settings.
Next:
–
UTC
OT Demo Cell
Deploy a simulated plant cell — a Modbus PLC simulator (:502) + FUXA web HMI (:1881) from the Packer-baked ot-sim gallery image — with no public IP, and BeyondTrust access auto-wired: Web Jump → HMI, protocol tunnel → PLC port, plus the Shell Jump and optional Password Safe onboarding every Azure deploy gets. Bake the image first on the Build Image tab (Debian 12 preset + provisioners/ot/ot-sim-debian.sh).
Deploy a cell
No ot-sim image yet — build one on the Build Image tab, or tick "show all".
The cell gets no public IP — access is PRA-brokered only, which is the point.
No NSGs found.
What the image you picked was baked with. The dashboard cannot read this off an image — both runtimes produce an ot-sim image — so it is your assertion, and it decides whether the cell's own platform endpoints can be brokered at all.
The cell itself
The cell simulates every PLC protocol at once — each gets its own PRA protocol tunnel, so access can be granted per vendor. It also runs those simulators on k3s, so the cell's own Kubernetes API can be brokered the same way: a recorded kubectl into the plant cluster, with no other route in. Protocols the image does not simulate (e.g. DNP3) stay available on the standalone tunnel card below.
BeyondTrust PRA placement — where the cell's jump items land; defaults are the configured azure_bt_jump_group_name / azure_jumpoint_name.
Pick the pair matching the cell's region. With a Gateway override the deploy skips the shared-gateway size check — the host behind that Gateway needs ≥2 GB RAM for the Web Jump.
The agent that brokers this access runs in the plant, on its own industrial-DMZ host deployed beside the cell — not in a cluster somewhere else. On Azure the two zones are NSGs on the VMs' NICs, and the cell's carries an outbound Deny: Azure's default outbound access gives a VM with no public IP a route to the internet, so that rule is what makes the air gap real rather than documented. Needs the Purdue zoning on (ot_purdue_firewall_enabled) and azure_jumpoint_name set, so the zone can name the Gateway; the deploy refuses with the remedy if anything is missing.
No image with broker in its name yet — bake one with OT_ROLE=broker and name it e.g. ot-broker (see provisioners/ot/README.md), or tick "show all".
8 GB or more: the agent requests 1Gi on its own.
The gateway backing the Web Jump needs ≥2 GB RAM (azure_jumpoint_vm_size Standard_B1ms minimum, Standard_B2s preferred — Settings → Integrations → Privileged Remote Access) — the deploy checks and refuses early with the remedy otherwise.
Cells
No OT cells yet.
Standalone OT Protocol Tunnel
A generic-TCP PRA protocol tunnel to any host the gateway can reach — for demoing against your own lab gear without deploying a cell.
Edit tags
Nothing removable — the tags on this selection are the dashboard's own.
Updated .
Queued for agent — this connection is reached through one, so the change lands when the job runs.
— view job
could not be updated:
—
already had it.
PRA access —
Creates a BeyondTrust PRA Shell Jump to this VM, so you reach it over SSH through the representative console. Blank fields use the configured defaults. Destroying the VM removes the jump.
This VM has Shell Jump . Re-apply replaces it with one built from the options below.
PRA is not configured (bt_api_host / bt_client_id / bt_client_secret). Set it on Settings — the dropdowns stay empty and the job will fail until then.
Resolved to a bt_client_secret override for this jump's provisioning.