Skip to content

Azure Deployment Guide

Use the Azure Terraform foundation when SkillMeat needs managed Azure infrastructure or a disposable Azure-hosted development environment.

For compute, storage, network, and external-service requirements by deployment method, see Deployment System Requirements.

Plan / Decision Matrix

Mode Use When Infrastructure Shape
dev-container-apps You want a disposable low-cost Azure environment with the managed runtime shape. Azure Container Apps web/API, private PostgreSQL Flexible Server, Key Vault, Log Analytics, scale-to-zero app replicas.
staging You need a managed Azure pre-production environment. Container Apps web/API, private PostgreSQL Flexible Server, Key Vault, Log Analytics.
production You need the managed Azure production path. Container Apps web/API with higher replica bounds, private PostgreSQL Flexible Server with zone-redundant HA, Key Vault purge protection, longer log retention.

Layout

Terraform is under deploy/azure/terraform/:

deploy/azure/terraform/
├─ envs/
│  ├─ dev-container-apps/
│  ├─ staging/
│  └─ production/
└─ modules/
   └─ skillmeat_azure/

The root Makefile wraps common Terraform commands with TF_PROVIDER=azure.

Architecture

The managed Azure environments provision this shape for SkillMeat:

  • Azure Container Apps runs separate web and api apps from GHCR-published images.
  • Azure Database for PostgreSQL Flexible Server runs in a delegated private subnet.
  • Azure Key Vault stores the generated DATABASE_URL, optional registry credentials, and application secrets.
  • Log Analytics collects Container Apps logs.
  • A VNet connects the Container Apps environment and PostgreSQL.
Users -> Container Apps web
Users -> Container Apps API -> PostgreSQL Flexible Server private subnet
                           -> Key Vault
                           -> Log Analytics

Azure Container Apps produces separate public FQDNs for the web and API apps. Terraform outputs web_url, api_url, and api_health_url. A later provider module can add Azure Front Door or Application Gateway if a single public hostname with /api/* routing is required.

Image Configuration

Terraform consumes published GHCR image tags for the web and API containers. Publish images before planning or applying an environment update, then point the environment inputs at the intended tags. Prefer immutable version tags over latest so Container App revisions are explicit and reviewable.

Next.js inlines NEXT_PUBLIC_* values during pnpm build. Runtime Container App environment variables do not change client-side values already compiled into the web image. Build the web image with the correct public API URL, auth mode, and Clerk publishable key for the target environment before publishing the tag Terraform will deploy.

Local Commands

Set TF_PROVIDER=azure and TF_ENV to dev-container-apps, staging, or production:

make terraform-fmt TF_PROVIDER=azure
make terraform-validate TF_PROVIDER=azure TF_ENV=dev-container-apps
make terraform-plan TF_PROVIDER=azure TF_ENV=staging
make terraform-validate TF_PROVIDER=azure TF_ENV=production

Shortcut targets:

make terraform-validate-azure-dev-container-apps
make terraform-validate-azure-staging
make terraform-validate-azure-production
make terraform-plan-azure-dev-container-apps
make terraform-plan-azure-staging
make terraform-plan-azure-production

terraform-validate runs terraform init -backend=false before validation. terraform-plan uses the selected environment root and requires Azure credentials plus any configured remote backend access.

Usage Examples

Validate the disposable Azure development environment:

make terraform-validate-azure-dev-container-apps

Plan staging:

make terraform-plan-azure-staging

Use the generic target for any environment root:

make terraform-validate TF_PROVIDER=azure TF_ENV=staging
make terraform-plan TF_PROVIDER=azure TF_ENV=production

CI Validation

.github/workflows/terraform.yml runs when files under deploy/aws/**, deploy/azure/**, or the workflow itself change. It checks Terraform formatting, then validates each configured environment root with terraform init -backend=false. The workflow does not read cloud secrets and does not run terraform plan or terraform apply.

Release Checklist

  1. Build and publish web/API images to GHCR with environment-appropriate values.
  2. Update the selected Terraform environment inputs to reference the new image tags.
  3. Run make terraform-validate TF_PROVIDER=azure TF_ENV=<env>.
  4. Run make terraform-plan TF_PROVIDER=azure TF_ENV=<env> with Azure credentials.
  5. Review the plan before applying through the approved operator workflow.