> For the complete documentation index, see [llms.txt](https://developer.harness.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.harness.io/database-devops/use-db-devops/structure-git-repository/environment-by-branch.md).

# Environment by Branch in Harness Database DevOps

Harness Database DevOps supports managing database changes using **environment-specific branches**. This approach allows you to maintain different configurations for development, staging, and production environments directly in your Git repository.

### Why use environment branches in Harness Database DevOps? <a href="#why-use-environment-branches-in-harness-database-devops" id="why-use-environment-branches-in-harness-database-devops"></a>

Here are several reasons why teams opt for a branch-per-environment strategy:

* **Consistency with application deployment**: If you are already managing app deployments using environment-specific branches, aligning your DB changes keeps both layers synchronized.
* **Environment-Specific Configurations**: Maintain isolated configurations or schema changes for dev, staging, and production environments.
* **Controlled Progression**: Promote and test changes in lower environments before merging them into production.
* **Audit Trail**: Each branch maintains a commit history that improves traceability and accountability for schema changes.

### What are the tradeoffs of branch per environment? <a href="#what-are-the-tradeoffs-of-branch-per-environment" id="what-are-the-tradeoffs-of-branch-per-environment"></a>

While beneficial, this approach introduces some complexity:

* **Increased Complexity**: Managing multiple branches requires rigorous Git hygiene.
* **Potential for Drift**: Without strict coordination, environments can diverge.
* **Merge Conflicts**: More branches = more chances for conflict.
* **Overhead**: Requires additional team effort to maintain branches and reviews.
* **Unintentional promotion of dev-only changes**: If you are managing dev/staging-only changes (like test tables or mock data), they may unintentionally get merged into higher environments.

{% hint style="info" %}
**Recommendation**: Use the `context` field on the database instance to restrict execution, even when the change exists in the branch. You can adopt this model if your **application deployment already follows a branch-per-environment** structure, ensuring consistency across the stack.
{% endhint %}

### How to configure <a href="#how-to-configure" id="how-to-configure"></a>

Follow these steps to configure environment-based deployments in Harness Database DevOps:

#### 1. Set up your Git branches <a href="#id-1-set-up-your-git-branches" id="id-1-set-up-your-git-branches"></a>

Create separate branches in your Git repo for each environment: `development`, `staging`, `production`, etc.

#### 2. Define schema configuration per branch <a href="#id-2-define-schema-configuration-per-branch" id="id-2-define-schema-configuration-per-branch"></a>

Create a DB Schema definition for each environment branch.

* Go to **Database DevOps** and click **Add DB Schema**. ![Create a New Schema](/files/UwKis7ITK96VUYaWYl5S)

#### 3. Create a database instance <a href="#id-3-create-a-database-instance" id="id-3-create-a-database-instance"></a>

Create a separate database instance for each target environment.

1. Select the **Database Schema** and click **Add DB Instances** in Harness.
2. Create a new instance for each environment.
3. Attach the appropriate JDBC connector and context labels. ![Create a New Database Instance](/files/ycjWuCgpORH9qIfGZIe7)

#### 4. Configure a Git trigger <a href="#id-4-configure-a-git-trigger" id="id-4-configure-a-git-trigger"></a>

Set up a trigger for each branch so Harness deploys automatically when changes are merged.

1. Navigate to **Pipeline Studio > Triggers**. ![Pipeline Triggers](/files/NnN4EU4hM0oyyVlStUVZ)
2. Add a new **Git trigger** that listens for changes on each environment branch.

* For example, `dev` trigger watches `dev` branch merges.

3. Select the **Git repository** and specify the **Event** type (e.g., `Push`). ![Example Git Trigger Configuration](/files/HFfGg3RDQcwy03QvVk1j)
4. Click on Continue and Configure the conditions for the trigger:

   * **Branch Name**: Specify the branch to watch (e.g., `dev`, `staging`, `prod`).
   * **Changed Files**: Optionally, specify file patterns to filter changes (e.g., `schemas/*.sql`).

   ![Example Trigger Conditions](/files/q0NcekgDVEBWV9W8CG4L)
5. Enter the Pipeline Inputs that the trigger will use:

   * **Trigger Branch**: This is the branch that the trigger will monitor.
   * **Rollback Tag (Optional)**: Optionally, specify a tag to use for rollbacks.
   * **Tag (Optional)**: Optionally, specify a tag to apply to the deployment.

   ![Example Trigger Inputs](/files/nAAvTBaX0nr1FsP3E52q)

{% hint style="info" %}
Go to [How to configure Git triggers in Harness](/harness-ai/use-harness-platform/triggers/tutorial-cd-trigger.md) to set up branch-based triggers for each environment.
{% endhint %}

#### 5. Design your pipeline <a href="#id-5-design-your-pipeline" id="id-5-design-your-pipeline"></a>

Build a pipeline that applies the correct schema for each environment branch.

1. In **Pipelines**, create a pipeline that includes a `DBSchemaApply` step.
2. Set up the pipeline to:

* Deploy using the associated schema and DB instance.
* Apply only the changes in that branch.
* Optionally include approvals, rollback, and verification steps.

{% tabs %}
{% tab title="Visual Overview" %}
![Pipeline Design](/files/TzXi4q2Xxxmvdx06u1Zb)
{% endtab %}

{% tab title="YAML Overview" %}

```yml
pipeline:
  identifier: Module_Demo_Betamultienv
  projectIdentifier: default_project
  orgIdentifier: default
  stages:
    - stage:
        identifier: DB_Migrate
        type: Custom
        name: DB Migrate
        description: "Deploy DB Schema to multiple environments"
        spec:
          execution:
            steps:
              - parallel:
                  - stepGroup:
                      identifier: Liquibase_Update_staging
                      name: Update Staging
                      steps:
                        - parallel:
                            - step:
                                identifier: Apply_To_Staging
                                type: DBSchemaApply
                                name: Apply To Staging
                                spec:
                                  connectorRef: account.harnessImage
                                  resources:
                                    limits:
                                      memory: 500Mi
                                      cpu: 400m
                                  dbSchema: db_devops_demo
                                  dbInstance: staging
                                  tag: <+stage.variables.tag>
                                timeout: 10m
                                when:
                                  stageStatus: Success
                                  condition: <+pipeline.variables.trigger_branch>
                                    == "staging"
                      stepGroupInfra:
                        type: KubernetesDirect
                        spec:
                          connectorRef: db
                          namespace: harness-delegate-ng
                          initTimeout: 10m
                      when:
                        stageStatus: Success
                        condition: <+stage.variables.rollback_tag> == "" || <+stage.variables.rollback_tag>
                          ==null
                  - stepGroup:
                      identifier: Liquibase_Update_prod_us
                      name: Update Production-us
                      steps:
                        - step:
                            identifier: Apply_to_Production_us
                            type: DBSchemaApply
                            name: Apply to Production-us
                            spec:
                              connectorRef: account.harnessImage
                              resources:
                                limits:
                                  memory: 500Mi
                                  cpu: 400m
                              dbSchema: db_devops_demo
                              dbInstance: authoring
                              tag: <+stage.variables.tag>
                            timeout: 10m
                            when:
                              stageStatus: Success
                              condition: <+pipeline.variables.trigger_branch> == "staging"
                      stepGroupInfra:
                        type: KubernetesDirect
                        spec:
                          connectorRef: db
                          namespace: harness-delegate-ng
                          initTimeout: 10m
                      when:
                        stageStatus: Success
                        condition: <+stage.variables.rollback_tag> == "" || <+stage.variables.rollback_tag>
                          ==null
                      delegateSelectors:
                        - cockroachdb-delegate
            rollbackSteps: []
          serviceDependencies: []
        tags: {}
        failureStrategies:
          - onFailure:
              errors: []
              action:
                type: Abort
        variables:
          - name: rollback_tag
            type: String
            description: Specify this if you wish to rollback to the particular tag
            required: false
            value: <+input>
          - name: branch
            type: String
            description: ""
            required: true
            value: main
          - name: changelogfile
            type: String
            description: ""
            required: false
            value: example-changelog.yaml
          - name: tag
            type: String
            description: Argument to Liquibase Tag Command
            required: false
            value: <+trigger.commitSha>
          - name: server_jdbc_url
            type: String
            description: JDBC URL of the target server
            required: false
            value: <+pipeline.variables.server_jdbc_url>
          - name: arch
            type: String
            description: ""
            required: false
            value: latest
        delegateSelectors:
          - cockroachdb-delegate
        when:
          pipelineStatus: Success
  tags:
    demo: ""
  variables:
    - name: server_jdbc_url
      type: String
      description: ""
      required: false
      value: jdbc:sqlserver://<+variable.sql_server_ip_address>;database=MyTestDataBase;trustServerCertificate=true
    - name: user
      type: String
      description: ""
      required: false
      value: <+secrets.getValue("mysql_sa_user")>
    - name: trigger_branch
      type: String
      description: ""
      required: true
      value: <+trigger.targetBranch>
  name: Module Demo - Beta-multi-env
```

{% endtab %}
{% endtabs %}

#### 6. Manage promotion between environments <a href="#id-6-manage-promotion-between-environments" id="id-6-manage-promotion-between-environments"></a>

Promote changes between environments using Git pull requests.

1. Use Git pull requests to promote changes between branches, for example `dev` to `staging` or `staging` to `prod`.
2. Harness will auto-detect the merged changes via the trigger and deploy accordingly.

### Conclusion <a href="#conclusion" id="conclusion"></a>

Deploying by environment branches in Harness Database DevOps provides alignment with traditional application deployment strategies and gives teams clear separation of concerns. While it introduces more Git management overhead, it enables safer promotion paths and more isolated testing.

Ensure you manage drift carefully, use [contexts](/database-devops/use-db-devops/reference/glossary/context.md) to limit dev-only changes, and maintain strong PR discipline when promoting between branches.

### Next steps <a href="#next-steps" id="next-steps"></a>

* Go to [Trunk-based development](/database-devops/use-db-devops/structure-git-repository/trunk-based-development.md) to compare the single-branch strategy and choose the right approach for your team.
* Go to [Create a pipeline in Database DevOps](/database-devops/use-db-devops/deployment-pipeline-configuration/create-a-pipeline.md) to build your first environment-based database pipeline.
* Go to [Automated rollback for database schemas](/database-devops/use-db-devops/deployment-pipeline-configuration/rollback-and-failure-strategies/rollback-for-database-schemas.md) to configure rollback strategies for failed deployments.
