This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Migrating Brownfield to CD

Already have a running system? A phased approach to migrating existing applications and teams to continuous delivery.

Most teams adopting CD are not starting from scratch. They have existing codebases, existing processes, existing habits, and existing pain. This section provides the phased migration path from where you are today to continuous delivery, without stopping feature delivery along the way.

The Reality of Brownfield Migration

Migrating an existing system to CD is harder than building CD into a greenfield project. You are working against inertia: existing branching strategies, existing test suites (or lack thereof), existing deployment processes, and existing team habits. Every change has to be made incrementally, alongside regular delivery work.

The good news: every team that has successfully adopted CD has done it this way. The practices in this guide are designed for incremental adoption, not big-bang transformation.

The Migration Phases

The migration is organized into five phases. Each phase builds on the previous one. Start with Phase 0 to understand where you are, then work through the phases in order.

Phase Name Goal Key Question
0 Assess Understand where you are “How far are we from CD?”
1 Foundations Daily integration, testing, small work “Can we integrate safely every day?”
2 Pipeline Automated path to production “Can we deploy any commit automatically?”
3 Optimize Improve flow, reduce batch size “Can we deliver small changes quickly?”
4 Deliver on Demand Deploy any change when needed “Can we deliver any change to production when needed?”

Where to Start

If you don’t know where you stand

Start with Phase 0 - Assess. Complete the value stream mapping exercise, take baseline metrics, and fill out the current-state checklist. These activities tell you exactly where you stand and which phase to begin with.

If you know your biggest pain point

Start with Anti-Patterns. Find the problem your team feels most, and follow the links to the practices and migration phases that address it.

Quick self-assessment

If you don’t have time for a full assessment, answer these questions:

  • Do all developers integrate to trunk at least daily? If no, start with Phase 1.
  • Do you have a single automated pipeline that every change goes through? If no, start with Phase 2.
  • Can you deploy any green build to production on demand? If no, focus on the gap between your current state and Phase 2 completion criteria.
  • Do you deploy at least weekly? If no, look at Phase 3 for batch size and flow optimization.

Principles for Brownfield Migration

Do not stop delivering features

The migration is done alongside regular delivery work, not instead of it. Each practice is adopted incrementally. You do not stop the world to rewrite your test suite or redesign your pipeline.

Fix the biggest constraint first

Use your value stream map and metrics to identify which blocker is the current constraint. Fix that one thing. Then find the next constraint and fix that. Do not try to fix everything at once.

See Identify Constraints and the CD Dependency Tree.

Make progress visible

Track your DORA metrics from day one: deployment frequency, lead time for changes, change failure rate, and mean time to restore. These metrics show whether your changes are working and build the case for continued investment.

See Baseline Metrics.

Start with one team

CD adoption works best when a single team can experiment, learn, and iterate without waiting for organizational consensus. Once one team demonstrates results, other teams have a concrete example to follow.

Common Brownfield Challenges

These challenges are specific to migrating existing systems. For the full catalog of problems teams face, see Anti-Patterns.

Challenge Why it’s hard Approach
Large codebase with no tests Writing tests retroactively is expensive and the ROI feels unclear Do not try to add tests to the whole codebase. Add tests to every file you touch. Use the test-for-every-bug-fix rule. Coverage grows where it matters most.
Long-lived feature branches The team has been using feature branches for years and the workflow feels safe Reduce branch lifetime gradually: from two weeks to one week to two days to same-day. Do not switch to trunk overnight.
Manual deployment process The “deployment expert” has a 50-step runbook in their head Document the manual process first. Then automate one step at a time, starting with the most error-prone step.
Flaky test suite Tests that randomly fail have trained the team to ignore failures Quarantine all flaky tests immediately. They do not block the build until they are fixed. Zero tolerance for new flaky tests.
Tightly coupled architecture Changing one module breaks others unpredictably You do not need microservices. You need clear boundaries. Start by identifying and enforcing module boundaries within the monolith.
Organizational resistance “We’ve always done it this way” Start small, show results, build the case with data. One team deploying daily with lower failure rates is more persuasive than any slide deck.

Migration Timeline

These ranges assume a single team working on the migration alongside regular delivery work:

Phase Typical Duration Biggest Variable
Phase 0 - Assess 1-2 weeks None - just do it
Phase 1 - Foundations 1-6 months Current testing and trunk-based development maturity
Phase 2 - Pipeline 1-3 months Complexity of existing deployment process
Phase 3 - Optimize 2-6 months Organizational willingness to change batch size and approval processes
Phase 4 - Deliver on Demand 1-3 months Confidence in pipeline and rollback capability

Do not treat these timelines as commitments. The migration is an iterative improvement process, not a project with a deadline.

1 - Document Your Current Process

Before formal value stream mapping, get the team to write down every step from “ready to push” to “running in production.” Quick wins surface immediately; the documented process becomes better input for the value stream mapping session.

The Brownfield CD overview covers the migration phases, principles, and common challenges. This page covers the first practical step - documenting what actually happens today between a developer finishing a change and that change running in production.

Why Document Before Mapping

Value stream mapping is a powerful tool for systemic improvement. It requires measurement, cross-team coordination, and careful analysis. That takes time to do well, and it should not be rushed.

But you do not need a value stream map to spot obvious friction. Manual steps that could be automated, wait times caused by batching, handoffs that exist only because of process - these are visible the moment you write the process down.

Document your current process first. This gives you two things:

  1. Quick wins you can fix this week. Obvious waste that requires no measurement or cross-team coordination to remove.
  2. Better input for value stream mapping. When you do the formal mapping session, the team is not starting from a blank whiteboard. They have a shared, written description of what actually happens, and they have already removed the most obvious friction.

Quick wins build momentum. Teams that see immediate improvements are more willing to invest in the deeper systemic work that value stream mapping reveals.

How to Do It

Get the team together. Pick a recent change that went through the full process from “ready to push” to “running in production.” Walk through every step that happened, in order.

The rules:

  • Document what actually happens, not what should happen. If the official process says “automated deployment” but someone actually SSH-es into a server and runs a script, write down the SSH step.
  • Include the invisible steps. The Slack message asking for review. The email requesting deploy approval. The wait for the Tuesday deploy window. These are often the biggest sources of delay and they are usually missing from official process documentation.
  • Get the whole team in the room. Different people see different parts of the process. The developer who writes the code may not know what happens after the merge. The ops person who runs the deploy may not know about the QA handoff. You need every perspective.
  • Write it down as an ordered list. Not a flowchart, not a diagram, not a wiki page with sections. A simple numbered list of steps in the order they actually happen.

What to Capture for Each Step

For every step in the process, capture these details:

Field What to Write Example
Step name What happens, in plain language “QA runs manual regression tests”
Who does it Person or role responsible “QA engineer on rotation”
Manual or automated Is this step done by a human or by a tool? “Manual”
Typical duration How long the step itself takes “4 hours”
Wait time before it starts How long the change sits before this step begins “1-2 days (waits for QA availability)”
What can go wrong Common failure modes for this step “Tests find a bug, change goes back to dev”

The wait time column is usually more revealing than the duration column. A deploy that takes 10 minutes but only happens on Tuesdays has up to 7 days of wait time. The step itself is not the problem - the batching is.

Example: A Typical Brownfield Process

This is a realistic example of what a brownfield team’s process might look like before any CD practices are adopted. Your process will differ, but the pattern of manual steps and wait times is common.

# Step Who Manual/Auto Duration Wait Before What Can Go Wrong
1 Push to feature branch Developer Manual Minutes None Merge conflicts with other branches
2 Open pull request Developer Manual 10 min None Forgot to update tests
3 Wait for code review Developer (waiting) Manual - 4 hours to 2 days Reviewer is busy, PR sits
4 Address review feedback Developer Manual 30 min to 2 hours - Multiple rounds of feedback
5 Merge to main branch Developer Manual Minutes - Merge conflicts from stale branch
6 CI runs (build + unit tests) CI server Automated 15 min Minutes Flaky tests cause false failures
7 QA picks up ticket from board QA engineer Manual - 1-3 days QA backlog, other priorities
8 Manual functional testing QA engineer Manual 2-4 hours - Finds bug, sends back to dev
9 Request deploy approval Team lead Manual 5 min - Approver is on vacation
10 Wait for deploy window Everyone (waiting) - - 1-7 days (deploys on Tuesdays) Window missed, wait another week
11 Ops runs deployment Ops engineer Manual 30 min - Script fails, manual rollback
12 Smoke test in production Ops engineer Manual 15 min - Finds issue, emergency rollback

Total typical time: 3 to 14 days from “ready to push” to “running in production.”

Even before measurement or analysis, patterns jump out:

  • Steps 3, 7, and 10 are pure wait time - nothing is happening to the change.
  • Steps 8 and 12 are manual testing that could potentially be automated.
  • Step 10 is artificial batching - deploys happen on a schedule, not on demand.
  • Step 9 might be a rubber-stamp approval that adds delay without adding safety.

Spotting Quick Wins

Once the process is documented, look for these patterns. Each one is a potential quick win that the team can fix without a formal improvement initiative.

Automation targets

Steps that are purely manual but have well-known automation:

  • Code formatting and linting. If reviewers spend time on style issues, add a linter to CI. This saves reviewer time on every single PR.
  • Running tests. If someone manually runs tests before merging, make CI run them automatically on every push.
  • Build and package. If someone manually builds artifacts, automate the build in the pipeline.
  • Smoke tests. If someone manually clicks through the app after deploy, write a small set of automated smoke tests.

Batching delays

Steps where changes wait for a scheduled event:

  • Deploy windows. “We deploy on Tuesdays” means every change waits an average of 3.5 days. Moving to deploy-on-demand (even if still manual) removes this wait entirely.
  • QA batches. “QA tests the release candidate” means changes queue up. Testing each change as it merges removes the batch.
  • CAB meetings. “The change advisory board meets on Thursdays” adds up to a week of wait time per change.

Process-only handoffs

Steps where work moves between people not because of a skill requirement, but because of process:

  • QA sign-off that is a rubber stamp. If QA always approves and never finds issues, the sign-off is not adding value.
  • Approval steps that are never rejected. Track the rejection rate. If an approval step has a 0% rejection rate over the last 6 months, it is ceremony, not a gate.
  • Handoffs between people who sit next to each other. If the developer could do the step themselves but “process says” someone else has to, question the process.

Unnecessary steps

Steps that exist because of historical reasons and no longer serve a purpose:

  • Manual steps that duplicate automated checks. If CI runs the tests and someone also runs them manually “just to be sure,” the manual run is waste.
  • Approvals for low-risk changes. Not every change needs the same level of scrutiny. A typo fix in documentation does not need a CAB review.

Quick Wins vs. Value Stream Improvements

Not everything you find in the documented process is a quick win. Distinguish between the two:

Quick Wins Value Stream Improvements
Scope Single team can fix Requires cross-team coordination
Timeline Days to a week Weeks to months
Measurement Obvious before/after Requires baseline metrics and tracking
Risk Low - small, reversible changes Higher - systemic process changes
Examples Add linter to CI, remove rubber-stamp approval, enable on-demand deploys Restructure testing strategy, redesign deployment pipeline, change team topology

Do the quick wins now. Do not wait for the value stream mapping session. Every manual step you remove this week is one less step cluttering the value stream map and one less source of friction for the team.

Bring the documented process to the value stream mapping session. The team has already aligned on what actually happens, removed the obvious waste, and built some momentum. The value stream mapping session can focus on the systemic issues that require measurement, cross-team coordination, and deeper analysis.

What Comes Next

  1. Fix the quick wins. Assign each one to someone with a target of this week or next week. Do not create a backlog of improvements that sits untouched.
  2. Schedule the value stream mapping session. Use the documented process as the starting point. See Value Stream Mapping.
  3. Start the replacement cycle. For manual validations that are not quick wins, use the Replacing Manual Validations cycle to systematically automate and remove them.

2 - Replacing Manual Validations with Automation

The repeating mechanical cycle at the heart of every brownfield CD migration: identify a manual validation, automate it, prove the automation works, and remove the manual step.

The Brownfield CD overview covers the migration phases, principles, and common challenges. This page covers the core mechanical process - the specific, repeating cycle of replacing manual validations with automation that drives every phase forward.

The Replacement Cycle

Every brownfield CD migration follows the same four-step cycle, repeated until no manual validations remain between commit and production:

  1. Identify a manual validation in the delivery process.
  2. Automate the check so it runs in the pipeline without human intervention.
  3. Validate that the automation catches the same problems the manual step caught.
  4. Remove the manual step from the process.

Then pick the next manual validation and repeat.

Two rules make this cycle work:

  • Do not skip “validate.” Run the manual and automated checks in parallel long enough to prove the automation catches what the manual step caught. Without this evidence, the team will not trust the automation, and the manual step will creep back.
  • Do not skip “remove.” Keeping both the manual and automated checks adds cost without removing it. The goal is replacement, not duplication. Once the automated check is proven, retire the manual step explicitly.

Inventory Your Manual Validations

Before you can replace manual validations, you need to know what they are. A value stream map is the fastest way to find them. Walk the path from commit to production and mark every point where a human has to inspect, approve, verify, or execute something before the change can move forward.

Common manual validations and where they typically live:

Manual Validation Where It Lives What It Catches
Manual regression testing QA team runs test cases before release Functional regressions in existing features
Code style review PR review checklist Formatting, naming, structural consistency
Security review Security team sign-off before deploy Vulnerable dependencies, injection risks, auth gaps
Environment configuration Ops team configures target environment Missing env vars, wrong connection strings, incorrect feature flags
Smoke testing Someone clicks through the app after deploy Deployment-specific failures, broken integrations
Change advisory board CAB meeting approves production changes Risk assessment, change coordination, rollback planning
Database migration review DBA reviews and runs migration scripts Schema conflicts, data loss, performance regressions

Your inventory will include items not on this list. That is expected. The list above covers the most common ones, but every team has process-specific manual steps that accumulated over time.

Prioritize by Effort and Friction

Not all manual validations are equal. Some cause significant delay on every release. Others are quick and infrequent. Prioritize by mapping each validation on two axes:

Friction (vertical axis - how much pain the manual step causes):

  • How often does it run? (every commit, every release, quarterly)
  • How long does it take? (minutes, hours, days)
  • How often does it produce errors? (rarely, sometimes, frequently)

High-frequency, long-duration, error-prone validations cause the most friction.

Effort to automate (horizontal axis - how hard is the automation):

  • Is the codebase ready? (clean interfaces vs. tightly coupled)
  • Do tools exist? (linters, test frameworks, scanning tools)
  • Is the validation well-defined? (clear pass/fail vs. subjective judgment)

Start with high-friction, low-effort validations. These give you the fastest return and build momentum for harder automations later. This is the same constraint-based thinking described in Identify Constraints - fix the biggest bottleneck first.

Low Effort High Effort
High Friction Start here - fastest return Plan these - high value but need investment
Low Friction Do these opportunistically Defer - low return for high cost

Walkthrough: Replacing Manual Regression Testing

A concrete example of the full cycle applied to a common brownfield problem.

Starting state

The QA team runs 200 manual test cases before every release. The full regression suite takes three days. Releases happen every two weeks, so the team spends roughly 20% of every sprint on manual regression testing.

Step 1: Identify

The value stream map shows the 3-day manual regression cycle as the single largest wait time between “code complete” and “deployed.” This is the constraint.

Step 2: Automate (start small)

Do not attempt to automate all 200 test cases at once. Rank the test cases by two criteria:

  • Failure frequency: Which tests actually catch bugs? (In most suites, a small number of tests catch the majority of real regressions.)
  • Business criticality: Which tests cover the highest-risk functionality?

Pick the top 20 test cases by these criteria. Write automated tests for those 20 first. This is enough to start the validation step.

Step 3: Validate (parallel run)

Run the 20 automated tests alongside the full manual regression suite for two or three release cycles. Compare results:

  • Did the automated tests catch the same failures the manual tests caught?
  • Did the automated tests miss anything the manual tests caught?
  • Did the automated tests catch anything the manual tests missed?

Track these results explicitly. They are the evidence the team needs to trust the automation.

Step 4: Remove

Once the automated tests have proven equivalent for those 20 test cases across multiple cycles, remove those 20 test cases from the manual regression suite. The manual suite is now 180 test cases - taking roughly 2.7 days instead of 3.

Repeat

Pick the next 20 highest-value test cases. Automate them. Validate with parallel runs. Remove the manual cases. The manual suite shrinks with each cycle:

Cycle Manual Test Cases Manual Duration Automated Tests
Start 200 3.0 days 0
1 180 2.7 days 20
2 160 2.4 days 40
3 140 2.1 days 60
4 120 1.8 days 80
5 100 1.5 days 100

Each cycle also gets faster because the team builds skill and the test infrastructure matures. For more on structuring automated tests effectively, see Testing Fundamentals and Functional Testing.

When Refactoring Is a Prerequisite

Sometimes you cannot automate a validation because the code is not structured for it. In these cases, refactoring is a prerequisite step within the replacement cycle - not a separate initiative.

Code-Level Blocker Why It Prevents Automation Refactoring Approach
Tight coupling between modules Cannot test one module without setting up the entire system Extract interfaces at module boundaries so modules can be tested in isolation
Hardcoded configuration Cannot run the same code in test and production environments Extract configuration into environment variables or config files
No clear entry points Cannot call business logic without going through the UI Extract business logic into callable functions or services
Shared mutable state Test results depend on execution order and are not repeatable Isolate state by passing dependencies explicitly instead of using globals
Scattered database access Cannot test logic without a running database and specific data Consolidate data access behind a repository layer that can be substituted in tests

The key discipline: refactor only the minimum needed for the specific validation you are automating. Do not expand the refactoring scope beyond what the current cycle requires. This keeps the refactoring small, low-risk, and tied to a concrete outcome.

For more on decoupling strategies, see Architecture Decoupling.

The Compounding Effect

Each completed replacement cycle frees time that was previously spent on manual validation. That freed time becomes available for the next automation cycle. The pace of migration accelerates as you progress:

Cycle Manual Time per Release Time Available for Automation Cumulative Automated Checks
Start 5 days Limited (squeezed between feature work) 0
After 2 cycles 4 days 1 day freed 2 validations automated
After 4 cycles 3 days 2 days freed 4 validations automated
After 6 cycles 2 days 3 days freed 6 validations automated
After 8 cycles 1 day 4 days freed 8 validations automated

Early cycles are the hardest because you have the least available time. This is why starting with the highest-friction, lowest-effort validation matters - it frees the most time for the least investment.

The same compounding dynamic applies to small batches - smaller changes are easier to validate, which makes each cycle faster, which enables even smaller changes.

Small Steps in Everything

The replacement cycle embodies the same small-batch discipline that CD itself requires. The principle applies at every level of the migration:

  • Automate one validation at a time. Do not try to build the entire pipeline in one sprint.
  • Refactor one module at a time. Do not launch a “tech debt initiative” to restructure the whole codebase before you can automate anything.
  • Remove one manual check at a time. Do not announce “we are eliminating manual QA” and try to do it all at once.

The risk of big-step migration:

  • The work stalls because the scope is too large to complete alongside feature delivery.
  • ROI is distant because nothing is automated until everything is automated.
  • Feature delivery suffers because the team is consumed by a transformation project instead of delivering value.

This connects directly to the brownfield migration principle: do not stop delivering features. The replacement cycle is designed to produce value at every iteration, not only at the end.

For more on decomposing work into small steps, see Work Decomposition.

Measuring Progress

Track these metrics to gauge migration progress. Start collecting them from baseline before you begin replacing validations.

Metric What It Tells You Target Direction
Manual validations remaining How many manual steps still exist between commit and production Down to zero
Time spent on manual validation per release How much calendar time manual checks consume each release cycle Decreasing each quarter
Pipeline coverage % What percentage of validations are automated in the pipeline Increasing toward 100%
Deployment frequency How often you deploy to production Increasing
Lead time for changes Time from commit to production Decreasing

If manual validations remaining is decreasing but deployment frequency is not increasing, you may be automating low-friction validations that are not on the critical path. Revisit your prioritization and focus on the validations that are actually blocking faster delivery.