Skip to main content

Platform Engineering and Infrastructure as Code on Microsoft Azure

Platform Engineering and Infrastructure as Code on Microsoft Azure

Azure offers two credible routes to infrastructure as code and two credible routes to CI/CD, which is why most Azure platform work starts with a decision rather than a build. Celestique Cloud helps you choose between Bicep and Terraform, and between Azure DevOps and GitHub, then builds the modules, pipelines and policy guardrails that make the choice hold. Identity, approval and audit run through Microsoft Entra ID, which is usually the directory your business already governs. Management group and subscription structure sits one layer below this work, in our landing zone practice.

Why Azure

When this is the right platform.

  • Where Microsoft 365 is already in place, Microsoft Entra ID is the directory the business governs day to day, so pipeline permissions, deployment approvals and access reviews can sit on groups it already owns rather than on a second identity system nobody reviews.
  • Bicep is first-party, has no state file to protect and previews changes with what-if, which shortens the learning curve for teams writing infrastructure as code for the first time.
  • Azure Policy applies the same rule at management group and subscription level that the pipeline checks at pull request, so the control still holds when a change arrives outside the pipeline.
  • Azure DevOps and GitHub can coexist during a transition. Teams embedded in Azure Repos and Azure Pipelines keep working while new services adopt GitHub Actions, sharing one module library and one policy set.
  • Azure Container Apps carries services that do not justify a cluster and Azure Kubernetes Service is there for the ones that do, so the runtime decision is per workload rather than all or nothing.

Where it is less suited

We would rather say this now than after a migration.

  • Bicep only targets Azure. If you run workloads on another cloud, or manage SaaS platforms that publish Terraform providers, standardising on Terraform avoids maintaining two module libraries, at the cost of running and protecting state.
  • Bicep has no plan file you can archive. What-if is a preview operation rather than a committed plan that apply consumes, so the exact-change artefact an auditor asks for is something the pipeline has to capture and store deliberately.
  • Deployment stacks give Bicep a real lifecycle boundary and deny-assignment protection, but what-if is not supported inside a stack. Safe delete and preview-before-apply therefore pull against each other, and most estates end up using stacks for platform resources and plain incremental deployments for application releases.
  • Azure DevOps and GitHub overlap heavily, and Microsoft's new investment is concentrated on GitHub. Azure DevOps remains supported and still receives updates, but choosing it today means accepting that new capability lands elsewhere first. Running both indefinitely means two permission models, two audit trails and two sets of runners to patch.
  • Azure Kubernetes Service upgrades, node image refreshes and add-on support windows are continuing work, and staying on an older minor version means moving the cluster to the Premium tier for long-term support, which is a per-cluster charge. A managed control plane is not a maintenance-free cluster.
  • Azure Policy is capable but awkward to test. There is no local dry run worth trusting, remediation across a large estate evaluates slowly, and a definition that reads correctly is often scoped wrong. Proving a policy in a sandbox subscription before assigning it broadly is an extra step worth taking.

Business outcomes

What Azure delivers here.

One way to deploy into Azure
Every subscription receives change through the same pipeline and the same module set, so an engineer moving between products does not relearn deployment.Agreed measure: Share of Azure resource changes applied through a pipeline rather than the portal, read from subscription activity logs.
Environments generated rather than assembled
Development, test and production come from the same Bicep or Terraform modules with different parameter files, so a fix proven in test behaves the same in production.Agreed measure: Drift findings per environment per month, with the number closed in code tracked separately from those accepted.
Guardrails that hold outside the pipeline
Compliance and risk owners get assurance that a resource created by hand still meets the standard, because Azure Policy evaluates it regardless of how it arrived.Agreed measure: Azure Policy compliance by subscription, reported monthly with every exemption listed.
Deployment evidence without the paperwork
Commit, plan, approver and applied result are captured against every production release, and Application Insights shows the deployment alongside the application behaviour that followed it.Agreed measure: Proportion of production releases carrying a complete commit, plan, approver and applied-result record.
New services start ready to deploy
A team starts from a template repository with pipeline, policy checks, registry access and Key Vault wiring already connected, rather than waiting on a platform ticket.Agreed measure: Elapsed days from repository creation to that team's first production deployment.

Common client problems

What we usually hear first.

  • We have Azure DevOps for some teams and GitHub for others, and no idea which one is the standard.

    We assess where each is genuinely embedded, what it would cost to move and what it costs to keep both, then set a target and a migration order instead of leaving the question open. A shared Bicep or Terraform module library and a shared policy set mean both toolchains produce the same result while the transition runs. We will also be direct that Microsoft's new investment is concentrated on GitHub, which is a factor in the target rather than an emergency.

  • Half our Azure resources were created in the portal and we cannot tell which ones.

    We reconcile the running estate against the code base, then import or rebuild in priority order, starting with production and anything holding data. What stays outside code is recorded as an exception with an owner and a review date rather than quietly ignored.

  • Bicep or Terraform? We have been arguing about it for six months.

    We make the call against your real constraints: whether the estate is Azure-only, whether Terraform is already in use elsewhere, who will maintain the modules and whether managing state is work you want. The decision is written down with its trade-offs so it does not reopen every quarter.

  • Our pipeline service principal has owner rights and a secret that expired last month.

    We move pipelines to workload identity federation so there is no secret to expire, then scope each deployment identity to the subscription, resource group and role it actually needs. Standing high-privilege access is replaced with elevation that is requested, time-bound and logged.

  • Our AKS cluster was set up two years ago and nobody wants to touch it.

    We bring the cluster configuration into code, establish a supported upgrade path and rehearse the upgrade on a non-production cluster before production is touched. Where a workload never needed Kubernetes, we assess whether Azure Container Apps removes the maintenance entirely. We will also show you what staying on an old minor version costs, because long-term support means moving the cluster to the Premium tier.

How we deliver

Our Azure delivery approach.

  1. 01

    Assessment and advisory

    Azure platform work usually stalls on unresolved decisions rather than on build effort. We resolve them with evidence taken from your own subscriptions.

    • Bicep against Terraform, decided. Judged on whether the estate is Azure-only, who maintains the modules, existing Terraform investment and your appetite for protecting state.
    • Azure DevOps against GitHub, decided. Compared against how your teams actually work, where repositories, pipelines and boards are already embedded, and what a move would break.
    • Activity logs read for portal changes. Azure activity logs used to establish how many resource changes currently arrive outside a pipeline, broken down by subscription and by team.
    • Deployed resources reconciled to code. What is unmanaged, duplicated or orphaned listed explicitly, with an owner assigned to each item rather than a total reported.
    • Structure and tagging checked first. Management group and subscription structure, naming, tagging and existing Azure Policy assignments reviewed against what the pipeline will need to enforce.
    • Sequenced plan with a commercial case. Effort, dependencies, cost and the measures that will define success, ordered so the first increment is worth having on its own.
  2. 02

    Architecture and implementation

    We build the module library, the pipelines and the runtime foundations together, proving each on a real workload before it becomes the standard.

    • A published module library. Versioned Bicep or Terraform modules published to a registry, with pinned versions and a tested upgrade path for the teams consuming them.
    • Remote state locked and recoverable. Wherever Terraform is used, state is configured with locking, restricted access and a documented, rehearsed recovery procedure.
    • What-if or plan before approval. Pipelines in Azure Pipelines or GitHub Actions run what-if or plan, publish the output for review, gate on environment approval, then apply.
    • Registry hardened, deployed by digest. Azure Container Registry with tag locking, retention rules and Defender for Cloud image scanning, then deployment to AKS or Azure Container Apps by digest rather than by floating tag.
    • Azure Policy shipped with the module. Policy defined as code alongside the infrastructure modules, so a control arrives with the resource pattern it governs instead of turning up months later.
    • Proven by an empty-subscription rebuild. A non-production environment rebuilt into an empty subscription straight from the repository, with the elapsed time recorded as a baseline.
  3. 03

    Security and governance

    Pipeline identity and secret handling are where Azure delivery platforms most often carry avoidable risk. We remove the standing credentials first, then tighten scope.

    • Federated identity, no stored secret. Pipelines moved to Microsoft Entra workload identity federation, so no client secret or certificate is held in Azure DevOps or GitHub at all.
    • Deployment identity scoped down. Each identity limited to the subscription, resource group and role it needs, with inherited owner assignments left over from initial setup removed.
    • Key Vault with rotation you own. Secrets, keys and certificates stored in Azure Key Vault and referenced at run time, with near-expiry events subscribed and the rotation the vault does not perform scheduled.
    • Policy proven before it is enforced. Azure Policy assigned at management group level with deny and audit effects agreed in advance, each proven in a sandbox subscription before promotion.
    • Production needs a second person. Branch protection, mandatory review and protected environment approvals, so a release to production is never a single pair of hands.
    • Compliance mapped to your framework. Azure Policy compliance and pipeline controls mapped to what your customers ask about, such as the Essential Eight, to support your assurance work. We help you align to a framework rather than certify against one.
  4. 04

    Adoption and enablement

    The platform succeeds when a delivery team can create a new service without asking permission and without asking how. We build that path, then teach it.

    • A template repository to clone. Pipeline, module references, policy checks, Azure Container Registry access and Key Vault wiring already connected, so a new service starts deployable.
    • First pipelines built in pairs. The first two or three service pipelines written with your engineers, so the patterns are learned during the build rather than read afterwards.
    • Approvers taught to read a plan. Working sessions on what-if and plan output, because an approval given by someone who cannot read the diff is a control on paper only.
    • Runbooks for Azure-specific failures. Failed deployments, stuck state locks, rollback in Azure Container Apps and AKS, and a revoked or expired federated credential.
    • Hand-over by doing, while we watch. Your team performs a production deployment and a subscription rebuild while we observe and only advise.
    • Pipeline share tracked, not asserted. The proportion of Azure resource changes arriving through the pipeline reported against the baseline captured during assessment.
  5. 05

    Managed service continuation

    Under an agreed managed scope we keep the Azure platform current, because version pins, policy exemptions and cluster support windows all expire on somebody else's schedule.

    • AKS support windows tracked. Version support windows, node image releases and add-on compatibility watched, with upgrades scheduled before a version leaves standard support.
    • Versions kept current and tested. Bicep, Terraform provider, module and container base image versions updated on a cadence and tested in a lower environment before production.
    • Drift detected across subscriptions. Scheduled drift detection, with each change either returned to code or recorded as an accepted exception carrying a named owner.
    • Policy exemptions closed off. Azure Policy compliance and exemptions reviewed monthly, closing the temporary exemptions that have outlived the reason they were granted.
    • Pipeline failures acted on. Duration and failure rate tracked in Azure DevOps pipeline analytics or GitHub Actions run history, with Application Insights used to catch releases that degraded the workload after a successful deploy.
    • Cost reported by environment. Azure spend broken down by environment and workload, including non-production resources that could be scheduled off, resized or retired.

Reference architecture

An Azure delivery platform, layer by layer.

How the pieces fit together on Microsoft Azure. Every engagement adapts this, and we will tell you which layers you already have.

  1. 01

    Source and review

    Branch protection and required review, so a change has an author and a reviewer.

    • GitHub or Azure Repos
    • Branch protection rules
    • Pull request policy checks
  2. 02

    Validate

    Lint, test and preview all run before a human is asked to approve anything.

    • GitHub Actions or Azure Pipelines
    • Bicep what-if or terraform plan
    • Container build and image scan
  3. 03

    Approve

    The preview published and signed off by someone who did not write the change.

    • Protected environments
    • Published plan artefact
    • Second-person approval
  4. 04

    Apply

    Federated identity, scoped per subscription, with no cloud secret stored anywhere.

    • Workload identity federation
    • Scoped deployment identity
    • Azure Key Vault references
  5. 05

    Run and observe

    Where the artefact runs, and how a bad release is traced back to its commit.

    • Azure Kubernetes Service or Container Apps
    • Azure Monitor
    • Application Insights

Across every layer

  • Azure Policy evaluating resources however they arrive
  • Microsoft Entra ID groups for pipeline and approval rights
  • Every layer defined in version-controlled code
  • Cost reported by environment, non-production included
Most pipelines we inherit have 01, 02 and 04 and nothing at 03: a preview is generated in the same job that applies it, so nobody ever reads it. The other common gap is treating the pipeline as the only control, which is why Azure Policy spans all five layers rather than living inside one. A portal edit never touches the pipeline at all.

Technology reference

The Microsoft Azure services we build with.

A reference architecture view of the platform services used in this domain, and what each one does in the design.

Source control and delivery pipelines

  • GitHubHosts repositories, pull requests, branch protection and required review for teams standardising on GitHub.
  • GitHub ActionsRuns the plan, review, approval and apply workflow, with environment protection rules gating production.
  • Azure DevOpsHosts repositories, pipelines and work tracking for teams already embedded in the Microsoft toolchain.
  • Azure ReposProvides Git hosting with branch policy and required reviewers where Azure DevOps is the standard.
  • Azure PipelinesRuns multi-stage deployment pipelines with environment approvals and deployment history per stage.

Infrastructure as code

  • BicepDeclares Azure resources in a first-party language with what-if previews and no state file to protect.
  • TerraformDeclares infrastructure where the estate reaches beyond Azure or an existing Terraform investment should be extended.

Build artefacts and runtime

  • Azure Container RegistryStores container images and OCI artefacts with tag locking, retention rules and pull identity scoped through Microsoft Entra ID. Image vulnerability scanning comes from Microsoft Defender for Cloud rather than the registry itself.
  • Azure Kubernetes ServiceRuns container workloads that need orchestration, custom networking or a large service footprint.
  • Azure Container AppsRuns container services that need scale to zero and managed ingress without cluster maintenance.

Guardrails, identity and secrets

  • Azure PolicyEnforces resource standards at management group and subscription level and reports compliance independently of the pipeline.
  • Microsoft Entra IDIssues the federated identity a pipeline deploys with, and holds the groups that carry approval and platform administration rights.
  • Azure Key VaultHolds secrets, keys and certificates referenced at deploy and run time, with expiry events available to drive rotation.

Deployment telemetry

  • Azure MonitorCollects platform metrics, logs and alerts across the Azure resources the platform deploys, including resource health signals. Pipeline duration and failure rate come from Azure DevOps pipeline analytics or GitHub Actions run history rather than from here.
  • Application InsightsCorrelates a deployment with the application behaviour that followed it, so a regression is traced back to a release.

Product names and icons are trademarks of Microsoft and Amazon Web Services, reproduced unmodified from their official architecture icon libraries to identify the technologies used in these architectures. Their presence does not indicate partnership, certification or endorsement by either vendor.

Azure questions

What people ask about doing this on Azure.

Cost, lock-in and the parts that go wrong, answered before you have to ask twice.

  • Bicep or Terraform for Azure? What do you actually recommend?

    If the estate is Azure-only and the team is new to infrastructure as code, Bicep is usually the shorter path: first-party, no state file to protect, what-if built in. Terraform earns its extra operational work where you span clouds, manage SaaS platforms with published providers, or already have Terraform skill in the building. The uncomfortable part is that this is close to a one-way decision, because your module library, your pipelines and your hiring all follow it, so we record the reasoning as a decision rather than a preference.

  • Is Azure DevOps being retired in favour of GitHub?

    Not retired, and we would not advise a panic migration. Azure DevOps continues to be supported and still receives updates, and Boards and Pipelines have a real user base. What has changed is where the new capability lands: Microsoft's development investment is now concentrated on GitHub. If you are already deep in Azure DevOps, the sensible position is a documented target and an unhurried migration order, not a rebuild this quarter. If you are choosing from scratch today, we would choose GitHub.

  • What does an Azure delivery platform cost to run each month?

    Separately from your workloads, there are four lines worth seeing. Hosted agents or Actions minutes, which grow with test suites rather than release count, and self-hosted runners trade that bill for patching work. Azure Container Registry storage, which grows quietly until retention rules exist. Log Analytics ingestion for deployment and platform telemetry, which is the line that surprises people. And non-production environments, most often left at production size out of caution. We estimate all four at expected volume during assessment and state the assumptions.

  • Do we need AKS, or is Azure Container Apps enough?

    For a modest number of stateless HTTP services, Container Apps is usually enough and it removes cluster upgrades, node images and add-on compatibility from your team's list entirely. AKS earns its maintenance when you genuinely use Kubernetes primitives: operators, custom controllers, complex networking, or portability you can actually name a use for. We assess it per workload, and the honest answer for a meaningful share of the clusters we are shown is that the workload never needed one.

  • Will Azure Policy start blocking our releases?

    It can, and that risk is managed by sequencing rather than by hope. Preventive effects run in audit mode first, we publish exactly which existing and in-flight deployments would have been blocked, agree an exemption path with a named approver, then enforce. The failure mode to avoid is enforcing broadly, blocking a legitimate release, and responding with a scope exclusion so wide that the control is quietly disabled everywhere. Policy that has never blocked anything is also worth questioning.

  • We are a small team. Can we maintain an Azure platform in-house afterwards?

    Yes, if the platform is sized for the team rather than for a reference architecture. That usually means Bicep over Terraform to avoid state as an operational concern, Container Apps over AKS to avoid the upgrade cadence, one toolchain rather than two, and a deliberately small module library. Where a client has one part-time platform engineer and we are asked for a full self-service developer platform, we will say the maintenance load is unrealistic and scope down instead of building it.

  • Can you bring resources created in the portal under code without rebuilding them?

    Sometimes, and it is slower and less predictable than writing new ones. Bicep and Terraform can both adopt existing resources, but the imported definition has to be reconciled with what is actually deployed, and settings applied by hand years ago frequently do not match anything you would choose now. We import in priority order starting with production and anything holding data, and where a resource is cheaper to redeploy than to reconcile we will recommend that instead.

Related industries

Where this work has the most leverage.

  • Professional Services

    Governed enterprise search, document intelligence and secure copilots that respect matter confidentiality and conflict boundaries.

  • Construction and Property

    Tender intelligence, addenda tracking and project reporting that keep estimators and contract administrators ahead of the documents instead of buried in them.

  • Manufacturing and Distribution

    Demand and inventory intelligence, production analytics and supplier automation built on data your planners already trust.

Free discovery workshop

Start with a platform engineering and iac discovery workshop.

Bring one challenge. We will assess whether Microsoft Azure is the right platform for it before recommending anything.