July 23, 2026
Building a Azure SOC Lab: Infrastructure & Key Vault Deception (Stage 1)
Setting up a functional Security Operations Center (SOC) lab in the cloud often feels like a trade off between realism and high Azure…

By Pinac Joshi
3 min read
Setting up a functional Security Operations Center (SOC) lab in the cloud often feels like a trade off between realism and high Azure monthly bills. Thanks to my university, I was able to get a student Azure Subscription with limited credits of 100$. I wanted to learn how Azure Sentinel worked, along with IaC technology to quickly deploy and destroy the lab in order to preserve the credits.
In this first stage of my Azure SOC Lab Series, I am deploying a fully automated, cloud-native threat detection setup using Terraform, Microsoft Sentinel, and a sprinkle of Deception Engineering, all while keeping compute and storage costs near zero.
Here is how to deploy cloud infrastructure as code (IaC), establish telemetry pipelines, and trap attackers using decoy credentials.
🏗️ The Architecture Overview
Before diving into the code, here is how the Stage 1 environment is wired together
🧰 Tech Stack Breakdown
- IaC: Terraform (
azurermprovider v4.0+) - SIEM / Telemetry: Microsoft Sentinel, Azure Log Analytics Workspace (LAW), Kusto Query Language (KQL)
- Deception Targets: Azure Key Vault, Azure Blob Storage
- Diagnostic Pipeline: Azure Monitor Diagnostic Settings
1. Deploying Core SIEM & Decoy Infrastructure
The IaC script sets up a Log Analytics Workspace configured with a 30-day retention policy to avoid unexpected ingestion costs. It then onboards Microsoft Sentinel and provisions two honeypot targets, a Storage Account and an Azure Key Vault.
Here is a snippet from the deployment configuration:
# Resource Group & Free-Tier Log Analytics Workspace
resource "azurerm_resource_group" "rg" {
name = "rg-soc-lab-prod"
location = "norwayeast"
}
resource "azurerm_log_analytics_workspace" "law" {
name = "law-soc-${random_id.suffix.hex}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
sku = "PerGB2018"
retention_in_days = 30
}
# Decoy Key Vault with Bait Credential
resource "azurerm_key_vault_secret" "honey_secret" {
name = "db-prod-connection-string"
value = "Server=tcp:db-prod.database.windows.net;Database=customers;User=admin;Password=FakePassword123!"
key_vault_id = azurerm_key_vault.honey_kv.id
}# Resource Group & Free-Tier Log Analytics Workspace
resource "azurerm_resource_group" "rg" {
name = "rg-soc-lab-prod"
location = "norwayeast"
}
resource "azurerm_log_analytics_workspace" "law" {
name = "law-soc-${random_id.suffix.hex}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
sku = "PerGB2018"
retention_in_days = 30
}
# Decoy Key Vault with Bait Credential
resource "azurerm_key_vault_secret" "honey_secret" {
name = "db-prod-connection-string"
value = "Server=tcp:db-prod.database.windows.net;Database=customers;User=admin;Password=FakePassword123!"
key_vault_id = azurerm_key_vault.honey_kv.id
}Diagnostic Pipeline
To detect unauthorised access, diagnostic settings stream AuditEvent logs directly into Sentinel:
resource "azurerm_monitor_diagnostic_setting" "kv_diag" {
name = "kv-audit-to-sentinel"
target_resource_id = azurerm_key_vault.honey_kv.id
log_analytics_workspace_id = azurerm_log_analytics_workspace.law.id
enabled_log {
category = "AuditEvent"
}
}resource "azurerm_monitor_diagnostic_setting" "kv_diag" {
name = "kv-audit-to-sentinel"
target_resource_id = azurerm_key_vault.honey_kv.id
log_analytics_workspace_id = azurerm_log_analytics_workspace.law.id
enabled_log {
category = "AuditEvent"
}
}
2. Detection as Code: Sentinel Analytics Rules
Instead of manually creating detection rules in the Azure Portal GUI, I define the Sentinel rule inside HCL code. This rule triggers every 5 minutes if an unauthenticated probe attempts to read our bait secret.
resource "azurerm_sentinel_alert_rule_scheduled" "kv_honeypot_alert" {
name = "deception-honey-vault-access"
log_analytics_workspace_id = azurerm_log_analytics_workspace.law.id
display_name = "Deception - Unauthorized Honey-Vault Access Attempt"
severity = "High"
enabled = true
query_frequency = "PT5M"
query_period = "PT5M"
trigger_operator = "GreaterThan"
trigger_threshold = 0
# MITRE ATT&CK Mapping
tactics = ["CredentialAccess"]
techniques = ["T1552"]
query = <<-QUERY
AzureDiagnostics
| where ResourceType == "VAULTS"
| where Resource startswith "KV-HONEYPOT"
| where ResultSignature == "Unauthorized" or httpStatusCode_d == 401 or httpStatusCode_d == 403
| project TimeGenerated, Resource, OperationName, requestUri_s, CallerIPAddress, ResultSignature, httpStatusCode_d
QUERY
}resource "azurerm_sentinel_alert_rule_scheduled" "kv_honeypot_alert" {
name = "deception-honey-vault-access"
log_analytics_workspace_id = azurerm_log_analytics_workspace.law.id
display_name = "Deception - Unauthorized Honey-Vault Access Attempt"
severity = "High"
enabled = true
query_frequency = "PT5M"
query_period = "PT5M"
trigger_operator = "GreaterThan"
trigger_threshold = 0
# MITRE ATT&CK Mapping
tactics = ["CredentialAccess"]
techniques = ["T1552"]
query = <<-QUERY
AzureDiagnostics
| where ResourceType == "VAULTS"
| where Resource startswith "KV-HONEYPOT"
| where ResultSignature == "Unauthorized" or httpStatusCode_d == 401 or httpStatusCode_d == 403
| project TimeGenerated, Resource, OperationName, requestUri_s, CallerIPAddress, ResultSignature, httpStatusCode_d
QUERY
}
3. Threat Simulation & Detection Verification
Let's test the trap by simulating an external credential discovery attack.
Attack Simulation
Send an unauthenticated HTTP GET request targeting the honeypot URI:
curl -s -i "https://kv-honeypot-<SUFFIX>.vault.azure.net/secrets/db-prod-connection-string?api-version=7.4"curl -s -i "https://kv-honeypot-<SUFFIX>.vault.azure.net/secrets/db-prod-connection-string?api-version=7.4"Expected Output: An immediate HTTP/1.1 401 Unauthorized response.
Validating Telemetry in Sentinel
Within 5 minutes, Sentinel runs the scheduled analytics rule, flags the unauthorised access attempt, and fires an incident.
🎯 What I Accomplished in Stage 1
- IaC Infrastructure: Fully automated deployment of Log Analytics, Sentinel, and honeypot assets via Terraform.
- Deception Engineering: Placed realistic bait secrets configured for zero false-positive alerts.
- Detection as Code: Packaged custom KQL threat-hunting logic into native Sentinel Analytics Rules.
You can find the github code here.
🚀 What's Next?
In Stage 2: SOAR Automation & Response, I will build Azure Logic Apps to intercept high-severity Sentinel alerts and instantly send automated incident notifications to Slack/Discord. Stage 3: Serverless Threat Hunting Stage 4: CI/CD Detection Pipeline
Stay tuned!