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
- An Azure subscription with an active resource group
- Azure CLI installed and configured
- Network connectivity between Azure and your on-premise AD via Azure VPN Gateway or ExpressRoute
- Access to the SlashID Docker registry (request via Slack or support@slashid.com)
STEP 1: Create the connection on the SlashID Console
In the SlashID Console > Configuration > Data sources > Add data source and select Active Directory from the list.
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
- 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.
- 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
- Ensure your VNet has connectivity to your on-premise AD via Azure VPN Gateway or ExpressRoute.
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 IDyour.domain.local- your AD domainadmin.user- your AD admin usernamefirst.controller.your.domain.local- your domain controller FQDN- Docker registry credentials (request access from SlashID)
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:
| Endpoint | Purpose |
|---|---|
/health | Detailed health status of all agents |
/health/live | Liveness probe (is the process running?) |
/health/ready | Readiness 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
| Variable | Required | Description |
|---|---|---|
AD_SNAPSHOT_N_DOMAIN | Yes | Your AD domain name |
AD_SNAPSHOT_N_USERNAME | Yes | Username (Domain Admins member, RID 512) |
AD_SNAPSHOT_N_PASSWORD | Yes | Password for the admin user |
AD_SNAPSHOT_N_TARGET_DC | Yes | Domain controller FQDN or IP |
AD_SNAPSHOT_N_SLASHID_AUTH_TOKEN | Yes | Token from STEP 1 |
AD_SNAPSHOT_N_LDAPS | No | Enable LDAPS (default: false) |
AD_SNAPSHOT_N_LDAPS_PORT | No | LDAPS port (default: 636) |
AD_SNAPSHOT_N_COLLECTION_METHOD | No | All or Computers |
AD_SNAPSHOT_N_FQDN_RESOLVER | No | DNS server IP for FQDN resolution |
WMI_N_DOMAIN | Yes | Your AD domain name |
WMI_N_USERNAME | Yes | Username (Domain Admins member) |
WMI_N_PASSWORD | Yes | Password for the admin user |
WMI_N_TARGET_DC | Yes | Domain controller FQDN or IP |
WMI_N_SLASHID_AUTH_TOKEN | Yes | Token from STEP 1 |
WMI_N_KERBEROS_AUTH | No | Use Kerberos auth (default: false) |
WMI_N_AES_KEY | No | AES key for Kerberos auth |
HEALTH_PORT | No | Health server port (default: 8080) |
HEALTH_SERVER_ENABLED | No | Enable health server (default: true) |
- Configure one
AD_SNAPSHOT_Nentry per AD domain - Configure one
WMI_Nentry per domain controller - Replace
Nwith sequential numbers (1, 2, 3...)
Example: Multiple domains
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
- Check the container status:
az container show \
--name slashid-ad-collector \
--resource-group slashid-rg \
--query "{Status:instanceView.state, IP:ipAddress.ip}"
- View logs:
az container logs \
--name slashid-ad-collector \
--resource-group slashid-rg
- 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
- Verify the VNet peering or VPN connection is active
- Check that your Network Security Group (NSG) allows the required ports
- 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
- Verify registry credentials are correct
- 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
- Verify the credentials belong to a Domain Admins (RID 512) member
- Check that the username format matches your AD configuration
- 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