Development Documentation
View as:

Environment Strategy

The platform uses a branch-per-environment model with selective cherry-pick promotion. Each environment (DEV, UAT, PROD) maps to a dedicated git branch, and deployments trigger automatically when commits land on that branch.

Environment Flow

graph LR
    F["feature/*<br/>Feature env"] -->|PR + squash merge| M["main<br/>DEV auto-deploy"]
    M -->|cherry-pick PR| U["release/uat<br/>UAT auto-deploy"]
    U -->|cherry-pick PR| P["release/prod<br/>PROD manual approval"]

This is not a traditional GitFlow model. Changes are promoted individually via cherry-pick, not merged wholesale. This gives fine-grained control over what reaches each environment -- see Promotion Workflow for details.

Branch-to-Environment Mapping

BranchEnvironmentDeploy ModeApproval
feature/*Feature (local/CI)DuckDB smoke + Fabric slim CINone
mainDEVAuto-deploy on pushNone
release/uatUATAuto-deploy on push1 reviewer PR
release/prodPRODDeploy after approval2 reviewer PR + production environment gate

What Triggers on Each Branch

feature/* -- Validation Only

No deployment happens. Two CI pipelines validate the code:

  • dbt-ci-smoke runs on every push to any branch. It compiles the dbt project against DuckDB to catch syntax errors and reference issues in seconds.
  • dbt-ci-slim runs as a PR gate when a PR targets main. It does a state-aware slim build against the Fabric CI environment, running only modified models and their downstream dependents.

main -- DEV Auto-Deploy

Merging a PR to main triggers deployment pipelines based on what files changed:

Path ChangePipeline Triggered
dbt/**dbt-dev-build -- full dbt build to DEV warehouse
terraform/**infra-deploy -- Terraform apply to DEV
security/**security-deploy -- SQL grants and RLS to DEV warehouse
functions/**functions-deploy -- Azure Functions to DEV

No manual steps. No approval gates. DEV is the fast-feedback environment.

release/uat -- UAT Auto-Deploy

Commits cherry-picked from main trigger the same pipeline set, but targeting UAT resources:

Path ChangePipeline Triggered
dbt/**dbt-uat-deploy -- dbt build to UAT warehouse
terraform/**infra-deploy -- Terraform apply to UAT
security/**security-deploy -- SQL grants to UAT warehouse
functions/**functions-deploy -- Azure Functions to UAT
semantic/**, reports/**fabric-deploy -- semantic models + reports to UAT

Cherry-pick PRs require 1 reviewer (a Lead from FP GER Fabric Platform Team).

release/prod -- PROD with Approval Gate

Same pipeline set as UAT, but every pipeline that touches PROD requires manual approval via the production Azure DevOps environment. The pipeline pauses at the deployment job, an approver reviews the changes, and clicks Approve or Reject.

Manifest Isolation

Each environment has its own manifest.json path in Azure Blob Storage (gerisdbtartifacts). This prevents cross-environment contamination where a DEV build's manifest could cause UAT's slim build to skip models that were actually modified.

EnvironmentBlob PathUsed By
CI (nightly)dbt-artifacts/ci/manifest.jsondbt-nightly-full, dbt-ci-slim
DEVdbt-artifacts/dev/manifest.jsondbt-dev-build
UATdbt-artifacts/uat/manifest.jsondbt-uat-deploy
PRODdbt-artifacts/prod/manifest.jsondbt-prod-deploy

The slim CI pipeline always downloads from ci/ (nightly) -- never from DEV, UAT, or PROD paths.

CI Bronze Source

The CI workspace does not own its Bronze data. scripts/sync_ci_shortcuts.py runs at the start of every nightly and ensures the CI Lakehouse_Bronze contains OneLake schema shortcuts into a configured source workspace. The source, declared in deployment/ci.yml as ci_workspaces.source_workspace_id, is DEV-Bronze — it already carries the normalised schema layout (ax, sharepoint, vesper, …) that the dbt sources expect, produced by the 2.2 Process-to-Gold notebook. The raw PROD Datalake uses different schema names (AX2012, sharepoint_ad, no vesper) and cannot be shortcutted directly.

The declarative list of schemas lives in pipelines/ci-bronze-shortcuts.yml. To add a schema, append it to that file. To repoint at a different source workspace, change source_workspace_id and delete any stale shortcuts in the CI Lakehouse first — the sync script only creates missing shortcuts, it doesn't reconcile targets.

After creating shortcuts, the script POSTs /sqlEndpoints/{id}/refreshMetadata and waits for the SQL analytics endpoint to rediscover tables. Without the explicit refresh, Lakehouse_Bronze.schema.table queries from the warehouse can return Invalid object name for 10+ minutes after a shortcut is created.

Configuration Files

All per-environment values live in git-tracked config files. No Azure DevOps variable groups are used.

EnvironmentConfig FileBranch
CIdeployment/ci.yml(hardcoded to CI, used by nightly + slim)
DEVdeployment/dev.ymlmain
UATdeployment/uat.ymlrelease/uat
PRODdeployment/prod.ymlrelease/prod

Each config file contains workspace IDs, warehouse connection strings, function app names, storage paths, Terraform state keys, identity object IDs, and access control configuration. See deployment/dev.yml for the full structure.

Pipelines detect the environment from Build.SourceBranch via templates/detect-environment.yml and load config via templates/load-deployment-config.yml.

Terraform Parameter Files

Terraform uses separate tfvars per environment:

EnvironmentTerraform Config
DEVterraform/environments/dev/terraform.tfvars
UATterraform/environments/uat/terraform.tfvars
PRODterraform/environments/prod/terraform.tfvars

These contain workspace names, capacity IDs, role assignments, and git connection settings.

Feature Branch Auto-Cleanup

Feature branches (feature/*) are intended to be short-lived. After a PR is merged to main, the source branch is deleted automatically by Azure DevOps branch policy. Stale feature branches without recent activity can be cleaned up by the nightly maintenance pipeline.

Related Pages