tldr;
Most teams don’t struggle because they can’t write pipelines. They struggle because pipelines slowly turn into snowflakes.
One pipeline has a “special” approval step. Another uses different variable names. Prod behaves slightly differently to non-prod. Someone adds a quick hack for a one-off scenario, then three months later it becomes “the way we do it” for that workload forever.
Probelm statement
"We have inconsistency, it is hard to manage"
Solution
The answer to this is boring on purpose: templates
Templates
This isn’t a new idea, and I am not not pretending it is. But it’s one of the highest leverage things I’ve done to make delivery predictable across multiple teams and environments, without constantly re-designing how deployments should work.
When I say templates, I don’t mean “a YAML snippet that saves a bit of typing”.
I mean we bake workflows into reusable building blocks, so that pipelines look and behave the same way:
- same stage layout
- same job boundaries
- same environment conventions
- same approval and safety model
- same output handling
- same defaults and guardrails, with escape patterns when they are needed
Ours simple goal: if you understand one pipeline, you understand them all (mostly).
Why this matters
Templates give us consistency, but the real benefits are:
1) Behaviour is predictable across environments
Terraform is the obvious example. We want:
- dev/test to move fast and be largely automated
- production to be safe, deliberate, and observable
- the mechanics of plan/apply/output to be identical everywhere
Templates let us keep the workflow consistent while still adjusting the policy per environment (for example: approvals, branch rules, auto-apply rules).
2) We reduce “pipeline drift”
Without templates, every team gradually makes changes to their pipeline to get a win. Eventually you end up with 'n' pipelines and 'y' slightly different definitions of “done”.
Templates pull that drift back into a single place.
3) We move improvements into the platform
If we improve logging, error handling, approvals, or artefact publishing in the template, everyone gets it. That’s the key.
It turns “CI/CD improvements” from “go fix 80 pipelines" into “update the template and roll forward”.
Structure
This is the bit that tends to get lost. The structure matters.
Stages > Jobs > Steps
Stages represent lifecycle phases
Stages are where we draw the big boundaries. For Terraform, that might be:
Validate (lint, fmt, static checks)
> Plan (generate a plan, publish it, summarise it)
> Apply (apply the plan if allowed)
> Outputs (emit outputs for downstream usage)
> Post-Deploy (smoke tests, metadata, notifications)
Not every workload needs all of these, but the pattern stays stable.
Stages
Stages are also where we attach:
- environment targeting
- approvals / checks
- conditions (branch gates, safe-change gates)
Jobs
Jobs represent “units of responsibility”
Jobs should be cohesive and independently understandable. A job should answer: what did we try to do here?
For example:
- a job to run terraform plan
- a job to run terraform apply
- a job to publish outputs / artefacts
- a job to run smoke tests
Keeping job responsibilities clean matters for:
- troubleshooting
- reruns
- permissions scoping (where possible)
- clear logs
Steps
Steps are implementation detail
Steps are the mechanics: install tooling, auth, run the command, publish artefacts.
The template makes steps consistent:
- same terraform versioning approach
- same auth mechanism
- same folder conventions
- same output formatting
- same failure handling
If we find a better way to do something, we fix it once in the template and move on.
Example
Terraform as the example workload, this is where templates pay for themselves quickly because it’s inherently repetitive and environment-driven.
A typical pipeline flow:
1. Init with a standard backend configuration approach
2. Validate / fmt so we catch obvious issues early
3. Plan and publish the plan as an artefact (or at least publish a summary)
4. Apply only under the right conditions
5. Outputs published in a predictable format for downstream pipelines
The important bit: teams don’t have to remember how to do any of this. They just opt into the template and pass parameters.
Parameterisation
Standard where it matters, flexible where it counts
The trick is balancing “platform consistency” with “teams need autonomy”.
Good template parameters tend to be things like:
- environment name
- subscription / account target
- working directory
- feature flags like plan-only vs plan+apply
- approval mode
- additional validations
- what outputs to publish
Bad template parameters are the ones that let every team reinvent the workflow. If you allow too much freedom, you end up back at snowflakes.
So we’re deliberate:
- tight defaults
- few but meaningful knobs
- escape hatches for truly weird cases, ideally via extension points rather than forks
Consistency
Consistency doesn’t mean “everything is identical”
One important point: templates don’t mean every workload is treated the same.
Networking and shared workloads, are the obvious exceptions. They might require:
- stricter approval
- different safety rules (create-only rules don’t apply cleanly)
- extra validation steps
- more careful blast radius boundaries
Templates should support those cases, but in a controlled way. The point isn’t to force everything into one pipeline shape, it’s to keep the delivery system understandable.
Outputs
Outputs: the underrated superpower
One of the biggest wins from templating Terraform pipelines is outputs become an artefact.
That matters because downstream stages and deployments often need:
- resource IDs
- connection details (non-secret)
- environment metadata
- references for Helm values, app configs, or other IaC layers
If every pipeline publishes outputs differently, automation turns into a nightmare.
If every pipeline publishes outputs consistently, you can build reliable end-to-end workflows.
Productisation
This is where the “pipeline as a product” value comes from.
The goal: reduce cognitive load
The best pipelines are the ones you don’t think about.
Engineers shouldn’t need to be CI/CD experts to make changes safely. They should be able to:
- make a change
- read the plan
- understand what will happen
- get the right approvals when needed
- see clear logs when something breaks
Once we have consistent templates, we can build on top of them:
- policy-driven approvals (based on plan analysis)
- automatic PR feedback (plan summaries posted back to PRs)
- standardised smoke tests per workload type
- cost estimation hooks
- drift detection on schedules
- consistent observability around deployments
Start treating them as part of your platform.
Reducing effort: pipelines are not where teams should spend time
One of the strongest arguments for CI/CD templates has nothing to do with YAML quality or architectural purity.
It’s about where engineering effort is spent.
Product and feature squads exist to deliver value to customers:
- shipping features
- fixing bugs
- improving reliability and performance
- learning from real usage
They should not:
- design pipeline workflows
- debate where approvals should sit
- figure out how Terraform should be initialised
- rediscover how to safely deploy to production
Every hour a product team spends crafting or debugging pipelines is an hour not spent improving the product.
Instead:
- the platform team owns the delivery mechanics
- product teams consume a paved road
- the “how” of delivery is mostly solved up front
The result is less friction, faster onboarding, and fewer subtle mistakes.
Consistency reduces thinking, not flexibility
A common fear with templating is that it “locks teams in”.
In practice, good templates do the opposite. They remove the need to think about the boring, repetitive bits, so teams can focus on what actually matters for their workload.
When a pipeline is predictable:
- reviews are faster
- failures are easier to diagnose
- on-call engineers recognise patterns immediately
- audits and compliance become simpler
We are remvoing cognitive from teams, not adding it!
Summary
When templates are:
- widely adopted
- versioned
- extensible
- and boringly reliable
You unlock real platform leverage:
- improvements roll out everywhere
- safety guarantees are consistent
- teams onboard faster
- delivery becomes a non-event
The best compliment a CI/CD platform can get is silence. If teams aren’t talking about pipelines, it’s usually because they’re busy adding value.