Problem / motivation
AiSOC ships first-class AWS Terraform (infra/terraform/) and a GCP "skeleton" (infra/terraform/gcp/, explicitly labeled as such in its README). Azure is the remaining big-three cloud gap.
The gap is visible in two places:
- The Deployment options table in the root README lists AWS and Helm
as first-class, plus Render/Fly/Railway/Coolify — Azure is absent.
- AiSOC already has first-party Azure connectors (Entra, Defender,
Activity, M365 audit) for ingesting Azure security data, so there's
a real population of Azure-shop users who can ingest from Azure but
can't deploy AiSOC onto Azure without writing the Terraform
themselves.
For self-hosters whose corporate cloud is Azure, will face a lack of a documented Azure deploy path, which is a deciding factor.
Proposed solution
Proposed solution
Add infra/terraform/azure/ as a skeleton that mirrors the GCP
pattern (same scope, same file layout, same "documented limitations"
discipline), plus matching docs.
Proposed scope (skeleton — matches GCP)
- Compute: Azure Container Apps (ACA) for the 3 customer-visible
services: api, web, ingest. Scale-to-zero, closest analog to
Cloud Run.
- Database: Azure Database for PostgreSQL Flexible Server, private
IP via VNet integration.
- Cache: Azure Cache for Redis (Basic tier default).
- Secrets: Azure Key Vault (DB password, SECRET_KEY,
AISOC_CREDENTIAL_KEY, optional OPENAI_API_KEY).
- Registry: Azure Container Registry (ACR).
- Workload identity: Managed Identity per service, with role
assignments to Key Vault + ACR.
- Networking: VNet + subnet for ACA, private endpoints for
Postgres + Redis.
- State backend: Azure Storage Account + blob lease locking,
documented but not auto-provisioned (matches AWS/GCP pattern).
Deferred to a v2 follow-up (documented as Limitations)
Same shape as the GCP README's "Limitations" section:
- Long-running services (
agents, realtime, connectors,
alert-fusion, threatintel, fusion) — recommended path is AKS
Automatic sharing the VNet/DB provisioned here.
- ClickHouse / OpenSearch / Neo4j / Qdrant — out of scope for the
skeleton.
- Kafka — deferred (Event Hubs Kafka-protocol surface is the obvious
candidate; happy to scope separately).
- HTTPS load balancer / custom domain (Application Gateway + WAF).
- CMEK / customer-managed key envelope encryption.
File layout (mirrors infra/terraform/gcp/)
infra/terraform/azure/
├── README.md
├── versions.tf
├── variables.tf
├── main.tf # resource group, VNet, APIs, ACR
├── database.tf # Postgres Flexible Server + db + user
├── redis.tf
├── secrets.tf # Key Vault entries
├── iam.tf # Managed Identities + role assignments
├── container_apps.tf # api / web / ingest
├── outputs.tf
└── terraform.tfvars.example
Docs (shipped in the same PR)
infra/terraform/azure/README.md — same shape as the GCP one
(Layout, Prerequisites, Quick start, State backend, Container
images, Costs, Limitations, Tear-down).
apps/docs/docs/deployment/azure.md — public-facing deployment
guide, registered in apps/docs/sidebars.ts.
- Update
infra/terraform/README.md and the root README's
"Deployment options" table so Azure shows up alongside AWS/GCP.
CI
Propose adding a single GitHub Actions job that runs
terraform fmt -check -recursive + terraform validate against all
three (AWS, GCP, Azure) Terraform directories. The existing AWS/GCP
modules currently have neither, so this is a win that benefits
all three.
A deploy-azure.yml workflow mirroring deploy-api.yml (with OIDC
federation, no long-lived secrets) is a sensible follow-up — happy to
include it in the same PR if preferred, or split.
Questions before I start coding
-
ACA vs AKS Automatic for the skeleton? I'm proposing ACA to
mirror the GCP Cloud Run choice. Any reason to prefer AKS
Automatic ? (e.g. to mirror the AWS EKS pattern)?
-
Kafka — defer entirely (matches GCP skeleton) or include Event
Hubs with the Kafka protocol surface? (My suggestion is to do it as a seperate PR)
-
Default region — proposing eastus. Preference for
westeurope instead?
-
SKU defaults — proposing startup-credit-friendly tier/ Azure free credits
(Burstable B1ms Postgres, Basic C0 Redis, smallest ACA SKU),
with a documented production-tier override block. Matches GCP
pattern. What do you think?
-
deploy-azure.yml workflow — same PR or follow-up (prefered)?
Once these are nailed down I can start a draft PR.
Background / scoping note
I'm a backend dev with some Terraform experience, but new to AiSOC.
I've read CONTRIBUTING.md, the AWS + GCP Terraform READMEs, the
deployment docs, and the workflows directory. Eval harness doesn't
apply to this change (no agent/orchestrator/prompts/RAG/detection
touched).
Alternatives considered
-
Bicep instead of Terraform. Bicep is more idiomatic in
Microsoft-shop teams, but the project standard is Terraform
(both AWS and GCP) and dual-tooling adds maintenance cost. Sticking
with Terraform for consistency. Open to discussion.
-
Skip the skeleton, write the full module. Higher value but much
bigger surface area for first review. Mirroring the GCP skeleton
pattern keeps the diff reviewable and lets the heavy storage tier
(ClickHouse / OpenSearch / Neo4j / Qdrant) land as a follow-up once
the shape is agreed.
-
Use a community Azure module. Considered, but pinning a third-
party module for production-relevant infra adds an upstream-trust
axis the AWS/GCP modules don't have. Hand-rolled HCL keeps the
trust boundary inside the repo.
Component area
Infra / DevOps
Checklist
Problem / motivation
AiSOC ships first-class AWS Terraform (
infra/terraform/) and a GCP "skeleton" (infra/terraform/gcp/, explicitly labeled as such in its README). Azure is the remaining big-three cloud gap.The gap is visible in two places:
as first-class, plus Render/Fly/Railway/Coolify — Azure is absent.
Activity, M365 audit) for ingesting Azure security data, so there's
a real population of Azure-shop users who can ingest from Azure but
can't deploy AiSOC onto Azure without writing the Terraform
themselves.
For self-hosters whose corporate cloud is Azure, will face a lack of a documented Azure deploy path, which is a deciding factor.
Proposed solution
Proposed solution
Add
infra/terraform/azure/as a skeleton that mirrors the GCPpattern (same scope, same file layout, same "documented limitations"
discipline), plus matching docs.
Proposed scope (skeleton — matches GCP)
services:
api,web,ingest. Scale-to-zero, closest analog toCloud Run.
IP via VNet integration.
AISOC_CREDENTIAL_KEY, optional OPENAI_API_KEY).
assignments to Key Vault + ACR.
Postgres + Redis.
documented but not auto-provisioned (matches AWS/GCP pattern).
Deferred to a v2 follow-up (documented as Limitations)
Same shape as the GCP README's "Limitations" section:
agents,realtime,connectors,alert-fusion,threatintel,fusion) — recommended path is AKSAutomatic sharing the VNet/DB provisioned here.
skeleton.
candidate; happy to scope separately).
File layout (mirrors infra/terraform/gcp/)
infra/terraform/azure/
├── README.md
├── versions.tf
├── variables.tf
├── main.tf # resource group, VNet, APIs, ACR
├── database.tf # Postgres Flexible Server + db + user
├── redis.tf
├── secrets.tf # Key Vault entries
├── iam.tf # Managed Identities + role assignments
├── container_apps.tf # api / web / ingest
├── outputs.tf
└── terraform.tfvars.example
Docs (shipped in the same PR)
infra/terraform/azure/README.md— same shape as the GCP one(Layout, Prerequisites, Quick start, State backend, Container
images, Costs, Limitations, Tear-down).
apps/docs/docs/deployment/azure.md— public-facing deploymentguide, registered in
apps/docs/sidebars.ts.infra/terraform/README.mdand the root README's"Deployment options" table so Azure shows up alongside AWS/GCP.
CI
Propose adding a single GitHub Actions job that runs
terraform fmt -check -recursive+terraform validateagainst allthree (AWS, GCP, Azure) Terraform directories. The existing AWS/GCP
modules currently have neither, so this is a win that benefits
all three.
A
deploy-azure.ymlworkflow mirroringdeploy-api.yml(with OIDCfederation, no long-lived secrets) is a sensible follow-up — happy to
include it in the same PR if preferred, or split.
Questions before I start coding
ACA vs AKS Automatic for the skeleton? I'm proposing ACA to
mirror the GCP Cloud Run choice. Any reason to prefer AKS
Automatic ? (e.g. to mirror the AWS EKS pattern)?
Kafka — defer entirely (matches GCP skeleton) or include Event
Hubs with the Kafka protocol surface? (My suggestion is to do it as a seperate PR)
Default region — proposing
eastus. Preference forwesteuropeinstead?SKU defaults — proposing startup-credit-friendly tier/ Azure free credits
(
Burstable B1msPostgres,Basic C0Redis, smallest ACA SKU),with a documented production-tier override block. Matches GCP
pattern. What do you think?
deploy-azure.ymlworkflow — same PR or follow-up (prefered)?Once these are nailed down I can start a draft PR.
Background / scoping note
I'm a backend dev with some Terraform experience, but new to AiSOC.
I've read CONTRIBUTING.md, the AWS + GCP Terraform READMEs, the
deployment docs, and the workflows directory. Eval harness doesn't
apply to this change (no agent/orchestrator/prompts/RAG/detection
touched).
Alternatives considered
Bicep instead of Terraform. Bicep is more idiomatic in
Microsoft-shop teams, but the project standard is Terraform
(both AWS and GCP) and dual-tooling adds maintenance cost. Sticking
with Terraform for consistency. Open to discussion.
Skip the skeleton, write the full module. Higher value but much
bigger surface area for first review. Mirroring the GCP skeleton
pattern keeps the diff reviewable and lets the heavy storage tier
(ClickHouse / OpenSearch / Neo4j / Qdrant) land as a follow-up once
the shape is agreed.
Use a community Azure module. Considered, but pinning a third-
party module for production-relevant infra adds an upstream-trust
axis the AWS/GCP modules don't have. Hand-rolled HCL keeps the
trust boundary inside the repo.
Component area
Infra / DevOps
Checklist