Blog
Database DevOps

Infrastructure as Code Isn't Enough: Why Database Delivery Must Evolve | Harness Blog

Infrastructure as Code transformed infrastructure delivery. Learn why database delivery requires a different approach and how Database DevOps closes the gap.

  • Infrastructure as Code solved infrastructure provisioning, but it did not solve database schema change delivery.
  • Database changes are fundamentally different because they modify persistent production state.
  • Separate application and database deployment workflows increase operational risk.
  • Modern platform teams need version-controlled database schema change delivery with rollback and governance built in.
  • AI will accelerate software delivery, making unified delivery workflows increasingly important.

For more than a decade, Infrastructure as Code (IaC) has transformed how engineering organizations build and operate systems.

Infrastructure became programmable, provisioning became repeatable, and configuration became version-controlled.

Teams gained the ability to automate environment creation, enforce policy consistently, and scale infrastructure operations far beyond what manual processes could support.

Yet one critical part of software delivery never fully made the same transition, the database.

As Mrina Sugosh, Senior Product Marketing Manager at Harness, explained during a recent discussion on modern software delivery: infrastructure evolved into a declarative system while database delivery largely remained procedural.

That gap is becoming increasingly difficult to ignore.

Infrastructure Became Programmable. Database Changes Didn't.

Infrastructure as Code introduced a powerful operating model. Instead of manually configuring servers and cloud resources, teams could define desired state in code and let pipelines handle deployment. Tools like Terraform, OpenTofu, AWS CloudFormation, AWS CDK, and Terragrunt let organizations standardize infrastructure management and retire the fragile, hand-run processes that came before.

Platform engineering itself emerged from this shift. Version-controlled infrastructure, reproducible environments, and codified policy became foundational capabilities for modern engineering organizations.

Databases followed a different path. Schema changes, migrations, rollback logic, and data management frequently stayed outside that same delivery framework. The result is a split operating model: infrastructure is automated, applications are automated, and database changes are still done by hand. That separation is where the risk lives.

The Hidden Gap in Modern Software Delivery

Modern systems are no longer simple applications running on servers. They're interconnected ecosystems of applications, databases, APIs, queues, caches, event systems, and infrastructure services, each one depending on the others behaving correctly.

Yet many organizations still deploy these components through separate workflows. A database engineer manages schema changes, a DevOps engineer manages infrastructure, an application team manages deployments, and success depends on those people coordinating rather than those systems coordinating.

Wyatt Munson, Product Education Engineer at Harness, described what that looks like in practice: sitting shoulder to shoulder with a software engineer during a deployment, one person ready to roll back the application and the other ready to roll back the database, both watching for the moment to click at the same time. It worked. But a release that hinges on two people and their timing isn't a delivery model that scales.

Why Database Delivery Is Fundamentally Different

Many organizations assume database delivery should behave like IaC, but the reality is more complicated. Infrastructure provisioning is generally additive and reconstructable: if a virtual machine fails, you recreate it; if a Kubernetes cluster is misconfigured, you rebuild it.

Database changes operate differently because they carry persistent business state. They represent years of accumulated data, application assumptions, indexing strategies, access patterns, and operational dependencies. A schema migration isn't provisioning infrastructure. It's modifying a live system, and even seemingly small changes can ripple outward:

  • Dropping a column removes information permanently.
  • Index changes affect query performance.
  • Schema migrations can impact application behavior.
  • Data migrations may create consistency issues across services.

As Munson put it: "At the end of the day, it's the data that's the most important." Losing infrastructure is disruptive. Losing data is catastrophic.

The GitHub Incident That Exposed the Problem

The risks of database delivery aren't theoretical. One example discussed during the webinar was a GitHub production database migration. A migration removed a column believed to be unused, but parts of the application still referenced that column through a separate ORM path. After the change deployed, GitHub saw elevated error rates across pull requests, push operations, notifications, webhooks, and API traffic.

The failure wasn't really the migration itself. It was that the database change and the application that depended on it were validated separately rather than together. The migration was checked as a migration and the application was checked as an application, but the two were never exercised as one system before the change reached production. So the dependency stayed invisible until it broke in front of customers.

This is the gap a unified delivery model is built to close, and it closes it in two places:

  1. Catch it in pre-prod. Had the schema change and the application deployed together into a production-like environment, spun up on demand with Infrastructure as Code, the same errors that surfaced in production would have shown up there first, against real application behavior, where they cost nothing.
  2. Gate it before prod. A destructive change like dropping a production column should pass through a policy gate before it ever reaches production, held for explicit review and ideally backed by proof that it cleared QA without breaking anything.

Three Requirements for Modern Database Delivery

1. Version Control Database Changes

Database changes should be managed like application code, through version control and GitOps. That gives every change traceability, auditability, and a documented history: who made it, why, and when it shipped. The same properties that make application code reviewable and repeatable apply just as well to a schema migration.

2. Automate Validation and Rollback

Database delivery needs more than deployment automation. Before a change reaches production it should go through:

  • Validation against a realistic environment, so problems surface in pre-prod, not prod.
  • Schema and migration testing as part of the pipeline.
  • Environment promotion, the same staged path application code follows.
  • A defined reverse path: a reviewed rollback where the change can be cleanly undone, a tested forward-fix where it can't.

The goal is to remove uncertainty before a change ships, not to rely on an emergency undo after it's already in production.

3. Unify Delivery Workflows

The biggest opportunity is bringing infrastructure, application, and database delivery into a single operational framework. Instead of coordinating separate workflows by hand, platform teams orchestrate them through one pipeline, so application deployment, infrastructure provisioning, and database migration run as a single coordinated motion, governed consistently rather than stitched together by hand.

From Infrastructure as Code to Delivery as Code

The next phase of platform engineering extends the code-driven model beyond infrastructure to delivery itself. Call it Delivery as Code: the principles that made infrastructure programmable, applied to how every change ships, databases included.

In practice that means three things.

Database Pipelines

Database changes move through controlled promotion workflows rather than ad hoc scripts, so each one is reviewed, tested, and promoted environment to environment like application code. 

Policy Enforcement

Governance gets codified through policy engines such as Open Policy Agent, so the rules that used to live in someone's head become enforceable at the pipeline:

  • No dropping production tables
  • No violating naming standards
  • No deploying unapproved schema changes to prod

AI-Assisted Operations

AI begins to absorb the repetitive operational work, helping draft migration definitions and validation checks so engineers spend less time on boilerplate and more on the changes that actually need judgment.

The goal isn't replacing engineers. It's removing the repetitive operational toil so they can focus on higher-value work.

Building a Unified Delivery Platform

Platform teams are facing a new reality. AI-generated code is increasing development velocity dramatically, and more changes are entering delivery systems than ever before. When application deployment is automated but database delivery stays manual, the database becomes the bottleneck, and the fix isn't more coordination meetings. It's a unified delivery model where:

  • Infrastructure changes are version-controlled.
  • Database changes are version-controlled.
  • Governance is codified.
  • Testing is automated.
  • Rollbacks are built into workflows.

That's a delivery system that can scale alongside modern software development. Infrastructure as Code was the first step. Database DevOps is the next one.

Conclusion

Infrastructure as Code fundamentally changed software delivery by making infrastructure programmable.

But modern systems are more than infrastructure.

Applications, databases, policies, and delivery workflows must operate as a coordinated system.

As software delivery accelerates—particularly with the rise of AI-generated code—database delivery can no longer remain a separate operational process.

Platform teams that unify infrastructure, application, and database workflows will be better positioned to deliver software faster, safer, and with greater operational confidence.

Ready to see how Harness helps platform teams bring database delivery into the modern software delivery lifecycle? Explore Harness Database DevOps and Infrastructure as Code Management.

FAQ

What is Database DevOps?

Database DevOps applies DevOps principles to database changes, including version control, automation, testing, governance, and CI/CD workflows.

Why isn't Infrastructure as Code enough for databases?

Infrastructure as Code manages infrastructure state but does not address schema changes, data migrations, rollback workflows, or database governance.

Why can database changes be riskier than infrastructure changes?

Database changes modify persistent production data. Unlike infrastructure resources, databases often cannot be recreated without business impact.

How does Database DevOps improve software delivery?

It enables automated testing, version-controlled changes, rollback capabilities, and coordinated application and database deployments.

What role does GitOps play in database delivery?

GitOps provides version control, auditability, and workflow automation for database schema changes and migration management.

Can Harness DB DevOps be integrated into CI/CD pipelines?

Yes. Database DevOps integrates natively with Harness Continuous Delivery, so schema management, validation, and rollback run as steps in the same pipeline as your application deployments. If you run a different CI/CD tool, those same capabilities can be invoked from your existing pipelines instead.

How does Harness AI help database delivery?

Harness has an AI powered schema authoring capability, which can assist with migration generation, so engineers spend less time on boilerplate and more on the changes that need real judgment. Governance and approval controls stay in place regardless of how a change was authored.

← Previous:
Next: →

Related Resources

Database DevOps Gets Native Flyway Support

Database DevOps

Database DevOps Gets Native Flyway Support

November 18, 2025

Animesh Pathak

+ more
Time to Read

Harness Database DevOps was built to make database delivery as automated, safe, and repeatable as application delivery. Historically, Liquibase was our primary migration engine. Today we’ve added Flyway support - an SQL-first, simple migration engine - to give teams more choice and better alignment with their existing workflows.

Why Flyway? Understanding Developer Needs

Teams differ: some prefer Liquibase’s structured changelogs (XML/YAML/JSON); others prefer Flyway’s versioned SQL scripts. Flyway’s minimalism and convention-over-configuration approach make it attractive for developers who want direct control over SQL. Adding Flyway is about enabling choice and reducing friction for teams that already rely on SQL based migrations.

How Harness Simplifies Database Migrations?

Harness integrates both engines into one platform so teams can use their preferred tool while retaining centralized governance, approvals, drift detection, automated rollbacks, and environment visibility. You can run Liquibase and Flyway side by side within the same pipeline, with consistent policy and audit controls.

From a technical point of view, Flyway’s power lies in its simplicity - but that also means its conventions matter. Below is a brief guide to the essentials: naming conventions, baselines, pending migrations, and success validation.

Key Concepts:

  • Naming convention: Flyway uses versioned filenames such as V1_init.sql, V2_add_users_table.sql.
    The V prefix, version number, and double underscore separate version and description. This defines execution order and ensures predictability.
  • Baseline: When integrating Flyway into an existing database, baselineVersion and baselineOnMigrate=true tell Flyway to treat the current schema as a known version.
  • Pending migrations: Flyway automatically detects migrations present in code but not yet applied.
  • Success validation: Every applied migration is logged in the flyway_schema_history table. 

Best Practices:

  • Use clear and consistent script names (V3__add_email_index.sql).
  • Keep each migration atomic - one logical change per script.
  • Commit migrations alongside code for version alignment.
  • Always baseline before onboarding an existing database.

Sample Harness Pipeline Step:

__wf_reserved_inherit
Flyway Apply Migration in Harness Database DevOps

Example File Structure:

Benefits of Multi-Engine Support

Flexibility: Teams pick the engine that matches their workflow.
Scalability: Enterprises with multiple database tools can onboard easily.
Governance: Centralized policies, approvals, and audits apply consistently.
Productivity: Developers focus on writing migrations - Harness handles execution, safety, and rollback automation.

__wf_reserved_inherit
Harness Unified Pipeline
__wf_reserved_inherit
Migration State Dashboard for Flyway

The Future of Database DevOps at Harness

Supporting Flyway alongside Liquibase marks a significant step toward tool-neutral Database DevOps Orchestration. Harness continues to focus on developer freedom and operational confidence.

Whether you prefer structured changelogs or raw SQL scripts, Harness provides a unified pipeline experience - bringing automation, policy control, and observability under one roof. Try Flyway support in your next pipeline and experience how Harness brings agility, safety, and choice to modern database delivery.

Contact a Harness expert

Building Governance, Auditability, and Visibility into Database DevOps

Database DevOps

Building Governance, Auditability, and Visibility into Database DevOps

April 13, 2026

Jesse Wang

+ more
Time to Read

Introduction: Governance Must Be Built Into Delivery

Database changes are inherently complex: coordinating schema updates, managing risk, and avoiding downtime all require care. Even when teams improve how they deliver those changes, governance often remains inconsistent, manual, and reactive.

In many environments, governance is treated as a separate layer around deployment. Policies are applied unevenly, approvals become bottlenecks, and audit evidence is assembled after the fact, creating gaps in enforcement and increasing operational risk.

Effective governance must be enforced as part of how changes are delivered. With Harness Database DevOps, governance is built directly into the deployment pipeline, where each change is evaluated against defined policies before execution based on context such as environment, database type, and deployment configuration.

Pre-Execution Governance with Policy-as-Code

The most effective way to enforce governance is to evaluate changes before they are applied.

With Harness, database changes are analyzed prior to execution using policies defined through Open Policy Agent (OPA). These policies evaluate the SQL being applied along with its context, including the target environment and database type.

__wf_reserved_inherit

Policies can enforce context-aware rules, such as restricting destructive operations in production while allowing flexibility in development environments. Governance can also be adapted by environment. For example, policies that block deployments in production can surface warnings in lower environments, allowing issues to be identified and addressed earlier.

Because policies are defined as code, they can be versioned, reviewed, and updated alongside application and database changes. This ensures governance is applied consistently across teams and environments without relying on manual enforcement. Harness policies are applied across databases and migration tools, allowing teams to define policies once and enforce them consistently regardless of toolchain.

Governance as a System: Process and Consistency Across Environments

Effective governance extends beyond evaluating individual changes to ensuring that deployments follow the correct process.

Harness enforces this through pipeline-level controls, such as requiring changes to progress through defined environments and applying approvals where needed. These controls ensure that database changes follow consistent promotion paths, such as progressing from development to staging to production.

Governance is applied consistently even in complex environments where multiple teams use different database change tools or databases. Harness provides unified visibility and governance across tools such as Flyway and Liquibase, allowing policies to be defined once and enforced consistently regardless of the underlying toolchain.

By combining policy enforcement with structured workflows, teams can maintain control over how changes are delivered while reducing reliance on ad hoc reviews and manual coordination.

Auditability: Proving Enforcement and Change History

Harness provides a complete record of database activity across environments, including what changes were deployed, how they were executed, and who approved them.

In addition to change history, Harness maintains an audit trail of configuration changes to pipelines, policies, and governance settings. This allows teams to demonstrate that governance controls were consistently applied during a given period, simplifying audits by reducing the need to manually reconstruct evidence for each deployment.

Visibility Across Environments: Preventing Drift

Harness provides centralized visibility into database changes across environments, allowing teams to see what has been deployed where and when.

__wf_reserved_inherit

This visibility, combined with enforced deployment workflows, prevents cross-environment drift. Reporting and customizable dashboards extend this further, enabling teams to analyze delivery performance using metrics such as lead time and to track database changes as part of the broader software delivery process.

When used alongside Harness CD, teams can also view combined metrics across application and database changes, providing a more complete picture of delivery outcomes.

Conclusion: Governance That Scales With Delivery

Governance enforced before execution, defined as code, and applied consistently enables both control and scalability. But don’t take our word for it, just ask our customers.

Athena Health: “Harness gave us a truly out-of-the-box solution with features we couldn’t get from Liquibase Pro or a homegrown approach. We saved months of engineering effort and got more for less, with better governance, smarter change orchestration, and a clearer understanding of database state across teams and environments.”

By embedding governance directly into the delivery pipeline, teams can reduce manual oversight while improving compliance, consistency, and delivery speed.

Improving Liquibase Developer Experience with Harness Database DevOps Automated Change Generation

Database DevOps

Improving Liquibase Developer Experience with Harness Database DevOps Automated Change Generation

July 31, 2025

Stephen Atwell

+ more
Time to Read

This blog discusses how Harness Database DevOps can automate, govern, and deliver database schema changes safely, without having to manually author your database change.

Introduction

Adopting DevOps best practices for databases is critical for many organizations. With Harness Database DevOps, you can define, test, and govern database schema changes just like application code—automating the entire workflow from authoring to production while ensuring traceability and compliance. But we can do more–we can help your developers write their database change in the first place.

In this blog, we'll walk through a concrete example, using YAML configuration and a real pipeline, to show how Harness empowers teams to:

  • Automatically generate database changes using snapshots and diffs
  • Enforce governance before changes move beyond the authoring environment
  • Ensure consistency across environments via CI/CD using a GitOps Workflow

📽️ Companion Demo Video

To see this workflow in action, watch the companion demo:

In the demo, the pipeline captures changes, specifically adding a new column and index, and propagates those changes via Git before triggering further automated CI/CD, including rollback validation and governance.

Development teams adopting Liquibase for database continuous delivery can accelerate and standardize changeset authoring by leveraging Harness Database DevOps. By enabling developers to generate their changes by diffing DB environments, they no longer need to write SQL or YAML. This provides the benefits of state-based migrations and the benefits of script based migrations at the same time. They can define the desired state of the database in an authoring environment and automatically generate the changes to get there.

Automated Authoring: Step-by-Step with Harness Pipelines

1. Sync Development and Authoring Environments

The workflow starts by ensuring that your development and authoring environments are in sync with git, guaranteeing a clean baseline for change capture. The pipeline ensures the development environment reflects the current git state before capturing a new authoring snapshot. This allows developers to use their environment of choice—such as database UI tools—for schema design. To do this, we just run the apply step for the environment.

2. Take an Authoring Snapshot

Harness uses the LiquibaseCommand step to snapshot the current schema in the authoring environment:

- step:

    type: LiquibaseCommand

    name: Authoring Schema Snapshot

    identifier: snapshot_authoring

    spec:

      connectorRef: account.harnessImage

      command: snapshot

      resources:

        limits:

          memory: 2Gi

          cpu: "1"

      settings:

        output-file: mySnapshot.json

        snapshot-format: json

        dbSchema: pipeline_authored

        dbInstance: authoring

        excludeChangeLogFile: true

      timeout: 10m

      contextType: Pipeline

3. Generate a Diff Changelog

Next, the pipeline diffs the snapshot against the development database, generating a Liquibase YAML changelog (diff.yaml) that describes all the changes made in the authoring environment. Again, this uses the liquibase command step.:

- step:

    type: LiquibaseCommand

    name: Diff as Changelog

    identifier: diff_dev_as_changelog

    spec:

      connectorRef: account.harnessImage

      command: diff-changelog

      resources:

        limits:

          memory: 2Gi

          cpu: "1"

      settings:

        reference-url: offline:mssql?snapshot=mySnapshot.json

        author: <+pipeline.variables.email>

        label-filter: <+pipeline.variables.ticket_id>

        generate-changeset-created-values: "true"

        generated-changeset-ids-contains-description: "true"

        changelog-file: diff.yaml

        dbSchema: pipeline_authored

        dbInstance: development

        excludeChangeLogFile: true

      timeout: 10m

      when:

        stageStatus: Success

4. Merge Diff Changelog with the Central Changelog Using yq

Your git changelog should include all changes ever deployed, so the pipeline merges the auto-generated diff.yaml into the master changelog with a Run step that uses yq for structured YAML manipulation. This shell script also echoes only the new changesets to the log for the user to view.

- step:

    type: Run

    name: Output and Merge

    identifier: Output_and_merge

    spec:

      connectorRef: Dockerhub

      image: mikefarah/yq:4.45.4

      shell: Sh

      command: |

        # Optionally annotate changesets

        yq '.databaseChangeLog.[].changeSet.comment = "<+pipeline.variables.comment>" | .databaseChangeLog.[] |= .changeSet.id = "<+pipeline.variables.ticket_id>-"+(path | .[-1])' diff.yaml > diff-comments.yaml

        # Merge new changesets into the main changelog

        yq -i 'load("diff-comments.yaml") as $d2 | .databaseChangeLog += $d2.databaseChangeLog' dbops/ensure_dev_matches_git/changelogs/pipeline-authored/changelog.yml

        # Output the merged changelog (for transparency/logging)

        cat dbops/ensure_dev_matches_git/changelogs/pipeline-authored/changelog.yml

5. Commit to Git

Once merged, the pipeline commits the updated changelog to your Git repository. 

- step:

    type: Run

    name: Commit to Git

    identifier: Commit_to_git

    spec:

      connectorRef: Dockerhub

      image: alpine/git

      shell: Sh

      command: |

        cd dbops/ensure_dev_matches_git

        git config --global user.email "<+pipeline.variables.email>"

        git config --global user.name "Harness Pipeline"

        git add changelogs/pipeline-authored/changelog.yml

        git commit -m "Automated changelog update for ticket <+pipeline.variables.ticket_id>"

        git push

This push kicks off further CI/CD workflows for deployment, rollback testing, and integration validation in the development environment. The git repo is structured using a different branch for each environment, so promoting through staging to prod is accomplished by merging PRs.

Enforcing Database Change Policies

To ensure regulatory and organizational compliance, teams can automatically enforce their policies at deployment time. The demo features an example of a policy being violated, and fixing the change to meet it. The policy given in the demo is shown below, and it enforces a particular naming convention for indexes.

Example: SQL Index Naming Convention Policy

package db_sql

deny[msg] {

  some l

  sql := lower(input.sqlStatements[l])

  regex.match(`(?i)create\s+(NonClustered\s+)?index\s+.*`, sql)

  matches := regex.find_all_string_submatch_n(`(?i)create\s+(NonClustered\s+)?index\s+([^\s]+)\s+ON\s+([^\s(]+)\s?\(\[?([^])]+)+\]?\);`, sql,-1)[0]

  idx_name := matches[2]

  table_name := matches[3]

  column_names := strings.replace_n({" ": "_",",": "__"},matches[4])

  expected_index_name := concat("_",["idx",table_name,column_names])

  idx_name != expected_index_name

  msg := sprintf("Index creation does not follow naming convention.\n SQL: '%s'\n expected index name: '%s'", [sql,expected_index_name])

}

This policy automatically detects and blocks non-compliant index names in developer-authored SQL.

In the demo, a policy violation appears if a developer’s generated index (e.g., person_job_title_idx) doesn’t match the convention.

Conclusion

Harness Database DevOps amplifies Liquibase’s value by automating changelog authoring, merge, git, deployment, and pipeline orchestration—reducing human error, boosting speed, and ensuring every change is audit-ready and policy-compliant. Developers can focus on schema improvements, while automation and policy steps enable safe, scalable delivery.

Ready to modernize your database CI/CD?

Learn more about how you can improve your developer experience for database changes  or  contact us to discuss your particular usecase.

Request a demo

Check out State of the Developer Experience 2024

Get Started

Get Started with Harness AI

Try the full platform free. No module restrictions, no credit card.

Jesse Wang
Product Marketing Manager
Jesse Wang is the Product Marketing Manager for Harness Database DevOps. A former full stack software engineer with go-to-market experience, he has worked with dozens of companies and spoken with countless developers on their DevOps modernization journeys.
jesse-wang
Jesse Wang