> 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/continuous-delivery/use-gitops/gitops-entities/service/gitops-vs-cd-service.md).

# GitOps vs CD Services

Understand how GitOps services differ from traditional Continuous Delivery services in Harness

{% hint style="info" %}
This feature is in Beta[^1] and requires enablement. [View all early access features.](/release-notes/features.md)

{% @harness-feature-flag-access/request-feature-flag-access module="continuous-delivery" pagePath="continuous-delivery/use-gitops/gitops-entities/service/gitops-vs-cd-service" featureFlags="%5B%7B%22name%22%3A%22Merge%20GitOps%20and%20Kubernetes%20CD%20services%22%2C%22key%22%3A%22CDS\_GITOPS\_MERGE\_K8S\_SERVICES%22%2C%22status%22%3A%22BETA%22%2C%22description%22%3A%22Removes%20the%20GitOps%20checkbox%20and%20makes%20the%20gitOpsEnabled%20YAML%20field%20redundant%20so%20the%20same%20service%20can%20be%20used%20in%20both%20CD%20stages%20and%20GitOps%20stages.%22%7D%5D" %}
{% endhint %}

A **service** in Harness defines what you are deploying, typically a microservice, application, or workload. Every service bundles the configuration required to deploy your software across environments such as development, staging, or production.

Every service includes the following components:

* **Service Definition**: Specifies the deployment type (Kubernetes, Helm, Serverless, and related types).
* **Manifests**: Point to deployment specs such as Kubernetes manifests and Helm charts.
* **Artifacts**: Reference container images, packages, or binaries to deploy.
* **Variables**: Store configuration values specific to the service.
* **Config Files**: Include application config files when needed.

Services are reusable, so you can deploy the same definition to multiple environments using different pipelines and stages. This topic compares the traditional Continuous Delivery (CD) push model with the GitOps pull model for Kubernetes services.

***

## What you will learn from this topic

* How [traditional CD services](#two-approaches-for-deploying-kubernetes-services) work with a push-based workflow
* How [GitOps services](#two-approaches-for-deploying-kubernetes-services) work with a pull-based, Git-first workflow
* How to [compare pipeline steps](#comparing-pipeline-steps-cd-vs-gitops) between CD and GitOps workflows
* How to [choose the right model](#choosing-the-right-model) for your deployment scenario

***

## Before you begin

This topic assumes the following knowledge:

* **Harness services**: Familiarity with how services define manifests and artifacts. Go to [Create services](/continuous-delivery/use-continuous-delivery/cd-building-blocks/services/create-services.md) to create a Continuous Delivery service.
* **GitOps basics**: Familiarity with GitOps Agents and sync. Go to [Create a GitOps service](/continuous-delivery/use-gitops/gitops-entities/service/service.md) to configure a GitOps service.
* **PR pipelines (GitOps path)**: Familiarity with pull-request driven updates. Go to [PR pipeline basics](/continuous-delivery/use-gitops/pr-pipelines/pr-pipelines-basics.md) to review the GitOps PR pipeline flow.

***

## Two approaches for deploying Kubernetes services

Harness supports two main models for deploying Kubernetes services, each suited to different operational needs.

### Traditional Continuous Delivery

Continuous Delivery is a push-based approach. When you execute a pipeline, the Harness Delegate fetches manifests and artifacts, then applies them directly to your Kubernetes cluster. You control each deployment step, timing, and strategy (rolling update, canary, blue-green, and related strategies).

### GitOps

GitOps uses a pull-based workflow, where your Git repository is the source of truth for every deployment. Instead of pipelines pushing changes directly to Kubernetes, you update configuration files in Git (for example, through pull requests). A GitOps Agent (based on Argo CD) watches for changes in Git and continuously syncs your cluster to reflect the desired state.

Key GitOps principles include the following:

* **Declarative**: Everything is described and managed through configuration in Git.
* **Versioned and immutable**: Git histories provide complete audit trails.
* **Pulled automatically**: Agents fetch the desired state from Git and make sure your cluster matches.
* **Continuously reconciled**: Any drift from the Git state is auto-corrected by the agent.

Whether a service is used for GitOps or traditional Continuous Delivery depends on which fields you populate in the service definition and which pipeline stages you use it in.

{% hint style="info" %}
**Merge GitOps and Kubernetes CD services**

When the `CDS_GITOPS_MERGE_K8S_SERVICES` feature flag is enabled, the GitOps checkbox is removed and the `gitOpsEnabled` YAML field becomes redundant. The same service can be used in both Continuous Delivery stages and GitOps stages. You are responsible for populating the relevant fields for your use case (for example, a Release Repository for the Update Release Repo step, or an App Set Reference for Fetch Linked Apps). Contact [Harness Support](mailto:support@harness.io) to enable the flag.
{% endhint %}

Without the feature flag, the choice between GitOps and Continuous Delivery is permanent. You choose between them at service creation time and cannot change it afterwards.

{% hint style="info" %}
**Related GitOps reading**

Go to the following Harness resources for additional GitOps background:

* [Harness GitOps product overview](https://www.harness.io/products/continuous-delivery/harness-gitops)
* [GitOps vs. DevOps: What's the Difference?](https://www.harness.io/blog/gitops-vs-devops-whats-the-difference)
* [Complete Guide for GitOps on Kubernetes](https://www.harness.io/blog/complete-guide-for-gitops-on-kubernetes)
* [Top GitOps Benefits Explained](https://www.harness.io/blog/gitops-benefits)
  {% endhint %}

***

## How each deployment workflow works

The following examples show how each approach rolls out a new image version `v2.0.0`.

### Continuous Delivery service workflow (without GitOps)

Your service configuration can look like this:

```yaml
artifacts:
  primary:
    sources:
      - identifier: myapp
        type: DockerRegistry
        spec:
          imagePath: myorg/myapp
          tag: <+input>
```

Perform the following steps in a Continuous Delivery pipeline:

1. Start the Continuous Delivery pipeline.
2. Select the image tag `v2.0.0` when prompted.
3. The Harness Delegate applies the manifests, deploying `image: myorg/myapp:v2.0.0` to the cluster.

**Result**: The application updates immediately to version `v2.0.0`.

**Key trait**: Push-based. Harness acts directly to update your cluster.

### GitOps service workflow (with GitOps repository sources)

Your service configuration can look like this:

```yaml
manifests:
  - manifest:
      type: ReleaseRepo
      spec:
        store:
          spec:
            paths:
              - cluster-config/prod/config.json
```

Before the `config.json` update:

```json
{
  "imageTag": "v1.9.0"
}
```

Perform the following steps in a PR pipeline:

1. Run the PR pipeline.
2. Provide the new image tag `v2.0.0` as a variable.
3. The **Update Release Repo** step changes `config.json` to `"imageTag": "v2.0.0"` and raises a PR.
4. The PR is merged, either by a **Merge PR** step in the pipeline, or by authorized reviewers in your Git provider when you enable **Wait for PR merge** on the Update Release Repo step. With this option, the Harness step pauses and waits until an authorized user merges the PR in the Git system.
5. The Agent detects the change and syncs your application to match Git.

After update:

```json
{
  "imageTag": "v2.0.0"
}
```

**Result**: The application is updated after the Agent completes the sync.

**Key trait**: Pull-based. The agent syncs the cluster to the state defined in Git.

***

## Comparing pipeline steps: CD vs GitOps

The pipeline steps you build differ depending on which model you use.

### Continuous Delivery service steps

In traditional Continuous Delivery, pipeline steps interact directly with your cluster:

| Step                          | Purpose                                       |
| ----------------------------- | --------------------------------------------- |
| **K8s Rolling Deployment**    | Rolling update of your app                    |
| **K8s Canary Deployment**     | Deploy a canary for safe testing              |
| **K8s Blue Green Deployment** | Blue-green strategy for zero-downtime rollout |
| **K8s Apply**                 | Apply Kubernetes manifests                    |
| **K8s Scale**                 | Scale deployments up or down                  |
| **K8s Delete**                | Remove Kubernetes resources                   |

Example pipeline:

```yaml
execution:
  steps:
    - step:
        type: K8sRollingDeploy
        name: Rolling Deployment
        spec:
          skipDryRun: false
    - step:
        type: K8sApply
        name: Apply ConfigMap
        spec:
          filePaths:
            - configmap.yaml
```

### GitOps service steps (with GitOps repository sources)

GitOps pipelines manage changes through Git and rely on the agent to apply those updates.

| Step                    | Purpose                                                                                                                       |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Update Release Repo** | Update config files in Git and create a pull request. Optionally wait for authorized users to merge the PR in the Git system. |
| **Merge PR**            | Merge the pull request from within the pipeline (not needed when using Wait for PR merge)                                     |
| **Fetch Linked Apps**   | Get the relevant GitOps applications                                                                                          |
| **GitOps Sync**         | Manually trigger agent sync when needed                                                                                       |
| **Update GitOps App**   | Change app config such as Helm overrides                                                                                      |
| **GitOps Rollback**     | Roll back to a previous application deployment revision                                                                       |
| **Revert PR**           | Roll back by reverting a commit and opening a new PR                                                                          |

Example PR pipeline:

```yaml
execution:
  steps:
    - step:
        type: UpdateReleaseRepo
        name: Update Config
        spec:
          variables:
            - name: imageTag
              value: "v2.1.0"
            - name: replicas
              value: "5"
    - step:
        type: MergePR
        name: Merge Changes
        spec:
          mergeStrategy: squash
        identifier: MergePR_1
        timeout: 10m
    - step:
        type: FetchLinkedApps
        name: Get Applications
```

Bottom line:

* **Continuous Delivery pipelines** act directly on Kubernetes resources.
* **PR pipelines** update Git, and deployments happen when the agent detects changes.

***

## Choosing the right model

Use the following scenarios to decide which approach fits your workload.

### Use Continuous Delivery services when

Use Continuous Delivery services in these situations:

* You need immediate and explicit control over deployment timing and logic.
* Custom strategies such as canary and blue-green are essential.
* You must coordinate with external systems (migrations, API calls).
* Non-Kubernetes workloads or legacy apps are in play.
* Real-time deployment feedback is important.

**Example**: Deploying a monolithic application that needs a database migration, cache warming, and multiple manual approval steps.

### Use GitOps services when

Use GitOps services in these situations:

* You want all deployment config managed in Git for easy auditing.
* Automatic drift detection and correction matter.
* You are running multiple environments, kept in sync by files in Git.
* Active use of Git history and commit traceability is needed.
* You deploy microservices across many clusters with ApplicationSets.

**Example**: Managing microservices in development, staging, and production, each with distinct config files in Git, and letting the agent ensure clusters stay in sync.

***

## Summary: core differences

With the feature flag enabled, the same service can serve both models. The fields you populate determine the behavior:

| What changes           | Continuous Delivery workflow                                    | GitOps workflow                                                         |
| ---------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------- |
| **Manifest options**   | Add K8sManifest, Add Override File                              | Add Release Repo, Add App Set Reference (Deployment Repo is deprecated) |
| **Manifest target**    | Kubernetes resources (Deployment, Service, and related objects) | Git paths, config files, AppSet templates                               |
| **Artifact handling**  | Harness injects and deploys from pipeline                       | Git updated, agent deploys after sync                                   |
| **Pipeline steps**     | Kubernetes deployment steps                                     | PR steps (Update Repo, Merge PR, Fetch Apps)                            |
| **Deployment trigger** | Pipeline execution                                              | Merge to Git, agent detects and syncs                                   |
| **Speed**              | Immediate after pipeline runs                                   | Eventual, when agent syncs Git and cluster                              |
| **Control model**      | Push-based (Harness to cluster)                                 | Pull-based (agent from Git)                                             |

{% hint style="info" %}
**Deprecated Deployment Repo**

If your service still uses a Deployment Repository manifest, go to [Migrate Deployment Repo to Application Set references](/continuous-delivery/use-gitops/gitops-entities/service/migrate-deployment-repo-to-appset-references.md) to move to App Set references.
{% endhint %}

Key takeaway:

* **Continuous Delivery services** deploy directly to Kubernetes with each pipeline run.
* **GitOps services** update config in Git, and the agent syncs clusters to stay aligned.

***

## Next steps

* [Create a GitOps service](/continuous-delivery/use-gitops/gitops-entities/service/service.md): Configure a service for GitOps workflows.
* [Create a Continuous Delivery service](/continuous-delivery/use-continuous-delivery/cd-building-blocks/services/create-services.md): Create a service for push-based deployments.
* [PR pipeline basics](/continuous-delivery/use-gitops/pr-pipelines/pr-pipelines-basics.md): Build pipelines that update Git and sync through the agent.
* [Kubernetes services](/continuous-delivery/use-continuous-delivery/deploy-services-on-different-platforms/kubernetes/kubernetes-services.md): Review Kubernetes Continuous Delivery service configuration.

{% @harness-feedback/feedback %}

[^1]: Beta features are feature-complete but still being validated. Available on request.
