Skip to content

Connect Azure VMs

This guide shows you how to connect Azure virtual machines to Riptides using the AzureIMDS (Azure Instance Metadata Service) verifier. With AzureIMDS, daemons authenticate automatically using the signed identity token provided by the Azure IMDS — no manual tokens required.

Choose the installation method that matches your infrastructure:

  • Kubernetes — deploy the daemon as a Helm chart into an existing cluster
  • Virtual Machines — configure the daemon installed via the install script on Azure Linux VMs
  • A running Riptides control plane (see Getting Started)
  • kubectl configured to access the Riptides API
  • One or more Azure Linux VMs you want to connect
  • The VMs must be able to reach the control plane endpoint over the network
  • A managed identity attached to each VM — this is required and must be done before installing the daemon (see below)

Every Azure VM with a managed identity can request a signed identity token from the Azure Instance Metadata Service (IMDS) at http://169.254.169.254/metadata/identity/oauth2/token. The Riptides daemon retrieves this token and presents it to the control plane during registration. The control plane verifies the token signature using Microsoft’s public OIDC certificates and checks that the instance metadata (subscription ID, resource group, etc.) matches the Verifier’s requiredMetadata constraints.

Create a Verifier that accepts daemons presenting a valid Azure managed identity token. Use requiredMetadata to restrict which Azure subscriptions are allowed to register:

verifier-azureimds.yaml
apiVersion: auth.riptides.io/v1alpha1
kind: Verifier
metadata:
name: azureimds
namespace: riptides-system
spec:
AzureIMDS: {}
requiredMetadata:
- azureimds:subscription:id: "00000000-0000-0000-0000-000000000000"

Apply it:

Terminal window
riptides-cli ctl apply -f verifier-azureimds.yaml

Confirm the Verifier is available:

Terminal window
riptides-cli ctl get verifiers

Expected output:

NAME STATE
azureimds Available

Security note: Always set requiredMetadata with your Azure subscription ID to prevent VMs from unauthorized subscriptions from registering daemons. You can add multiple entries to allow several subscriptions.

To allow VMs from more than one Azure subscription:

spec:
AzureIMDS: {}
requiredMetadata:
- azureimds:subscription:id: "00000000-0000-0000-0000-000000000000"
- azureimds:subscription:id: "11111111-1111-1111-1111-111111111111"

A DaemonGroup lets you organize daemons into logical groups based on OS or other metadata, useful for scoping WorkloadIdentity assignments to your Azure fleet:

daemongroup-azure.yaml
apiVersion: core.riptides.io/v1alpha1
kind: DaemonGroup
metadata:
name: azure-linux-nodes
namespace: riptides-system
spec:
workloadID: riptides/daemongroup/azure-linux-nodes
selectors:
- linuxos:name: ubuntu
- linuxos:name: debian
- linuxos:name: fedora

Apply it:

Terminal window
riptides-cli ctl apply -f daemongroup-azure.yaml

This group will automatically include any connected daemon running Ubuntu, Debian, or Fedora. You can later scope WorkloadIdentity resources to this group using the scope.daemonGroup.id field.

Additional prerequisites for Kubernetes:

  • Kubernetes cluster v1.26 or later
  • Helm v3.12 or later

When installing the daemon via Helm, set authPlugin.type to AzureIMDS and enable the azure metadata collector so the daemon can retrieve the identity token from the Azure IMDS. Use the following values.yaml in place of the one shown in the getting-started guide:

daemon-values-azure.yaml
config:
daemon:
metadataCollectors:
procfs:
enabled: true
linuxos:
enabled: true
azure:
enabled: true
kubernetes:
enabled: true
kubeletHost: localhost
kubeletPort: 10250
kubeletCA: /etc/kubernetes/pki/ca.crt
skipKubeletVerification: true
credentials: /var/run/secrets/kubernetes.io/serviceaccount/token
controlPlane:
enabled: true
url: https://<your-env-id>.console.riptides.io
authPlugin:
type: AzureIMDS
dataDir: /data/riptides

Note: The azure metadata collector must be enabled — the daemon requests the identity token from http://169.254.169.254/metadata/identity/oauth2/token to authenticate with the control plane. The managed identity must be attached to the VM or node pool. The trustDomain must match the value configured on the control plane.

By default the daemon requests an identity token for the resource https://management.azure.com/, which must match the resource configured in your AzureIMDS Verifier. To use a different resource URI, set authPlugin.resource in your values.yaml:

authPlugin:
type: AzureIMDS
resource: https://my-custom-resource.example.com/

After deploying the daemon, check that your Azure nodes have registered:

Terminal window
riptides-cli ctl get daemons

You should see entries like:

NAME WORKLOAD-ID STATE
a1b2c3d4-e5f6-7890-abcd-e01234567890 riptides/daemon/my-subscription/my-resource-group/my-vm Connected

Run the install script with --azureimds. The script auto-detects Azure VMs, but you can pass the flag explicitly:

Terminal window
curl -fsSL https://docs.riptides.io/install.sh | sudo bash -s -- \
--controlplane-url https://<your-env-id>.console.riptides.io \
--azureimds

The script installs the kernel driver and daemon, writes /etc/riptides/config.yaml with authPlugin.type: AzureIMDS, and starts the riptides systemd service. The daemon authenticates automatically using the VM’s managed identity on first start.

Note: The managed identity must be attached to the VM before running the installer. The azure metadata collector is enabled automatically by the daemon when authPlugin.type is AzureIMDS.

To follow live logs and confirm a successful AzureIMDS handshake:

Terminal window
sudo journalctl -u riptides -f

By default the daemon requests an identity token for the resource https://management.azure.com/, which must match the resource configured in your AzureIMDS Verifier. If you configured your Verifier with a different resource URI, pass it as an argument to --azureimds:

Terminal window
curl -fsSL https://docs.riptides.io/install.sh | sudo bash -s -- \
--controlplane-url https://<your-env-id>.console.riptides.io \
--azureimds https://my-custom-resource.example.com/

Confirm the daemon has registered with the control plane:

Terminal window
riptides-cli ctl get daemons

You should see an entry like:

NAME WORKLOAD-ID STATE
a1b2c3d4-e5f6-7890-abcd-e01234567890 riptides/daemon/my-subscription/my-resource-group/my-vm Connected

When the daemon starts on an Azure VM, it:

  1. Requests a signed identity token from the Azure IMDS (http://169.254.169.254/metadata/identity/oauth2/token)
  2. Sends the token to the Riptides control plane
  3. The control plane verifies the token signature using Microsoft’s public OIDC certificates
  4. The control plane checks that the instance’s subscription ID matches the Verifier’s requiredMetadata
  5. On success, the daemon is registered and receives a workload ID in the format riptides/daemon/<subscription-id>/<resource-group>/<vm-name> (for example, riptides/daemon/my-subscription/my-resource-group/my-vm)

No tokens to distribute, no secrets to manage — the VM’s managed identity is the credential.

Now that your Azure nodes are connected, create WorkloadIdentity resources to assign SPIFFE identities to workloads running on those VMs. Scope identities to your DaemonGroup so they only apply to your Azure fleet:

workload-identity-azure.yaml
apiVersion: core.riptides.io/v1alpha1
kind: WorkloadIdentity
metadata:
name: my-backend-service
namespace: riptides-system
spec:
workloadID: my-app/backend-service
scope:
daemonGroup:
id: riptides/daemongroup/azure-linux-nodes
selectors:
- process:name: backend-service
connection:
tls:
mode: PERMISSIVE

Apply it:

Terminal window
riptides-cli ctl apply -f workload-identity-azure.yaml

Any process named backend-service running on a node in the azure-linux-nodes daemon group will receive the SPIFFE ID spiffe://example.com/my-app/backend-service.

For full details on WorkloadIdentity configuration, see the WorkloadIdentity reference.

SymptomPossible CauseResolution
riptides-modules fails to loadTrusted Launch / Secure Boot enabledDisable Secure Boot in the VM’s security configuration, or switch to a standard Generation 2 VM
Daemon does not appear in riptides-cli ctl get daemonsDaemon cannot reach control planeVerify network connectivity and firewall rules between the Azure VM and the control plane endpoint
Daemon shows authentication errorSubscription ID mismatchCheck that the Verifier’s requiredMetadata includes the correct Azure subscription ID
Daemon shows authentication errorNo managed identity attachedEnsure the VM has a system-assigned or user-assigned managed identity configured in the Azure portal
Daemon shows authentication errorIMDS not accessibleConfirm the VM can reach http://169.254.169.254 (this is available by default on Azure VMs)
DaemonGroup shows no daemonsSelector mismatchVerify the linuxos:name selector matches the OS running on your instances
VM daemon fails after config changeStale processRun sudo systemctl restart riptides and check journalctl -u riptides