# noel-mathews-org/flowforge-terraform architecture

> Architecture diagram of the GitHub repository noel-mathews-org/flowforge-terraform, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-30). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/noel-mathews-org/flowforge-terraform
- Repository: https://github.com/noel-mathews-org/flowforge-terraform

## Overview

1. This repository is an Azure infrastructure-as-code codebase, not an application runtime repo. Its core purpose is to provision and manage the FlowForge platform using Terraform, with GitHub Actions as the deployment control plane.

2. The Terraform structure is split into two layers:
   - `modules/` contains reusable building blocks for each Azure subsystem.
   - `env/` contains environment compositions (`dev`, `og-prod`, `prod`) that wire those modules together with environment-specific variables, provider config, and outputs.

3. The environment split is architecturally important:
   - `env/og-prod` is the bootstrap/persistent foundation, creating long-lived assets such as the Azure Container Registry and user-assigned managed identities.
   - `env/prod` is the destroy/recreate-friendly production stack that treats those identities and registry as external data sources, so the rest of the platform can be torn down and rebuilt without breaking identity continuity or image storage.
   - `env/dev` appears to be the lower-risk equivalent for non-prod testing.

4. The main network model is hub-and-spoke. `modules/hub_network` hosts the management plane, while `modules/spoke_network` hosts application-facing subnets. The spoke includes dedicated areas for AKS, Application Gateway, private endpoints, and database connectivity. Private DNS zones are part of this design so services resolve Azure private-link endpoints inside the VNet.

5. Security and traffic control are centralized in a few network boundaries:
   - `modules/firewall` is the forced egress point for AKS and other workloads, enforcing outbound filtering through user-defined routes.
   - `modules/vpn_gateway` provides point-to-site administrative access into the private network using Entra ID authentication.
   - `modules/app_gateway` is the public ingress layer, terminating TLS and forwarding traffic into AKS.
   - `modules/jumpbox` gives operators a private Windows administration host inside the hub network.

6. The core compute boundary is `modules/aks`. AKS is configured with OIDC issuer and Workload Identity, which is a major architectural choice: application pods authenticate to Azure using federated identities instead of secrets. The cluster appears to use separate system and user node pools, with the user pool carrying the FlowForge workloads.

7. The platform data layer is private-by-default. `modules/databases` provisions PostgreSQL Flexible Server and Redis, both accessed through private endpoints. `modules/storage` provides blob storage for application documents or reports, and `modules/key_vault` stores runtime secrets and connection values. `modules/ai_foundry` adds an Azure AI/OpenAI-backed service used by the analysis workload.

8. Identity and authorization are a first-class boundary in this repo. The README describes multiple user-assigned managed identities for distinct runtime actors:
   - GitHub Actions for pushing images to ACR
   - application pods for accessing Key Vault, storage, and database resources
   - an ARC runner identity for secret synchronization
   - an OpenTelemetry identity for publishing telemetry
   - an AI service identity for model invocation
   This separation is central to the architecture because it replaces static credentials with short-lived federated access.

9. GitHub Actions is the orchestration layer for infrastructure lifecycle:
   - `terraform-gitops.yml` runs plan/validate/security/cost checks and then waits for environment approval before apply.
   - `terraform-destroy.yml` is a manually dispatched destroy path with an additional text-confirmation safety gate.
   - `update-keyvault-secrets.yml` runs on a self-hosted runner inside AKS to sync GitHub secrets into Key Vault, then disables older secret versions.
   The workflows are tied to GitHub Environments, which act as policy and approval boundaries.

10. Remote Terraform state is externalized. `scripts/bootstrap_backend.ps1` creates the Azure Storage backend used for `.tfstate`, and grants the service principal access to that storage account/container. This means state management is part of the platform’s control plane, not stored locally.

11. There is a separate database bootstrap path in `db-permission/`. It exists because the application uses Entra ID passwordless auth to PostgreSQL, so the database must know about the managed identities. A PowerShell script fetches an AAD token, injects it into a Kubernetes job manifest, and runs a setup job that registers identities and grants database/schema/table privileges.

12. The main data flows are:
   - external users enter through Application Gateway into AKS
   - AKS workloads reach PostgreSQL, Redis, Storage, and Key Vault over private endpoints
   - outbound internet access from AKS is forced through Azure Firewall
   - operators enter through VPN Gateway or Jumpbox for private administration
   - GitHub Actions drives provisioning, destruction, and secret synchronization through OIDC and federated identities

13. From an architecture-diagram perspective, the important boundaries are:
   - GitHub / CI control plane
   - Azure subscription and Terraform state backend
   - hub network vs spoke application network
   - public ingress vs private service access
   - persistent bootstrap resources vs destroyable production stack
   - identity/auth boundaries between workloads, operators, and pipelines

14. The repository is therefore best understood as an enterprise Azure platform blueprint for a private, identity-driven application stack: Terraform defines the resources, GitHub Actions governs lifecycle, AKS runs the application, and Azure networking/private-link boundaries keep most traffic off the public internet.

Main entry points: [`env/prod`](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/env/prod) (Prod stack), [`modules/aks`](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/aks) (AKS cluster), [`modules/spoke_network`](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/spoke_network) (Spoke network), [`modules/hub_network`](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/hub_network) (Hub network)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_control_plane["GitHub control plane"]
  node_github_actions["GitHub Actions<br/>workflow control plane<br/>[workflows]"]
  node_terraform_gitops["GitOps flow<br/>workflow"]
  node_terraform_destroy["Destroy flow<br/>workflow"]
  node_sync_secrets["Secret sync<br/>workflow"]
end

subgraph group_terraform["Terraform layers"]
  node_env_dev["Dev stack<br/>terraform env"]
  node_env_og_prod["OG prod<br/>terraform env"]
  node_env_prod["Prod stack<br/>terraform env"]
end

subgraph group_platform["Azure platform"]
  node_hub_network{{"Hub network<br/>network module"}}
  node_spoke_network{{"Spoke network<br/>network module"}}
  node_firewall["Firewall<br/>egress control"]
  node_vpn_gateway["VPN gateway<br/>admin access"]
  node_app_gateway["App gateway<br/>public ingress"]
  node_jumpbox["Jumpbox<br/>admin host"]
  node_aks{{"AKS cluster<br/>compute platform"}}
  node_databases[("Databases<br/>data services")]
  node_storage[("Storage")]
  node_key_vault[("Key Vault<br/>secret store")]
  node_ai_foundry{{"AI Foundry<br/>ai service"}}
  node_monitoring(("Monitoring<br/>telemetry"))
end

subgraph group_bootstrap["Bootstrap paths"]
  node_backend_bootstrap["Backend bootstrap<br/>ps1 bootstrap"]
  node_db_permissions["DB setup<br/>ps1/sql bootstrap<br/>[run-setup.ps1]"]
end

node_github_actions -->|"runs"| node_terraform_gitops
node_github_actions -->|"runs"| node_terraform_destroy
node_github_actions -->|"runs"| node_sync_secrets
node_terraform_gitops -->|"plans/apply"| node_env_dev
node_terraform_gitops -->|"plans/apply"| node_env_og_prod
node_terraform_gitops -->|"plans/apply"| node_env_prod
node_terraform_destroy -->|"destroys"| node_env_prod
node_backend_bootstrap -.->|"state backend"| node_env_dev
node_backend_bootstrap -.->|"state backend"| node_env_og_prod
node_backend_bootstrap -.->|"state backend"| node_env_prod
node_env_dev -->|"uses"| node_hub_network
node_env_dev -->|"uses"| node_spoke_network
node_env_dev -->|"uses"| node_aks
node_env_dev -->|"uses"| node_databases
node_env_prod -->|"uses"| node_hub_network
node_env_prod -->|"uses"| node_spoke_network
node_env_prod -->|"uses"| node_aks
node_env_prod -->|"uses"| node_app_gateway
node_env_prod -->|"uses"| node_databases
node_env_prod -->|"uses"| node_storage
node_env_prod -->|"uses"| node_key_vault
node_env_prod -->|"uses"| node_ai_foundry
node_env_og_prod -->|"anchors"| node_storage
node_env_og_prod -->|"anchors"| node_key_vault
node_hub_network -->|"hosts"| node_vpn_gateway
node_hub_network -->|"hosts"| node_jumpbox
node_hub_network -->|"hosts"| node_firewall
node_spoke_network -->|"subnets"| node_aks
node_spoke_network -->|"subnets"| node_app_gateway
node_spoke_network -->|"private endpoints"| node_databases
node_spoke_network -->|"private endpoints"| node_storage
node_spoke_network -->|"private endpoints"| node_key_vault
node_spoke_network -->|"private endpoints"| node_ai_foundry
node_aks -->|"egress via"| node_firewall
node_app_gateway -->|"forwards to"| node_aks
node_vpn_gateway -->|"accesses"| node_hub_network
node_jumpbox -->|"admin access"| node_spoke_network
node_aks -->|"reads/writes"| node_databases
node_aks -->|"reads/writes"| node_storage
node_aks -->|"secrets"| node_key_vault
node_aks -->|"invokes"| node_ai_foundry
node_sync_secrets -->|"updates"| node_key_vault
node_db_permissions -->|"grants access"| node_databases
node_monitoring -->|"observes"| node_aks
node_monitoring -.->|"observes"| node_hub_network

click node_github_actions "https://github.com/noel-mathews-org/flowforge-terraform/blob/main/.github/workflows"
click node_terraform_gitops "https://github.com/noel-mathews-org/flowforge-terraform/blob/main/.github/workflows/terraform-gitops.yml"
click node_terraform_destroy "https://github.com/noel-mathews-org/flowforge-terraform/blob/main/.github/workflows/terraform-destroy.yml"
click node_sync_secrets "https://github.com/noel-mathews-org/flowforge-terraform/blob/main/.github/workflows/update-keyvault-secrets.yml"
click node_backend_bootstrap "https://github.com/noel-mathews-org/flowforge-terraform/blob/main/scripts/bootstrap_backend.ps1"
click node_db_permissions "https://github.com/noel-mathews-org/flowforge-terraform/blob/main/db-permission/run-setup.ps1"
click node_env_dev "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/env/dev"
click node_env_og_prod "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/env/og-prod"
click node_env_prod "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/env/prod"
click node_hub_network "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/hub_network"
click node_spoke_network "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/spoke_network"
click node_firewall "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/firewall"
click node_vpn_gateway "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/vpn_gateway"
click node_app_gateway "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/app_gateway"
click node_jumpbox "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/jumpbox"
click node_aks "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/aks"
click node_databases "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/databases"
click node_storage "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/storage"
click node_key_vault "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/key_vault"
click node_ai_foundry "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/ai_foundry"
click node_monitoring "https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/monitoring"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_github_actions,node_terraform_gitops,node_terraform_destroy,node_sync_secrets toneBlue
class node_env_dev,node_env_og_prod,node_env_prod toneAmber
class node_hub_network,node_spoke_network,node_firewall,node_vpn_gateway,node_app_gateway,node_jumpbox,node_aks,node_databases,node_storage,node_key_vault,node_ai_foundry,node_monitoring toneMint
class node_backend_bootstrap,node_db_permissions toneRose
```

## Components

### GitHub control plane

CI/CD and manual lifecycle orchestration.

- [GitHub Actions](https://github.com/noel-mathews-org/flowforge-terraform/blob/main/.github/workflows): workflow control plane · Runs plan, apply, destroy, and secret sync workflows. · `.github/workflows`
- [GitOps flow](https://github.com/noel-mathews-org/flowforge-terraform/blob/main/.github/workflows/terraform-gitops.yml): workflow · Plan, validate, security, cost checks, then approved apply. · `.github/workflows/terraform-gitops.yml`
- [Destroy flow](https://github.com/noel-mathews-org/flowforge-terraform/blob/main/.github/workflows/terraform-destroy.yml): workflow · Manual destruction path with safety confirmation. · `.github/workflows/terraform-destroy.yml`
- [Secret sync](https://github.com/noel-mathews-org/flowforge-terraform/blob/main/.github/workflows/update-keyvault-secrets.yml): workflow · Syncs GitHub secrets into Key Vault from an AKS runner. · `.github/workflows/update-keyvault-secrets.yml`

### Terraform layers

Environment compositions and reusable modules.

- [Dev stack](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/env/dev): terraform env · Lower-risk non-production environment composition. · `env/dev`
- [OG prod](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/env/og-prod): terraform env · Persistent bootstrap foundation for long-lived shared assets. · `env/og-prod`
- [Prod stack](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/env/prod): terraform env · Destroy/recreate-friendly production composition. · `env/prod`

### Azure platform

Core network, compute, data, and access subsystems.

- [Hub network](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/hub_network): network module · Central management network and shared private access boundary. · `modules/hub_network`
- [Spoke network](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/spoke_network): network module · Application-facing subnets for AKS, private endpoints, and services. · `modules/spoke_network`
- [Firewall](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/firewall): egress control · Forced outbound filtering and user-defined routing for workloads. · `modules/firewall`
- [VPN gateway](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/vpn_gateway): admin access · Point-to-site private access with Entra ID authentication. · `modules/vpn_gateway`
- [App gateway](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/app_gateway): public ingress · Public TLS ingress forwarding traffic into AKS. · `modules/app_gateway`
- [Jumpbox](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/jumpbox): admin host · Private Windows administration host in the hub network. · `modules/jumpbox`
- [AKS cluster](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/aks): compute platform · Private Kubernetes cluster using OIDC and Workload Identity. · `modules/aks`
- [Databases](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/databases): data services · PostgreSQL Flexible Server and Redis with private access. · `modules/databases`
- [Storage](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/storage): blob storage · Object storage for application documents or reports. · `modules/storage`
- [Key Vault](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/key_vault): secret store · Secrets and runtime connection values. · `modules/key_vault`
- [AI Foundry](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/ai_foundry): ai service · Azure AI/OpenAI-backed service used by analysis workloads. · `modules/ai_foundry`
- [Monitoring](https://github.com/noel-mathews-org/flowforge-terraform/tree/main/modules/monitoring): telemetry · Platform telemetry and observability boundary. · `modules/monitoring`

### Bootstrap paths

State backend and database privilege setup.

- [Backend bootstrap](https://github.com/noel-mathews-org/flowforge-terraform/blob/main/scripts/bootstrap_backend.ps1): ps1 bootstrap · Creates Terraform remote state storage and grants access. · `scripts/bootstrap_backend.ps1`
- [DB setup](https://github.com/noel-mathews-org/flowforge-terraform/blob/main/db-permission/run-setup.ps1): ps1/sql bootstrap · Registers managed identities and grants PostgreSQL permissions. · `db-permission/run-setup.ps1`

## Connections

- GitHub Actions → GitOps flow: runs · Primary infrastructure lifecycle pipeline.
- GitHub Actions → Destroy flow: runs · Manual destroy pipeline.
- GitHub Actions → Secret sync: runs · Secret synchronization workflow.
- GitOps flow → Dev stack: plans/apply · Targets the non-production environment.
- GitOps flow → OG prod: plans/apply · Targets the persistent foundation.
- GitOps flow → Prod stack: plans/apply · Targets the production stack.
- Destroy flow → Prod stack: destroys · Destroy/recreate path for production resources.
- Backend bootstrap → Dev stack: state backend · Provides remote Terraform state storage.
- Backend bootstrap → OG prod: state backend · Provides remote Terraform state storage.
- Backend bootstrap → Prod stack: state backend · Provides remote Terraform state storage.
- Dev stack → Hub network: uses · Wires environment into shared networking.
- Dev stack → Spoke network: uses · Defines application network placement.
- Dev stack → AKS cluster: uses · Deploys the cluster and workloads.
- Dev stack → Databases: uses · Deploys private data services.
- Prod stack → Hub network: uses · Production network composition.
- Prod stack → Spoke network: uses · Production application network composition.
- Prod stack → AKS cluster: uses · Production compute boundary.
- Prod stack → App gateway: uses · Public ingress for production traffic.
- Prod stack → Databases: uses · Production private data services.
- Prod stack → Storage: uses · Production object storage.
- Prod stack → Key Vault: uses · Production secret store.
- Prod stack → AI Foundry: uses · Production AI service integration.
- OG prod → Storage: anchors · Holds long-lived registry/storage-like foundation assets.
- OG prod → Key Vault: anchors · Holds persistent identity and secret boundary assets.
- Hub network → VPN gateway: hosts · Private operator access entry point.
- Hub network → Jumpbox: hosts · Private administration host.
- Hub network → Firewall: hosts · Central egress enforcement point.
- Spoke network → AKS cluster: subnets · Application and cluster placement.
- Spoke network → App gateway: subnets · Ingress and routing boundary.
- Spoke network → Databases: private endpoints · Private service access boundary.
- Spoke network → Storage: private endpoints · Private storage access boundary.
- Spoke network → Key Vault: private endpoints · Private secret access boundary.
- Spoke network → AI Foundry: private endpoints · Private AI service access boundary.
- AKS cluster → Firewall: egress via · Forces outbound traffic through filtered egress.
- App gateway → AKS cluster: forwards to · TLS ingress into Kubernetes workloads.
- VPN gateway → Hub network: accesses · Administrative private network entry.
- Jumpbox → Spoke network: admin access · Private operator access into the platform network.
- AKS cluster → Databases: reads/writes · Workloads consume PostgreSQL and Redis privately.
- AKS cluster → Storage: reads/writes · Workloads use blob storage.
- AKS cluster → Key Vault: secrets · Pods fetch runtime secrets and connection values.
- AKS cluster → AI Foundry: invokes · Analysis workloads call the AI service.
- Secret sync → Key Vault: updates · Pushes secret material into Key Vault.
- DB setup → Databases: grants access · Registers identities and applies PostgreSQL permissions.
- Monitoring → AKS cluster: observes · Collects platform telemetry from workloads.
- Monitoring → Hub network: observes · Captures network and platform signals.
