Skip to main content

On-premise Active Directory on Azure Container Instances

This guide walks you through deploying the SlashID Collector on Azure Container Instances (ACI) to monitor your on-premise Active Directory (AD) cluster.

Prerequisites

STEP 1: Create the connection on the SlashID Console

  1. In the SlashID Console > Configuration > Data sources > Add data source and select Active Directory from the list.

  2. Complete the following fields:

  • Name of the connection: an arbitrary name for your new connection
  • Authoritative status: whether this connection should be the primary source of truth to reconcile identities across providers
  1. Once the initial connector is created, it will appear in Configuration > Data sources. From this page, copy the Event streaming token and store it temporarily, as you will need it in the following step.

STEP 2: Set up VNet connectivity

Azure Container Instances requires a VNet to reach your on-premise network.

  1. Create a VNet with a subnet delegated to ACI (if you don't already have one):
# Create a resource group
az group create --name slashid-rg --location eastus

# Create a VNet
az network vnet create \
--name slashid-vnet \
--resource-group slashid-rg \
--address-prefix 10.0.0.0/16 \
--subnet-name aci-subnet \
--subnet-prefix 10.0.1.0/24

# Delegate the subnet to Azure Container Instances
az network vnet subnet update \
--name aci-subnet \
--vnet-name slashid-vnet \
--resource-group slashid-rg \
--delegations Microsoft.ContainerInstance/containerGroups
  1. Ensure your VNet has connectivity to your on-premise AD via Azure VPN Gateway or ExpressRoute.
Network Requirements

The VNet needs to reach your domain controllers on the following ports:

  • TCP 389 (LDAP) or TCP 636 (LDAPS)
  • TCP 135, 445, and dynamic RPC ports (WMI)

STEP 3: Store credentials in Key Vault

Store your AD credentials securely in Azure Key Vault:

# Create a Key Vault
az keyvault create \
--name slashid-kv \
--resource-group slashid-rg \
--location eastus

# Store secrets
az keyvault secret set \
--vault-name slashid-kv \
--name slashid-ad-password \
--value "your-ad-password"

az keyvault secret set \
--vault-name slashid-kv \
--name slashid-auth-token \
--value "your-event-streaming-token"

STEP 4: Create a managed identity

Create a managed identity for the container to access Key Vault secrets:

# Create a managed identity
az identity create \
--name slashid-identity \
--resource-group slashid-rg

# Get the identity's principal ID and resource ID
IDENTITY_ID=$(az identity show --name slashid-identity --resource-group slashid-rg --query id -o tsv)
PRINCIPAL_ID=$(az identity show --name slashid-identity --resource-group slashid-rg --query principalId -o tsv)

# Grant the identity access to Key Vault secrets
az keyvault set-policy \
--name slashid-kv \
--object-id $PRINCIPAL_ID \
--secret-permissions get list

STEP 5: Create the deployment definition

Create a deploy.yaml file to define your container group:

apiVersion: '2023-05-01'
location: eastus
name: slashid-ad-collector
properties:
containers:
- name: slashid-agent
properties:
image: slashid/agent:latest
resources:
requests:
cpu: 1.0
memoryInGb: 1.0
ports:
- port: 8080
protocol: TCP
environmentVariables:
# AD Snapshot configuration
- name: AD_SNAPSHOT_1_DOMAIN
value: 'your.domain.local'
- name: AD_SNAPSHOT_1_USERNAME
value: 'admin.user'
- name: AD_SNAPSHOT_1_TARGET_DC
value: 'first.controller.your.domain.local'
- name: AD_SNAPSHOT_1_PASSWORD
secureValue: 'your-ad-password' # Replace at deploy time
- name: AD_SNAPSHOT_1_SLASHID_AUTH_TOKEN
secureValue: 'your-event-streaming-token' # Replace at deploy time
# WMI Event Streamer configuration
- name: WMI_1_DOMAIN
value: 'your.domain.local'
- name: WMI_1_USERNAME
value: 'admin.user'
- name: WMI_1_TARGET_DC
value: 'first.controller.your.domain.local'
- name: WMI_1_PASSWORD
secureValue: 'your-ad-password' # Replace at deploy time
- name: WMI_1_SLASHID_AUTH_TOKEN
secureValue: 'your-event-streaming-token' # Replace at deploy time
osType: Linux
restartPolicy: Always
ipAddress:
type: Private
ports:
- port: 8080
protocol: TCP
subnetIds:
- id: /subscriptions/YOUR_SUBSCRIPTION_ID/resourceGroups/slashid-rg/providers/Microsoft.Network/virtualNetworks/slashid-vnet/subnets/aci-subnet
imageRegistryCredentials:
- server: docker.io
username: 'your-docker-username'
password: 'your-docker-password'
type: Microsoft.ContainerInstance/containerGroups

Replace the following values:

  • YOUR_SUBSCRIPTION_ID - your Azure subscription ID
  • your.domain.local - your AD domain
  • admin.user - your AD admin username
  • first.controller.your.domain.local - your domain controller FQDN
  • Docker registry credentials (request access from SlashID)
Using Key Vault references

For production deployments, use Azure Container Apps instead of ACI for native Key Vault integration, or retrieve secrets at deployment time using a script (see below).

STEP 6: Deploy with secrets from Key Vault

Create a deployment script that fetches secrets from Key Vault:

#!/bin/bash

# Fetch secrets from Key Vault
AD_PASSWORD=$(az keyvault secret show --vault-name slashid-kv --name slashid-ad-password --query value -o tsv)
AUTH_TOKEN=$(az keyvault secret show --vault-name slashid-kv --name slashid-auth-token --query value -o tsv)

# Deploy the container group
az container create \
--resource-group slashid-rg \
--name slashid-ad-collector \
--image slashid/agent:latest \
--cpu 1 \
--memory 1 \
--ports 8080 \
--vnet slashid-vnet \
--subnet aci-subnet \
--restart-policy Always \
--environment-variables \
AD_SNAPSHOT_1_DOMAIN=your.domain.local \
AD_SNAPSHOT_1_USERNAME=admin.user \
AD_SNAPSHOT_1_TARGET_DC=first.controller.your.domain.local \
WMI_1_DOMAIN=your.domain.local \
WMI_1_USERNAME=admin.user \
WMI_1_TARGET_DC=first.controller.your.domain.local \
--secure-environment-variables \
AD_SNAPSHOT_1_PASSWORD="$AD_PASSWORD" \
AD_SNAPSHOT_1_SLASHID_AUTH_TOKEN="$AUTH_TOKEN" \
WMI_1_PASSWORD="$AD_PASSWORD" \
WMI_1_SLASHID_AUTH_TOKEN="$AUTH_TOKEN"

Save this as deploy.sh, update the values, and run:

chmod +x deploy.sh
./deploy.sh

STEP 7: Verify health checks

The collector exposes health endpoints on port 8080:

EndpointPurpose
/healthDetailed health status of all agents
/health/liveLiveness probe (is the process running?)
/health/readyReadiness probe (are agents healthy?)

To check health from within your VNet, you can deploy a jump box or use Azure Bastion:

# Get the container's private IP
az container show \
--name slashid-ad-collector \
--resource-group slashid-rg \
--query ipAddress.ip -o tsv

# From a VM in the same VNet
curl http://<CONTAINER_IP>:8080/health

Configuration reference

# Active Directory Snapshot Uploaders (One per AD domain) AD_SNAPSHOT_1_DOMAIN=your.domain.local AD_SNAPSHOT_1_USERNAME=admin.user AD_SNAPSHOT_1_PASSWORD=admin-password AD_SNAPSHOT_1_TARGET_DC=first.controller.your.domain.local AD_SNAPSHOT_1_SLASHID_AUTH_TOKEN=123456789 # WMI Event Streamers (One per Domain Controller) WMI_1_DOMAIN=your.domain.local WMI_1_USERNAME=admin.user WMI_1_PASSWORD=admin-password WMI_1_TARGET_DC=first.controller.your.domain.local WMI_1_SLASHID_AUTH_TOKEN=123456789 WMI_2_DOMAIN=your.domain.local WMI_2_USERNAME=admin.user WMI_2_PASSWORD=admin-password WMI_2_TARGET_DC=second.controller.your.domain.local WMI_2_SLASHID_AUTH_TOKEN=123456789
VariableRequiredDescription
AD_SNAPSHOT_N_DOMAINYesYour AD domain name
AD_SNAPSHOT_N_USERNAMEYesUsername (Domain Admins member, RID 512)
AD_SNAPSHOT_N_PASSWORDYesPassword for the admin user
AD_SNAPSHOT_N_TARGET_DCYesDomain controller FQDN or IP
AD_SNAPSHOT_N_SLASHID_AUTH_TOKENYesToken from STEP 1
AD_SNAPSHOT_N_LDAPSNoEnable LDAPS (default: false)
AD_SNAPSHOT_N_LDAPS_PORTNoLDAPS port (default: 636)
AD_SNAPSHOT_N_COLLECTION_METHODNoAll or Computers
AD_SNAPSHOT_N_FQDN_RESOLVERNoDNS server IP for FQDN resolution
WMI_N_DOMAINYesYour AD domain name
WMI_N_USERNAMEYesUsername (Domain Admins member)
WMI_N_PASSWORDYesPassword for the admin user
WMI_N_TARGET_DCYesDomain controller FQDN or IP
WMI_N_SLASHID_AUTH_TOKENYesToken from STEP 1
WMI_N_KERBEROS_AUTHNoUse Kerberos auth (default: false)
WMI_N_AES_KEYNoAES key for Kerberos auth
HEALTH_PORTNoHealth server port (default: 8080)
HEALTH_SERVER_ENABLEDNoEnable health server (default: true)
note
  • Configure one AD_SNAPSHOT_N entry per AD domain
  • Configure one WMI_N entry per domain controller
  • Replace N with sequential numbers (1, 2, 3...)

Example: Multiple domains

# Active Directory Snapshot Uploaders (One per AD domain) # Required AD_SNAPSHOT_1_DOMAIN=north.sevenkingdoms.local AD_SNAPSHOT_1_USERNAME=brandon.stark AD_SNAPSHOT_1_PASSWORD=*** AD_SNAPSHOT_1_TARGET_DC=winterfell.north.sevenkingdoms.local AD_SNAPSHOT_1_SLASHID_AUTH_TOKEN=*** # Optional AD_SNAPSHOT_2_COLLECTION_METHOD=All AD_SNAPSHOT_1_LDAPS=false AD_SNAPSHOT_1_LDAPS_PORT=636 AD_SNAPSHOT_1_FQDN_RESOLVER=192.168.56.11 # Required AD_SNAPSHOT_2_DOMAIN=south.sevenkingdoms.local AD_SNAPSHOT_2_USERNAME=arya.stark AD_SNAPSHOT_2_PASSWORD=*** AD_SNAPSHOT_2_TARGET_DC=braavos.south.sevenkingdoms.local AD_SNAPSHOT_2_SLASHID_AUTH_TOKEN=*** # Optional AD_SNAPSHOT_2_COLLECTION_METHOD=Computers AD_SNAPSHOT_2_LDAPS=true AD_SNAPSHOT_2_LDAPS_PORT=689 AD_SNAPSHOT_2_FQDN_RESOLVER=192.168.56.12 # WMI Event Streamers (One per Domain Controller) # Required WMI_1_DOMAIN=north.sevenkingdoms.local WMI_1_USERNAME=bran.stark WMI_1_PASSWORD=*** WMI_1_TARGET_DC=winterfell.north.sevenkingdoms.local WMI_1_SLASHID_AUTH_TOKEN=*** # Optional WMI_1_KERBEROS_AUTH=false # Required WMI_2_DOMAIN=south.sevenkingdoms.local WMI_2_USERNAME=jaqen.hghar WMI_2_PASSWORD=*** WMI_2_TARGET_DC=braavos.south.sevenkingdoms.local WMI_2_SLASHID_AUTH_TOKEN=*** # Optional WMI_2_KERBEROS_AUTH=true WMI_2_AES_KEY=***

For multiple domains, add additional environment variables to your deployment:

az container create \
--resource-group slashid-rg \
--name slashid-ad-collector \
--image slashid/agent:latest \
--cpu 1 \
--memory 1.5 \
--ports 8080 \
--vnet slashid-vnet \
--subnet aci-subnet \
--restart-policy Always \
--environment-variables \
AD_SNAPSHOT_1_DOMAIN=north.sevenkingdoms.local \
AD_SNAPSHOT_1_USERNAME=brandon.stark \
AD_SNAPSHOT_1_TARGET_DC=winterfell.north.sevenkingdoms.local \
AD_SNAPSHOT_2_DOMAIN=south.sevenkingdoms.local \
AD_SNAPSHOT_2_USERNAME=arya.stark \
AD_SNAPSHOT_2_TARGET_DC=braavos.south.sevenkingdoms.local \
WMI_1_DOMAIN=north.sevenkingdoms.local \
WMI_1_USERNAME=bran.stark \
WMI_1_TARGET_DC=winterfell.north.sevenkingdoms.local \
WMI_2_DOMAIN=south.sevenkingdoms.local \
WMI_2_USERNAME=jaqen.hghar \
WMI_2_TARGET_DC=braavos.south.sevenkingdoms.local \
--secure-environment-variables \
AD_SNAPSHOT_1_PASSWORD="$AD_PASSWORD_NORTH" \
AD_SNAPSHOT_1_SLASHID_AUTH_TOKEN="$AUTH_TOKEN" \
AD_SNAPSHOT_2_PASSWORD="$AD_PASSWORD_SOUTH" \
AD_SNAPSHOT_2_SLASHID_AUTH_TOKEN="$AUTH_TOKEN" \
WMI_1_PASSWORD="$AD_PASSWORD_NORTH" \
WMI_1_SLASHID_AUTH_TOKEN="$AUTH_TOKEN" \
WMI_2_PASSWORD="$AD_PASSWORD_SOUTH" \
WMI_2_SLASHID_AUTH_TOKEN="$AUTH_TOKEN"

Verify the deployment

  1. Check the container status:
az container show \
--name slashid-ad-collector \
--resource-group slashid-rg \
--query "{Status:instanceView.state, IP:ipAddress.ip}"
  1. View logs:
az container logs \
--name slashid-ad-collector \
--resource-group slashid-rg
  1. Attach to the container for real-time logs:
az container attach \
--name slashid-ad-collector \
--resource-group slashid-rg

Updating the deployment

To update configuration, delete and recreate the container group:

# Delete the existing container
az container delete \
--name slashid-ad-collector \
--resource-group slashid-rg \
--yes

# Redeploy with updated configuration
./deploy.sh

To update secrets:

# Update the secret in Key Vault
az keyvault secret set \
--vault-name slashid-kv \
--name slashid-ad-password \
--value "new-password"

# Redeploy to pick up the new secret
az container delete --name slashid-ad-collector --resource-group slashid-rg --yes
./deploy.sh

Troubleshooting

Container keeps restarting

Check the logs for errors:

az container logs --name slashid-ad-collector --resource-group slashid-rg

Common causes:

  • Invalid AD credentials
  • Network connectivity issues to domain controllers
  • Missing environment variables

Cannot connect to domain controller

  1. Verify the VNet peering or VPN connection is active
  2. Check that your Network Security Group (NSG) allows the required ports
  3. Verify DNS resolution works for domain controller FQDNs
# Check container events
az container show \
--name slashid-ad-collector \
--resource-group slashid-rg \
--query "instanceView.events"

Container fails to start

  1. Verify registry credentials are correct
  2. Check the subnet delegation is properly configured:
az network vnet subnet show \
--name aci-subnet \
--vnet-name slashid-vnet \
--resource-group slashid-rg \
--query delegations

Authentication failures

  1. Verify the credentials belong to a Domain Admins (RID 512) member
  2. Check that the username format matches your AD configuration
  3. Ensure secure environment variables are passed correctly
# Verify Key Vault access
az keyvault secret show --vault-name slashid-kv --name slashid-ad-password

Network troubleshooting

Test connectivity from within Azure:

# Deploy a test container in the same subnet
az container create \
--resource-group slashid-rg \
--name network-test \
--image mcr.microsoft.com/azure-cli \
--vnet slashid-vnet \
--subnet aci-subnet \
--command-line "sleep 3600"

# Exec into it to test connectivity
az container exec \
--resource-group slashid-rg \
--name network-test \
--exec-command "/bin/bash"

# From inside the container, test connectivity
nc -zv first.controller.your.domain.local 389
nc -zv first.controller.your.domain.local 135