Skip to content
Deze documentatie wordt actief uitgebreid — kom regelmatig terug.

CI/CD Authentication — GitHub Actions to Azure (OIDC)

How the GitHub Actions pipelines authenticate to Azure to run tofu apply against the CNCL environment, using OIDC (workload identity federation) so no client secrets are stored in GitHub. Complements ASR Deployment Procedures (Infrastructure as Code) and the Deployment View.

Value
TenantTopsectorLogistiek.nl — 5024789e-bb64-49c4-bb41-5983c2b0ceef
Subscription“Azure subscription 1” — 66ff09d0-4495-4a1d-8f5a-5b577c96b76c
Resource groupCNCL-DEV
LocationWest Europe (westeurope)

These values are also kept in .env (gitignored) for local tofu runs and map to the env/dev.tfvars var-file used by the root module in infrastructure/tofu.

The azurerm provider authenticates via OIDC: GitHub Actions requests a short-lived ID token, Entra ID trusts it through a federated credential on a dedicated app registration, and grants the app’s RBAC roles. No secret to store or rotate.

The Azure environment is managed by the platform party (tenant / Entra ID governance) and the delivery party delivers the application. The only hard dependency on the platform party is an Entra Application Developer role grant: guest accounts cannot create directory objects (app registrations) by default. With that role, the DIL side creates the app registration and handles the RBAC and state setup itself, because the solution architect already holds Contributor + User Access Administrator on CNCL-DEV.

Azure and deployment work runs under DIL accounts (guest accounts in the TopsectorLogistiek tenant, home domain datainlogistics.nl). GitHub work uses the delivery party’s own GitHub accounts. The OIDC trust binds the repository to the service principal, so it is independent of any personal identity.

Guest accounts cannot create app registrations by default, so the platform party:

  1. Grants the Entra Application Developer role to the DIL accounts so the app registration + federated credentials can be created in-house. (Requested.) (The specific DIL accounts are listed in the request to the platform party, not here.)
  2. Assigns Contributor on CNCL-DEV to the delivery party’s developers’ DIL accounts. (Not yet assigned.)

DIL (architect — has Contributor + UAA on CNCL-DEV)

Section titled “DIL (architect — has Contributor + UAA on CNCL-DEV)”

Once Application Developer is granted:

  1. Creates the app registration / service principal (e.g. gh-cncl-bdi-deploy) → provides the Client ID used as ARM_CLIENT_ID.

  2. Adds the federated credentials. Issuer is always https://token.actions.githubusercontent.com. One credential per scenario:

    ScenarioSubject
    Push to mainrepo:Basic-Data-Infrastructure/CNCL-BDI:ref:refs/heads/main
    Environment devrepo:Basic-Data-Infrastructure/CNCL-BDI:environment:dev
    Pull requests (plan only)repo:Basic-Data-Infrastructure/CNCL-BDI:pull_request

    Repo: https://github.com/Basic-Data-Infrastructure/CNCL-BDI (public)

  3. Assigns the SP Contributor on CNCL-DEV (UAA permits the role assignment).

  4. Creates the OpenTofu remote-state storage account + container and grants the SP Storage Blob Data Contributor.

  • Adds infrastructure/tofu and .github/workflows to the repo.
  • Sets the GitHub repository variables (below).
  • Provisions the app’s Azure services in CNCL-DEV via OpenTofu and runs the pipeline (tofu apply).

Role assignments: creating resources needs Contributor; assigning roles (e.g. managed identity → Key Vault / storage) needs UAA. If the OpenTofu assigns roles itself, coordinate with the DIL architect (who has UAA) rather than widening the pipeline identity’s permissions.

GitHub configuration (no secrets with OIDC)

Section titled “GitHub configuration (no secrets with OIDC)”

Repository variables (Settings → Secrets and variables → Actions → Variables):

VariableValue
ARM_CLIENT_IDClient ID of the app registration
ARM_TENANT_ID5024789e-bb64-49c4-bb41-5983c2b0ceef
ARM_SUBSCRIPTION_ID66ff09d0-4495-4a1d-8f5a-5b577c96b76c

Workflow requirements:

permissions:
id-token: write # request the OIDC token
contents: read
env:
ARM_USE_OIDC: "true"
ARM_CLIENT_ID: ${{ vars.ARM_CLIENT_ID }}
ARM_TENANT_ID: ${{ vars.ARM_TENANT_ID }}
ARM_SUBSCRIPTION_ID: ${{ vars.ARM_SUBSCRIPTION_ID }}

The same ARM_* variables are read by the azurerm provider for local tofu runs (via .env); tofu variable values (location, rg name) come from env/dev.tfvars.

Recommended: an azurerm backend in a storage account inside CNCL-DEV. The deploy service principal needs Storage Blob Data Contributor on that account. The DIL architect creates the storage account + container and the role assignment (has Contributor + UAA), or it is handled in a small bootstrap step.

Live check against CNCL-DEV confirmed the environment is further along than this checklist assumed:

  • RGs CNCL-NET/CNCL-DEV/CNCL-TST, state account cnclbdidashtfstate (container tfstate) and ACR cnclbdidashacr already exist; the four required resource providers are Registered.
  • The DIL architect already holds Contributor + User Access Administrator on CNCL-DEV and CNCL-NET — so the app registration, role assignments and state-backend access can all be done in-house without waiting on the platform party’s Contributor grant.
  • Entra admin group CNCL-BDI-DEV-AKS-Admins created and wired into the dev tfvars.
  • The architect account was granted Storage Blob Data Contributor on the state account (for the tofu backend). The deploy SP still needs the same role once the app registration exists.

Platform party

  • Entra Application Developer role granted to DIL accounts (only needed if the app registration is not created by a global admin)
  • Contributor on CNCL-DEV for the delivery party’s developers (DIL accounts)

DIL (architect)

  • App registration created → Client ID
  • Federated credential(s) per subject (repo Basic-Data-Infrastructure/CNCL-BDI)
  • Deploy SP assigned Contributor on CNCL-DEV
  • State storage account + container exist; Blob Data Contributor granted (architect done; deploy SP pending)

Delivery party

  • infrastructure/tofu + .github/workflows added to the repo
  • GitHub repository variables set (ARM_CLIENT_ID/TENANT_ID/SUBSCRIPTION_ID)
  • App’s Azure services provisioned in CNCL-DEV via OpenTofu
  • Pipeline runs tofu apply successfully against CNCL-DEV

In samenwerking met

Connected Trade NetworkConclusionData in LogisticsContargoInland Terminals GroupVan Berkel