Skip to main content

DevSecOps · Infrastructure automation

Infrastructure that changes only through reviewed code

We write your infrastructure as Terraform modules, post the plan to every merge request for review, and let only the pipeline apply it. A scheduled plan reports drift, so a change made by hand is found rather than inherited.

Terraform moduleversioned in GitPlandiff of proposed changesReviewpeer and policy checksApplyfrom the pipeline onlyDrift detectionlive state against codeDrift becomes a change to the module
Versioned Terraform modules produce a plan on each merge request. Reviewers approve it, the pipeline runs apply under its own identity, and a scheduled plan reports drift back to the module owners.

The problem

Where this usually breaks down

  • Changes made in the console

    Someone fixes an incident by hand in the portal, the code no longer matches the estate, and the next apply quietly reverts the fix or fails halfway.

  • One state file for everything

    A single Terraform state for the whole estate locks every team on each change. Plans grow too long to review properly, and one mistake can reach everything.

  • Copied code between environments

    SIT, UAT and production are separate copies of the same code, edited apart. They drift a little with every change until nobody trusts UAT to predict production.

What we do

What we set up, and how each part works

We work in your repositories and through your change process, so everything we set up can be reviewed, run and changed by your engineers after we leave.

  • Versioned modules with clear interfaces

    We write Terraform modules for networks, clusters, identity and workload baselines, each with typed inputs, documented outputs and a version tag. Environments consume released versions, so an upgrade is a reviewed change rather than a surprise.

  • The plan reviewed on every merge request

    Every merge request runs the plan and posts it for review, with policy checks against the planned changes. Reviewers see exactly what will be created, changed or destroyed before anything is approved.

  • Applies only from the pipeline

    Only the pipeline applies, under an identity with the permissions it needs and no more. People keep read access and a logged break-glass route, and the change history lives in the repository.

  • State split along ownership lines

    Remote state is split by environment and by the team that owns each layer, with locking and restricted access. SIT, UAT and production use the same modules with different values, not different code.

  • Scheduled drift detection

    A scheduled plan runs against each environment and raises a ticket when the estate no longer matches the code. The owner then either adopts the change into code or lets the pipeline revert it.

  • Compliant VM templates as the default

    VM templates fix sizes, extensions, backup, tagging and in-guest policy, and Kubernetes deployments use Helm charts with the same defaults. Following the template is the easiest route to a compliant resource.

Reference architecture

The architecture as it was delivered

Figures from published engagements, reproduced unchanged. Open any figure full size, or read the write-up it comes from.

  1. Connectivity subscription hub network with Azure Firewall, ExpressRoute and VPN gateways, DDoS Protection and DNS Private Resolver, peered to a landing zone network with UDRs, NSGs, a load-balanced app tier, Key Vault, file share and backup.

    Figure 1 — Hub-and-spoke interconnection between the connectivity subscription and an application landing zone, including the compliant VM template baseline every workload inherits.

    Open full-size image: Figure 1 — Hub-and-spoke interconnection between the connectivity subscription and an application landing zone, including the compliant VM template baseline every workload inherits.
    Read the write-up: A governed Azure foundation a bank could build on

What you keep

What stays with your team when we finish

Everything is committed to your repositories or written into your documentation, under your access controls. Nothing depends on us to keep running.

  • A module library in your repository

    Versioned Terraform modules with examples, tests and a changelog, which your teams consume by version and extend through merge requests.

  • Environment configurations per layer

    The root configurations for each environment and layer, with remote state, locking and access set up and documented.

  • Pipelines for plan and apply

    The pipeline that plans on every merge request, applies on approval under its own identity and runs the scheduled drift check.

  • Runbooks and decision records

    Decisions on module boundaries and state layout, and runbooks for drift, state recovery, module upgrades and break-glass changes.

How we work

How an engagement runs, phase by phase

Each phase ends with something your team reviews and signs off before the next one starts. We work inside your change control, not around it.

  1. 01

    Inventory what exists

    We catalogue the resources that exist today, which are already in code, which were created by hand and how state is held. Critical resources get an import plan before anything changes.

  2. 02

    Design modules and state layout

    We agree the module boundaries, the state split and the review rules with your platform team, and write each decision down with the options set aside and why.

  3. 03

    Import and prove one environment

    Existing resources are imported into code for one environment first, and the plan must show no changes before the pipeline takes over applies there.

  4. 04

    Extend and hand over

    The same modules roll out to the remaining environments, with your engineers writing the changes and ours reviewing them. By the end, your team owns the modules, the pipelines and the drift process.

Technology

The tools this work runs on

Each group says whether a tool appears in our published work, so you can tell what we have shown from what we offer.

Run in production

  • Terraform
  • Azure
  • Azure Pipelines
  • Azure Repos
  • GitLab
  • Kubernetes
  • Helm

Offered, not in published work

  • Azure Policy

Questions

What teams ask before we start

We already have Terraform written by several teams. Do we start again?

Rarely. We review what exists, keep the modules that are sound, and refactor the rest behind stable interfaces. State follows with import and moved blocks, so resources are re-homed in code without being destroyed and recreated.

Does this work with the CI system we already run?

Yes. The plan, review and apply steps run in GitLab, Azure Pipelines, Jenkins or GitHub Actions. What we insist on is that the apply runs only from the pipeline, under an identity your team controls and can audit.

What happens when someone changes a resource by hand?

The next scheduled plan shows the difference and raises a ticket for the resource owner. They either write the change into code, if it should stay, or let the pipeline revert it. Emergency changes remain possible through break-glass access, and are reconciled afterwards.

What access do you need to our environments?

Read access for the inventory. During the build, we propose every change as a merge request, and your pipeline applies it under an identity you own. Nothing reaches your environments outside your own change process.

Who owns the modules after handover?

Your platform team. The modules, root configurations, pipelines and runbooks are in your repositories from the first commit, and your engineers publish new module versions themselves. We can stay on as reviewers, but nothing depends on us.

Related services

  • CI/CD pipelines with enforced gates

    Pipelines that run unit tests, SCA, SAST, quality and image scans in cost order, and send every failed gate to the team that owns it.

  • Azure landing zones

    Azure landing zones in Terraform: management groups, policy at scale and a hub-and-spoke network that every subscription inherits.

  • Cloud-native DevOps on Kubernetes

    One image built per change, Helm charts per service, and a GitOps controller that promotes it from SIT to UAT to PROD on Kubernetes.

Next step

Plan your infrastructure as code with us

Tell us what is in code today, what is not, and how changes reach production. We will suggest where to draw the first module and state boundaries.