Skip to content

[Feature]: Add Azure Terraform skeleton (mirror of infra/terraform/gcp/) #237

@Asinsayedali

Description

@Asinsayedali

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:

  1. The Deployment options table in the root README lists AWS and Helm
    as first-class, plus Render/Fly/Railway/Coolify — Azure is absent.
  2. 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

  1. 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)?

  2. 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)

  3. Default region — proposing eastus. Preference for
    westeurope instead?

  4. 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?

  5. 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

  • I have searched existing issues and this is not a duplicate
  • This feature aligns with the AiSOC roadmap or is a reasonable addition

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions