Skip to main content

GitHub Actions

GitHub Actions runs the workflows that are the only way a change reaches Azure: every plan, apply, image build and promotion is a workflow run triggered by a pull request, a merge, a release or a schedule. Every Azure repository except the GitOps repository, which ArgoCD reads, carries its own workflows.

What it does​

A workflow in .github/workflows/ runs jobs on a runner, either GitHub-hosted or self-hosted, selected by runs-on. Environments hold per-stage variables and can require reviewers before a job starts. With permissions: id-token: write a job obtains an OIDC token that a cloud trusts in place of a stored secret. Concurrency groups decide whether a new run cancels or queues behind the one in flight.

How BuiltForProd uses it​

RepositoryWorkflows
acme-azure-platform-baselineplan.yml (pull requests, optional Infracost), apply.yml (merge, prod Environment), drift-detection.yml, runner-image.yml
acme-azure-blueprint-webapp-infra, -etl-infraplan.yml and apply.yml per stage in a dev, staging, prod matrix (fail-fast: false, Environment per stage), drift-detection.yml
acme-azure-blueprint-webapp-codeci.yml, cd-integration.yml, cd-release.yml, promote-prod.yml, cd-frontend.yml, and the gitops-pr action
acme-azure-blueprint-etl-codeci.yml, cd-integration.yml, cd-release.yml, and the deploy-trigger action
acme-azure-blueprint-secretsplan.yml (dry-run sync per stage), sync.yml (path-aware sync, manual prune)

Sign-in. Every job that reaches Azure logs in as its repository's managed identity with a federated credential for one exact subject: pull_request, ref:refs/heads/main or environment:<stage>. No client secret exists; see GitHub OIDC. OpenTofu's provider and backend use the same token (ARM_USE_OIDC).

Runners. runs-on reads the repository variable RUNNER_LABELS and falls back to ubuntu-latest. The state storage, the vaults and the AKS API server are private, so blueprint plans and applies, drift checks, the secrets sync and the frontend and trigger deploys run on the Container Apps runners inside the landing zone. Lint and scan jobs and image builds stay on GitHub-hosted runners, because they need no Azure access or reach only the registry's public endpoint.

Gates. The Baseline applies in one job in the prod Environment with required reviewers. The blueprint infrastructure applies each stage in its own Environment, and prod waits for its reviewers. Web app images reach prod only through promote-prod.yml, behind the prod Environment, and a GitOps pull request a person merges; ArgoCD prod then syncs by hand.

Drift. The Baseline plans with -detailed-exitcode at 01:00 UTC: on Monday all 14 subscription folders, Tuesday to Friday core-network, core-identity, core-security, plat-dev, plat-staging and plat-prod. The blueprint infrastructure repositories plan dev, staging and prod daily at 05:00 UTC. In every infrastructure repository, drift or a failed plan opens or updates an issue labeled drift.

Hygiene. Applies and deploys queue (cancel-in-progress: false); a new push cancels an outdated plan. Third-party actions are pinned by commit SHA. Terragrunt and tflint are downloaded at pinned versions and checked against their release SHA-256. Plans and applies upload Terragrunt's run report as an artifact, and the plan is posted on the pull request.

Terms you will see​

TermMeaning
EnvironmentA GitHub stage with its variables and, for prod, required reviewers.
Federated subjectThe exact workflow context an identity trusts, such as environment:prod.
RUNNER_LABELSThe repository variable that sends jobs to the Container Apps runners.
Run reportTerragrunt's JSON summary of every unit in a run, kept as an artifact.
Deploy pull requestThe pull request a code workflow opens in the GitOps repository.

Where to read more​