> For the complete documentation index, see [llms.txt](https://docs.cortex.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cortex.io/configure/gitops.md).

# GitOps for Cortex overview

Cortex supports a [GitOps approach](https://about.gitlab.com/topics/gitops/): instead of managing your catalog in the Cortex UI, you define it in code. Entities, Scorecards, and Workflows are described in descriptor files that live in your Git repository, and Cortex treats those files as the source of truth. This keeps the definition of a system in the same place as the system itself, so your catalog can evolve alongside the code it describes.

The GitOps model offers several benefits:

* Your metadata is version-controlled.
* The repository where your code lives is also the source of truth for information about it.
* You always own the data.
* You can track GitOps changes in GitOps logs.
  * Users must have the `View GitOps Logs` permission.

{% hint style="success" %}
Want to learn more? Check out the Cortex Academy course on [using GitOps](https://academy.cortex.io/courses/gitops-dq31).
{% endhint %}

## How GitOps works in Cortex

With GitOps, you manage entities, Scorecards, and Workflows with descriptor files that live in your Git repository. An entity descriptor, also called a Cortex YAML, describes an entity in your catalogs. You can keep each entity's descriptor in the repository it describes, or keep all of your definitions together in a single repository.

For Bitbucket, GitHub, and GitLab, Cortex checks for a `cortex.yaml` or `cortex.yml` file anywhere in the default branch, and processes any changes you push to that branch. If you keep all of your definitions in a single repository, Cortex checks for YAML files in the `.cortex` directory.

Cortex finds Scorecards and Workflows by location rather than by filename. Scorecard definitions are read from the `.cortex/scorecards` directory, and Workflow definitions from `.cortex/workflows`. For more information, refer to [Scorecards as code](/standardize/scorecards/scorecards-as-code.md) and [Workflows as code](/streamline/workflows/workflows-as-code.md).

{% hint style="success" %}
Cortex recommends storing `cortex.yaml` in the repository root or `basePath`.
{% endhint %}

If you turn on GitOps-based auto-archival, Cortex archives an entity when its descriptor file is deleted from the repository. Cortex checks for deleted files only, so moving a file doesn't archive the entity. For more information, refer to [Archiving entities automatically](/ingesting-data-into-cortex/entities-overview/entities/archiving-entities/auto-archive.md).

### **GitOps repository structure**

There are two ways to structure descriptor files in your Git repository.

**Option 1: One `cortex.yaml` per repository**

Each repository contains a `cortex.yaml` file, stored anywhere in the default branch. This is commonly used for a one-to-one mapping, where the repository represents its Cortex entity. It's supported for Bitbucket, GitHub, and GitLab.

For Azure DevOps, the `cortex.yaml` file must be stored at the root of the default branch. To work around this in unique cases, refer to [Using multiple source directories](/configure/gitops/using-gitops-for-cortex.md#using-multiple-source-directories).

**Option 2: A single repository for all descriptors**

All descriptor YAMLs are stored in one repository, under a `.cortex` directory, in the subdirectories `catalog`, `domains`, `teams`, `scorecards`, and `workflows`. This is supported for all Git providers.

* The `catalog` subdirectory contains services and custom entities.
* The `domains` subdirectory contains domains.
* The `teams` subdirectory contains teams.
* The `scorecards` subdirectory contains Scorecards as code.
* The `workflows` subdirectory contains Workflows as code.

The following example shows a single repository structure. Entity descriptor files are listed under subdirectories for `catalog`, `domains`, `teams`, `scorecards`, and `workflows`:

```
.
└── .cortex
    ├── catalog
    │   ├── database.yml
    │   ├── s3-bucket.yml
    │   ├── auth-service.yml
    │   ├── my-custom-entity.yml
    │   ├── events
    │   │   ├── event-router.yml
    │   │   └── event-archiver.yml
    │   └── payments
    │       ├── payment-api.yml
    │       └── payment-worker.yml
    ├── domains
    │   ├── billing-domain.yml
    │   └── health-domain.yml
    ├── teams
    │   ├── eng-team.yml
    │   └── platform
    │       └── sre-team.yml
    ├── scorecards
    │   ├── production-readiness.yml
    │   └── security.yml
    └── workflows
        ├── onboarding.yml
        └── incident-response.yml
```

Note the following:

* Catalogs cannot be created via GitOps—they can only be defined in the Cortex UI.
* The `catalog` subdirectory contains the YAML files for services and custom entities, regardless of which catalogs the services and custom entities are organized into.
  * For example, you might have created catalogs for `API` and `Library`, and those catalogs might contain services or custom entities. In your Git repository, those entities will appear in the `catalog` subdirectory.
* You can organize YAML files into subdirectories nested under any of the `catalog`, `domains`, `teams`, `scorecards`, and `workflows` subdirectories. Cortex searches each of these recursively, so it finds YAML files at any depth.&#x20;
  * For example, Cortex finds both `.cortex/catalog/payment-api.yaml` and `.cortex/catalog/events/payment-api.yaml`. Each of these directories must be directly inside `.cortex`, so Cortex doesn't find `.cortex/internal/catalog/payment-api.yaml`.
* Directory names must match exactly. Cortex only searches the `catalog`, `domains`, `teams`, `scorecards`, and `workflows` subdirectories, so similarly named directories such as `.cortex/catalog-pilot/` or `.cortex/catalog_audit/` are ignored.

### Switching from the Cortex UI to GitOps

Cortex's Git integrations parse entity descriptor files automatically, so switching to GitOps is straightforward.

Cortex recommends switching after Cortex has been broadly rolled out to your organization. Give developers a chance to explore Cortex in the UI first, and set a threshold for when your organization is ready to cut over. You don't have to move everything at once, since you can [enable GitOps for each entity type](/configure/gitops/using-gitops-for-cortex.md#step-1-disable-ui-editing) separately.

### Using both the UI and GitOps

You can mix UI and GitOps management, but the details differ depending on what you're managing.

**Entities**

You can combine the two approaches for an entity type by enabling UI editing and disabling UI importing. New entities are then created through GitOps, but you edit them in the Cortex UI. Cortex doesn't process edits you make through GitOps, so the UI becomes the source of truth for changes:

1. From the main sidebar, click your avatar in the bottom-left corner.
2. Select **Settings**.
3. In Settings menu, locate the **Workspace** section, then select **GitOps**.
4. From the **Entities** tab, scroll to the **Options by type** section.
5. Toggle on **Enable UI editing for new entity types**.
6. Ensure that **Enable UI importing for new entity types** is toggled off.

**Workflows**

GitOps editing applies only to Workflows that are backed by a YAML file, so you can manage some Workflows through GitOps and others through the UI at the same time. You can still create and delete Workflows in the UI, and you can still edit any Workflow that isn't managed through GitOps.

**Scorecards**

When you enable GitOps editing for Scorecards, you can't edit any Scorecard in the UI, including Scorecards you originally created there. All edits must happen in the YAML file in your Git repository. You can still create and delete Scorecards in the UI.
