Automatically discover which resource group contains your VM, eliminating the need to specify --resource-group on every connection.
Auto-detect resource group is an azlin feature that automatically finds your VM across all resource groups in your Azure subscription. When you run azlin connect my-vm without specifying --resource-group, azlin:
- Checks its cache for a recent resource group mapping
- If not cached, queries Azure for VMs with the matching name or session tag
- Caches the result for future connections (15-minute TTL)
- Uses the discovered resource group for the connection
This eliminates "VM not found" errors when VMs are moved between resource groups or when you don't remember which resource group contains a specific VM.
Auto-detect resource group solves several common pain points:
Your VM was in rg-dev, but your team moved it to rg-prod. Now your connection fails:
azlin connect my-vm --resource-group rg-devError:
Error: VM 'my-vm' not found in resource group 'rg-dev'
Without auto-detect: You manually search for the VM, update your config file, and retry.
With auto-detect: azlin finds the VM in rg-prod automatically:
azlin connect my-vm
# Discovered VM 'my-vm' in resource group 'rg-prod' ✓You have 20 VMs across 5 resource groups. You want to connect to a specific VM but can't remember its resource group.
Without auto-detect: You run az vm list to search, then copy the resource group name.
With auto-detect: Just use the VM name:
azlin connect my-vm
# Auto-discovery finds the VM wherever it livesYou use azlin sessions (e.g., atg-dev, frontend-test) and want to reconnect without remembering VM details.
Without auto-detect: You look up the VM name and resource group from your notes or config file.
With auto-detect: Use the session name directly:
azlin connect atg-dev
# Finds VM by azlin-session tag: "atg-dev"You have VMs in multiple regions, each in a different resource group (rg-eastus, rg-westus, etc.).
Without auto-detect: You must remember or look up which region each VM is in.
With auto-detect: Just connect, azlin finds the right resource group:
azlin connect my-vm
# Auto-detects: my-vm is in rg-westusWhen you run azlin connect my-vm without --resource-group:
1. Check local cache (~/.azlin/cache/rg_cache.json)
├─▶ Cache hit (< 15 min old) → Use cached resource group
└─▶ Cache miss or expired → Continue to step 2
2. Query Azure for VM
├─▶ az vm list --query "[?tags.managed-by=='azlin' && ...]"
└─▶ Returns: [{name: "my-vm", resourceGroup: "rg-prod", ...}]
3. Cache the result
└─▶ Save to ~/.azlin/cache/rg_cache.json (15-min TTL)
4. Use discovered resource group
└─▶ Connect to my-vm in rg-prod
azlin searches for VMs in this order:
-
Cache lookup (fast: <100ms)
- Check if session name or VM name is in cache
- Verify cache entry is not expired (< 15 minutes old)
-
Azure tags query (moderate: 2-3 seconds)
- Search all VMs with
managed-by=azlintag - Match by VM name OR
azlin-sessiontag - Cache the result for future lookups
- Search all VMs with
-
Config file fallback (fast: <10ms)
- Check
~/.azlin/config.tomlfor explicit resource group mapping - Backward compatibility with older azlin configs
- Check
-
Default resource group (fast: <10ms)
- Use
default_resource_groupfrom config file - Last resort if all else fails
- Use
The discovery query looks like this:
az vm list \
--query "[?tags.\"managed-by\"=='azlin' &&
(name=='my-vm' || tags.\"azlin-session\"=='my-vm')].
{name:name, resourceGroup:resourceGroup,
sessionName:tags.\"azlin-session\"}" \
--output jsonExample result:
[
{
"name": "azlin-atg-dev-20241120",
"resourceGroup": "rg-eastus",
"sessionName": "atg-dev"
}
]From this, azlin knows atg-dev session is in resource group rg-eastus.
Cache is stored at ~/.azlin/cache/rg_cache.json:
{
"version": 1,
"entries": {
"atg-dev": {
"vm_name": "azlin-atg-dev-20241120",
"resource_group": "rg-eastus",
"session_name": "atg-dev",
"timestamp": 1732628400,
"ttl": 900
},
"my-vm": {
"vm_name": "my-vm",
"resource_group": "rg-prod",
"session_name": null,
"timestamp": 1732628500,
"ttl": 900
}
}
}Cache Hit (Fresh Entry)
azlin connect atg-dev
# Cache hit: using cached resource group 'rg-eastus' (<1 minute old)
# Connecting to azlin-atg-dev-20241120...Performance: ~100ms (no Azure query needed)
Cache Miss (No Entry)
azlin connect new-vm
# Resource group not cached, querying Azure...
# Discovered VM 'new-vm' in resource group 'rg-dev'
# Caching result for future connections...
# Connecting to new-vm...Performance: 2-3 seconds (Azure query + cache write)
Cache Expired (> 15 minutes old)
azlin connect atg-dev
# Cache entry expired (17 minutes old), refreshing...
# Discovered VM 'azlin-atg-dev-20241120' in resource group 'rg-eastus'
# Cache updated
# Connecting to azlin-atg-dev-20241120...Performance: 2-3 seconds (Azure query + cache update)
The cache is automatically invalidated when:
-
Connection fails - If azlin connects to a VM using cached resource group but the VM is not found, the cache entry is deleted and discovery runs again:
azlin connect my-vm # Using cached resource group 'old-rg'... # Error: VM not found in 'old-rg' # Cache invalidated, retrying with fresh discovery... # Discovered VM 'my-vm' in resource group 'new-rg' # Connecting to my-vm...
-
Manual invalidation - You can force cache refresh:
azlin connect my-vm --force-rg-refresh
-
TTL expiration - Cache entries expire after 15 minutes (configurable)
-
Cache cleanup - On startup, azlin purges entries older than 1 hour
View cache contents:
cat ~/.azlin/cache/rg_cache.json | jq .Clear entire cache:
rm ~/.azlin/cache/rg_cache.jsonConnect without specifying resource group:
azlin connect my-vmOutput (cache hit):
Using cached resource group 'rg-prod' (source: cache) ✓
Connecting to my-vm...
Connected!
Output (cache miss):
Resource group not specified, attempting auto-discovery...
Querying Azure for VM 'my-vm'...
Discovered VM 'my-vm' in resource group 'rg-prod' (source: tags) ✓
Caching result for future connections...
Connecting to my-vm...
Connected!
Connect using session name:
azlin connect atg-devOutput:
Resource group not specified, attempting auto-discovery...
Discovered VM 'azlin-atg-dev-20241120' in resource group 'rg-eastus' ✓
Session: atg-dev
Connecting to azlin-atg-dev-20241120...
Connected!
The cache now contains:
{
"atg-dev": {
"vm_name": "azlin-atg-dev-20241120",
"resource_group": "rg-eastus",
"session_name": "atg-dev"
}
}Next connection is instant:
azlin connect atg-dev
# Cache hit: using cached resource group 'rg-eastus' (<1 minute old) ✓Initial connection (VM in rg-dev):
azlin connect my-vm
# Discovered VM 'my-vm' in resource group 'rg-dev'VM is moved to rg-prod. Next connection:
azlin connect my-vm
# Using cached resource group 'rg-dev'...
# Error: VM 'my-vm' not found in resource group 'rg-dev'
# Cache invalidated, retrying discovery...
# Discovered VM 'my-vm' in resource group 'rg-prod' ✓
# Cache updated
# Connecting to my-vm...The cache is now updated with the new resource group.
Bypass cache and force fresh discovery:
azlin connect my-vm --force-rg-refreshOutput:
Forcing fresh resource group discovery...
Querying Azure for VM 'my-vm'...
Discovered VM 'my-vm' in resource group 'rg-prod'
Cache updated
Connecting to my-vm...
Provide resource group explicitly:
azlin connect my-vm --resource-group rg-prodOutput:
Using specified resource group 'rg-prod'
Skipping auto-discovery
Connecting to my-vm...
The cache is still updated for future auto-detect connections.
If you have VMs with the same name in different resource groups:
azlin connect my-vmOutput:
Resource group not specified, attempting auto-discovery...
Multiple VMs found with name 'my-vm':
1. my-vm (rg-dev) - Session: dev
2. my-vm (rg-prod) - Session: prod
3. my-vm (rg-staging) - Session: staging
Select VM [1-3]: 2
You select #2, and azlin caches your choice:
{
"my-vm": {
"vm_name": "my-vm",
"resource_group": "rg-prod",
"session_name": "prod"
}
}Future connections use rg-prod automatically until you clear the cache or the entry expires.
Enable auto-detect (default):
azlin config set resource_group.auto_detect trueDisable auto-detect globally:
azlin config set resource_group.auto_detect falseWhen disabled, you must specify --resource-group on every connection.
Change cache expiration time (default: 900 seconds = 15 minutes):
# Cache for 1 hour
azlin config set resource_group.cache_ttl 3600
# Cache for 5 minutes (aggressive invalidation)
azlin config set resource_group.cache_ttl 300
# Cache for 24 hours (slow-changing environments)
azlin config set resource_group.cache_ttl 86400Change Azure query timeout (default: 30 seconds):
azlin config set resource_group.query_timeout 60When auto-detect fails, use default resource group:
azlin config set resource_group.fallback_to_default true
azlin config set default_resource_group rg-fallbackNow if discovery fails:
azlin connect unknown-vm
# Auto-discovery failed
# Falling back to default resource group 'rg-fallback'
# Connecting to unknown-vm in rg-fallback...Edit ~/.azlin/config.toml directly:
[resource_group]
auto_detect = true # Enable auto-detection
cache_ttl = 900 # Cache TTL in seconds (15 min)
query_timeout = 30 # Azure query timeout
fallback_to_default = true # Use default RG if discovery fails
default_resource_group = "rg-default" # Fallback RG| Flag | Description | Example |
|---|---|---|
--resource-group=RG |
Explicitly specify resource group (skips auto-detect) | azlin connect vm --resource-group rg-prod |
--no-auto-detect-rg |
Disable auto-detect for this connection | azlin connect vm --no-auto-detect-rg --resource-group rg |
--force-rg-refresh |
Force cache refresh (ignore cached value) | azlin connect vm --force-rg-refresh |
Error:
Error: Auto-discovery failed - No VMs found with identifier 'my-vm'
Use --resource-group to specify explicitly
Cause: No VMs match the name or session tag in your Azure subscription.
Solutions:
-
List all azlin-managed VMs:
azlin list # Shows all VMs with managed-by=azlin tag -
Check if VM exists in Azure:
az vm list --query "[?name=='my-vm']" -o table -
Verify VM has
managed-by=azlintag:az vm show --name my-vm --resource-group rg-prod \ --query "tags.\"managed-by\"" -o tsvIf missing, add the tag:
az vm update --name my-vm --resource-group rg-prod \ --set tags.managed-by=azlin
-
Specify resource group explicitly:
azlin connect my-vm --resource-group rg-prod
Error:
Multiple VMs found with name 'my-vm':
1. my-vm (rg-dev) - Session: dev
2. my-vm (rg-prod) - Session: prod
Select VM [1-2]:
Cause: You have multiple VMs with the same name in different resource groups.
Solutions:
-
Select the correct VM from the list (azlin will cache your choice)
-
Use session name instead of VM name:
azlin connect dev # Connects to VM with session tag "dev" azlin connect prod # Connects to VM with session tag "prod"
-
Specify resource group explicitly:
azlin connect my-vm --resource-group rg-dev
-
Rename VMs to be unique:
az vm update --name my-vm --resource-group rg-dev \ --set tags.azlin-session=my-vm-dev
Error:
Warning: Resource group discovery timed out (30 seconds)
Falling back to default resource group 'rg-default'
Cause: Azure query took too long (slow network, large subscription).
Solutions:
-
Increase query timeout:
azlin config set resource_group.query_timeout 60 azlin connect my-vm -
Check Azure service status:
az monitor service-health list-events
-
Use cached result if available:
# Wait a moment for timeout, then retry # Cache from previous successful connection will be used azlin connect my-vm
-
Specify resource group to skip query:
azlin connect my-vm --resource-group rg-prod
Error:
Warning: Resource group cache corrupted, rebuilding...
Cause: The cache file is malformed or has invalid JSON.
Solutions:
-
Delete corrupted cache (azlin rebuilds automatically):
rm ~/.azlin/cache/rg_cache.json azlin connect my-vm -
Verify cache permissions:
ls -la ~/.azlin/cache/rg_cache.json # Should be -rw------- (0600)
-
Manually recreate cache directory:
mkdir -p ~/.azlin/cache chmod 700 ~/.azlin/cache
Error:
Error: Permission denied - Cannot list VMs in subscription
You need 'Reader' role at subscription or resource group level
Cause: Your Azure account lacks permissions to list VMs.
Solutions:
-
Request Reader role:
# Ask your Azure admin to grant this role: az role assignment create \ --assignee your-email@company.com \ --role "Reader" \ --scope "/subscriptions/<subscription-id>"
-
Use explicit resource group (requires Reader role only on that RG):
azlin connect my-vm --resource-group rg-prod
-
Disable auto-detect and use config file:
azlin config set resource_group.auto_detect false azlin config set default_resource_group rg-prod
Problem: VM was deleted, but cache still references it.
Symptom:
azlin connect old-vm
# Using cached resource group 'rg-old'...
# Error: VM 'old-vm' not found
# Cache invalidated (VM not found)
# Auto-discovery failed - No VMs foundSolution: Cache is automatically invalidated. No action needed.
To manually clear the cache entry:
rm ~/.azlin/cache/rg_cache.jsonNot currently. Auto-detect searches only the active Azure subscription. If you have VMs in multiple subscriptions, switch subscriptions first:
az account set --subscription "My Other Subscription"
azlin connect my-vmMulti-subscription support is planned for a future release.
Cache entries reference resource groups by name. If you rename a resource group in Azure:
- Existing cache entries become stale
- Next connection attempt fails (VM not found in old RG)
- Cache is invalidated automatically
- Fresh discovery finds VM in new RG
No manual intervention required.
No. Auto-detect only works with VM names or session names. If you specify an IP address, azlin skips auto-detect:
azlin connect 10.0.1.5 --resource-group rg-prodResource groups can contain VMs in different regions. Auto-detect doesn't care about regions - it searches all resource groups and returns the RG containing your VM, regardless of region.
Auto-detect won't find it by default. Add the tag manually:
az vm update --name my-vm --resource-group rg-prod \
--set tags.managed-by=azlinOr use --resource-group explicitly:
azlin connect my-vm --resource-group rg-prodYes. If you have Reader access to only specific resource groups, auto-detect searches only those groups. VMs in other resource groups won't be discovered.
Auto-detect uses the Azure CLI az vm list command, which is a read-only operation. Azure does not charge for read operations like this. The only cost is your time (2-3 seconds for the query).
Yes, run with debug logging:
azlin --debug connect my-vmOutput includes:
DEBUG: Running Azure query: az vm list --query "..."
DEBUG: Query returned 3 VMs: [{"name": "my-vm", ...}]
DEBUG: Selected VM: my-vm in rg-prod
No. The cache file contains only non-sensitive information (VM names, resource group names, timestamps). It has 0600 permissions (owner read/write only) to prevent tampering.
Each user has their own cache file under their home directory (~/.azlin/cache/rg_cache.json). Caches are isolated by user account.
Measure cache hit rate:
cat ~/.azlin/cache/rg_cache.json | \
jq '.entries | length'
# Shows number of cached entries
# Check freshness of entries
cat ~/.azlin/cache/rg_cache.json | \
jq '.entries | to_entries[] |
{key: .key, age_seconds: (now - .value.timestamp)}'Track discovery latency over time:
azlin --debug connect my-vm 2>&1 | \
grep "Discovery completed" | \
awk '{print $NF}'
# Prints discovery time in millisecondsCreate a monitoring script:
#!/bin/bash
for vm in vm1 vm2 vm3; do
start=$(date +%s%N)
azlin connect $vm --dry-run >/dev/null 2>&1
end=$(date +%s%N)
echo "$vm: $((($end - $start) / 1000000))ms"
done- Auto-Sync SSH Keys - Automatic key synchronization
- Configuration Reference - Complete configuration options
- Troubleshooting Connection Issues - Comprehensive troubleshooting guide
- Managing Multiple VMs - Working with many VMs efficiently
Found a bug or have a feature request? Open an issue on GitHub.
Have questions? Start a discussion.