ITSolutions Web Platform
ARCHITECTURE

How this environment is built

One workload (webplat), deployed by Bicep and Kustomize, entirely through GitHub Actions using OIDC — no long-lived Azure credentials anywhere in the pipeline.

GitHub Actions build, push, deploy OIDC federated token Microsoft Entra ID no stored secrets You HTTPS Application Gateway (WAF_v2) TLS termination · Let's Encrypt cert · OWASP managed ruleset public IP, dedicated subnet PRIVATE AKS CLUSTER — no public API server System node pool AGIC — reconciles this Ingress cert-manager — solves the ACME HTTP-01 challenge, renews the cert Key Vault Secrets Provider (prod only) Azure Policy add-on add-ons only — no app workloads User node pool (autoscaling) namespace: demo-web this page — served by nginx runs non-root, read-only rootfs HPA: 2-5 replicas on CPU 70% default-deny NetworkPolicy Azure Container Registry — kubelet identity pull Let's Encrypt — ACME HTTP-01

01Network

A dedicated VNet with three subnets: snet-aks for nodes and pods (no direct inbound from the Internet), snet-appgw for the Application Gateway (443/80 from the Internet, plus the port range Azure's own health probes need), and snet-pe for private endpoints into ACR and Key Vault. Nothing reaches the cluster except through the Gateway.

02Ingress & TLS

The Application Gateway Ingress Controller (AGIC) watches this app's Kubernetes Ingress object and reconfigures the Application Gateway automatically — no manual listener or routing-rule changes. TLS terminates at the Gateway using a certificate issued by Let's Encrypt via cert-manager, which proves domain ownership with an automated ACME HTTP-01 challenge and renews the certificate before it expires — the same mechanism browsers trust for any public HTTPS site.

03CI/CD

Every push builds and pushes a container image to ACR, tagged with the commit SHA, then applies the Kubernetes manifests to the cluster via az aks command invoke — the only way a GitHub-hosted runner (no VNet line-of-sight) can reach a cluster with no public API server, without a VPN, self-hosted runner, or Bastion host.