What Shift Left in DevOps Actually Means
By Isaiah Daniel·
Shift left means catching bugs, security holes and broken infrastructure where they are cheapest to fix: on the laptop and in the pull request.
Picture a team at Ledgerline, a fictional digital bank, shipping a Terraform change that opens a security group to 0.0.0.0/0. Nobody is careless. The change is reviewed, the pipeline is green, and the deploy goes out on schedule. The problem is that the only check that could catch it is a quarterly security review, weeks after the fact. By the time anyone notices, the port has been open to the internet for nine days.
That scenario is the clearest explanation of "shift left" I know. Picture your delivery process as a line running left to right: write code, commit, open a pull request, build, test, deploy, run in production. Most teams do their serious checking on the right side of that line. Shift left means moving those checks toward the left, so problems are found minutes after they are written instead of weeks after they ship.
Why the left side is cheaper
The cost of a defect grows with the distance between where it was introduced and where it was found. A failing unit test on your laptop costs you thirty seconds. The same bug found in staging costs a context switch, a ticket, a redeploy and maybe a blocked release. Found in production, it costs an incident, a postmortem and sometimes money or trust you do not get back.
There is also a feedback effect. When an engineer learns about a mistake while the code is still fresh in their head, the fix is small and the lesson sticks. When they learn about it three weeks later from a security team they have never met, the fix is a chore and the lesson is "security slows us down".
Shift left is not a tool. It is a decision about when each kind of check runs, and who owns the result.
What actually moves left
Almost every check you already do can run earlier than it does today:
| Check | Traditional place | Shifted left |
|---|---|---|
| Unit and integration tests | QA phase, nightly builds | Every commit, every pull request |
| Security scanning (SAST, dependencies) | Pre-release audit | Pull request pipeline |
| Secret detection | Incident response | Pre-commit hook and pull request |
| Infrastructure policy | Manual review, quarterly audit | terraform plan stage in CI |
| Container vulnerabilities | Runtime scanner in the cluster | Image build step |
| Performance regressions | Load test before a big launch | Lightweight benchmark per pull request |
The goal is not to delete the right-side checks. Production monitoring, runtime scanning and periodic audits still matter, because some problems only show up under real traffic. The point is that the right side should be a safety net, not the first line of defence.
A shifted-left pipeline at Ledgerline
Here is how I would set this up for Ledgerline, running NestJS services on Kubernetes with infrastructure in Terraform. Every stage below runs on every merge request, and nothing merges unless all of them pass.
# .gitlab-ci.yml
stages: [lint, test, security, infra, build]
lint:
stage: lint
image: node:20
script:
- npm ci
- npm run lint
- npx tsc --noEmit
unit-tests:
stage: test
image: node:20
services: [postgres:16]
variables:
POSTGRES_PASSWORD: test
DATABASE_URL: postgres://postgres:test@postgres:5432/postgres
script:
- npm ci
- npm test -- --coverage
secrets:
stage: security
image: zricethezav/gitleaks:latest
script:
- gitleaks detect --source . --redact --verbose
dependencies:
stage: security
image: node:20
script:
- npm audit --audit-level=high
terraform-policy:
stage: infra
image: bridgecrew/checkov:latest
script:
- checkov -d infra/ --framework terraform --compact
image-scan:
stage: build
image: docker:27
services: [docker:27-dind]
script:
- docker build -t ledgerline/api:$CI_COMMIT_SHA .
- docker run --rm -v /var/run/docker.sock:/var/run/docker.sock
aquasec/trivy:latest image --exit-code 1 --severity HIGH,CRITICAL
ledgerline/api:$CI_COMMIT_SHA
The terraform-policy job is the one that would have stopped the open security group from the opening. Checkov ships with a rule for ingress open to the world, so the merge request fails with a clear message pointing at the exact resource, before anyone has to review it by hand.
The pipeline is the middle of the line. You can go one step further left with a pre-commit hook, so the most common mistakes never even reach the server:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.4
hooks:
- id: gitleaks
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.92.0
hooks:
- id: terraform_fmt
- id: terraform_validate
A leaked AWS key caught by a pre-commit hook is a non-event. The same key caught after it has been pushed to a shared remote means rotating credentials and auditing every place the key could have been used.
Where teams get shift left wrong
Dumping everything on developers. Shifting left does not mean "developers now do the security team's job". It means the security, platform and QA people encode their knowledge into automated checks that developers run without thinking about it. If the shift is just a longer checklist, you have moved work, not reduced it.
Slow pipelines. If the merge request pipeline takes 40 minutes, engineers stop waiting for it, batch up changes and start pushing around it. Keep the left side fast: run the cheap checks first, parallelise the stages, cache dependencies, and move genuinely slow suites (full end-to-end, long load tests) to a nightly job.
Noisy scanners. A dependency scanner that flags 300 low-severity issues on day one gets ignored by day three. Start with a strict threshold (high and critical only), fix those, then tighten. An ignored check is worse than no check, because it trains people to click past warnings.
Forgetting the right side. Some failures, like a slow query that only appears with production data volumes, cannot be caught before deploy. Shift left pairs best with good observability (dashboards, alerts and fast rollback), so the problems that do slip through are caught in minutes, not days.
How to start without a big project
You do not need a platform team or a six-month programme. On a typical service I would add, in this order:
- Lint and type checks on every merge request. Fast, cheap, no false positives.
- Unit tests in the pipeline, required to pass before merge.
- Secret scanning, both as a pre-commit hook and in CI.
- Dependency scanning at high and critical severity only.
- Infrastructure policy checks on
terraform planfor any repo that touches cloud resources. - Container image scanning once you are shipping images.
Each step is a few lines of config and pays for itself the first time it catches something. The order matters: early wins with no false positives build trust in the pipeline, which makes the stricter checks easier to adopt.
Takeaways
- Shift left means running checks as early in the delivery line as possible, where problems are cheapest to fix.
- It applies to tests, security, secrets, infrastructure policy and container images, not just code quality.
- The left side must stay fast and quiet, or engineers will route around it.
- It does not replace production monitoring. It makes production the safety net instead of the first test.
- Start small: lint, tests, secrets, then policy and scanning, one merge request at a time.
If you are working on the reliability side of the same problem, my post on idempotent payments with Redis and PostgreSQL covers the kind of bug that no amount of shifting left fully removes, and how to design for it.