Complexity always finds a way in.

Our CI/CD pipeline started with a few scripts.

Build the code. Run the tests. Deploy the artifact.

It worked well. For a while.

Then requirements accumulated. Quietly.

Complexity Did Not Arrive All at Once

No one decided to make the pipeline complicated.

It happened incrementally:

  • add a security scan
  • support another environment
  • introduce feature flags
  • handle hotfixes
  • add approvals
  • support rollback

Each change made sense in isolation.

Together, they reshaped the system.

The first security scan added two minutes to the build. Acceptable. The second environment doubled deployment configurations. Manageable. Feature flags required conditional logic. Reasonable. Hotfixes needed a separate path. Necessary.

None of these additions felt dramatic. Each solved a real problem. Each was justified by a specific need. But each also added a branch, a condition, a special case.

Six months in, the pipeline had multiple entry points, conditional steps, environment-specific logic, and failure modes that depended on which path you took through it. Debugging became detective work. New engineers needed a guide to understand what was happening.

The pipeline still worked. But it no longer felt simple. And no single change was responsible for that.

Pipelines Reflect the Organization

Pipelines absorb every organizational concern:

  • security wants checks
  • compliance wants traceability
  • product wants speed
  • operations wants safety

CI/CD becomes the meeting point of competing priorities.

That guarantees complexity.

Security needs vulnerability scanning before deployment. Compliance needs audit trails for every production change. Product needs fast iteration cycles. Operations needs guardrails to prevent incidents.

The pipeline has to satisfy all of them. It cannot say no to legitimate requirements. So it grows.

This is Conway’s Law applied to automation. The pipeline structure mirrors the organizational structure. If security and compliance and product and operations all have veto power, the pipeline reflects that. It becomes a negotiation encoded in YAML.

The complexity is not accidental. It is organizational complexity made visible.

Automation Does Not Remove Decisions

Automation moves decisions earlier. It does not eliminate them.

Every pipeline step encodes:

  • who is allowed to deploy
  • what “done” means
  • when risk is acceptable

As those decisions evolve, pipelines evolve with them.

A manual deployment involved judgment at every step. Is the code ready? Are the tests sufficient? Is production stable enough to accept this change? Humans made those calls in the moment.

Automation forces those decisions to be made upfront. The pipeline either runs or it does not. Tests either pass or fail. Approval gates either block or allow. There is no room for situational judgment unless you build it in explicitly.

This is good for consistency. It is hard for nuance.

As teams learn more about what can go wrong, they add more checks. As requirements change, they add more conditions. The pipeline becomes a codification of accumulated wisdom and accumulated fear.

The Real Surprise

The surprise was not that pipelines got complex.

It was that complexity arrived without anyone owning it.

Scripts grew into workflows. Workflows became systems. Systems became critical infrastructure.

Without the ownership to match.

In the beginning, the pipeline was just a few scripts in a repository. Anyone could modify them. Changes were informal. No one thought about versioning or backward compatibility.

As the pipeline grew, it became load-bearing infrastructure. Deployments depended on it. Feature rollouts required it. Incident response used it. But it still lived in a repo alongside application code, managed as a side project.

No one had “pipeline owner” in their job description. No one was accountable for its reliability or evolution. Issues were fixed reactively. Improvements happened when someone had time.

The mismatch between importance and ownership created debt. The pipeline grew more complex faster than anyone’s understanding of it grew. Eventually, debugging the pipeline became as hard as debugging the application.

Final Thought

CI/CD pipelines do not stay simple because the work they support does not stay simple.

The goal is not to avoid complexity. It is to make it intentional.

Related reading: