> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ankra.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Add-on Settings

> Configure sync policies, retry behaviour, health checks, and ignore rules for your add-ons.

<Note>
  Add-on settings control how ArgoCD manages the lifecycle of your deployed add-ons. These settings apply to both standalone add-ons and add-ons within stacks.
</Note>

## Overview

Every add-on deployed through Ankra is backed by an ArgoCD Application. The settings page lets you fine-tune how ArgoCD synchronizes, monitors, and recovers your add-on. You can configure these settings from:

* **Stack Builder** -- click any add-on and open the **Settings** tab
* **Standalone Add-ons** -- open the add-on and click **Settings**

Changes made in the Stack Builder are applied when you save the stack. Changes to standalone add-ons are applied to ArgoCD immediately.

***

## Settings Profiles

Profiles are pre-configured bundles of settings optimized for common scenarios. Select a profile to quickly apply recommended values, or choose **Custom** to configure each setting individually.

| Profile                 | Automated Sync | Auto Prune | Self Heal | Health Check | Revision Limit | Best For                                    |
| ----------------------- | :------------: | :--------: | :-------: | :----------: | :------------: | ------------------------------------------- |
| **Default**             |       On       |     On     |     On    |      Off     |       10       | Most add-ons                                |
| **Development**         |       On       |     On     |     On    |      Off     |        5       | Fast iteration, dev/staging clusters        |
| **Production Critical** |       Off      |     Off    |    Off    |      On      |       20       | Critical workloads requiring manual control |
| **Stateful**            |       On       |     Off    |     On    |      Off     |       10       | Databases, message queues, stateful apps    |

Changing any individual setting automatically switches the profile to **Custom**.

***

## Sync Policy

The sync policy determines how ArgoCD responds to changes in your Git repository and drift in your cluster.

### Automated Sync

When enabled, ArgoCD automatically syncs your add-on whenever changes are detected in Git. When disabled, you must trigger syncs manually.

### Auto Prune

When enabled alongside Automated Sync, ArgoCD automatically deletes Kubernetes resources that are no longer defined in Git. This keeps your cluster clean but means removing a resource from your stack will delete it from the cluster.

<Warning>
  Auto Prune can delete resources that were removed from your Git repository. Make sure you intend to remove them before enabling this option.
</Warning>

### Self Heal

When enabled alongside Automated Sync, ArgoCD automatically reverts any manual changes made directly to the cluster. If someone modifies a resource with `kubectl`, ArgoCD will detect the drift and restore the resource to match Git.

***

## Sync Options

Sync options are flags that control specific ArgoCD behaviors during synchronization. You can select multiple options.

| Option                            | Description                                                                                       |
| --------------------------------- | ------------------------------------------------------------------------------------------------- |
| **Create Namespace**              | Automatically create the target namespace if it does not exist                                    |
| **Server-Side Apply**             | Use Kubernetes server-side apply instead of client-side. Recommended for large resources and CRDs |
| **Apply Out-of-Sync Only**        | Only apply resources that are out of sync, skipping unchanged resources. Reduces sync time        |
| **Respect Ignore Differences**    | Honor ignore difference rules during sync. Automatically enabled when ignore rules are present    |
| **Prune Propagation: Foreground** | Wait for dependent resources to be deleted before removing the parent                             |
| **Prune Propagation: Background** | Delete the parent immediately and let Kubernetes garbage-collect dependents                       |
| **Prune Propagation: Orphan**     | Remove the parent but leave dependent resources in place                                          |
| **Prune Last**                    | Prune resources only after all other sync operations complete                                     |
| **Replace**                       | Use `kubectl replace` instead of `kubectl apply`. Useful when apply fails due to field conflicts  |
| **Fail on Shared Resource**       | Fail the sync if a resource is already managed by another ArgoCD Application                      |

<Tip>
  **Server-Side Apply** and **Create Namespace** are enabled by default in most profiles. Server-Side Apply is recommended because it handles large objects and field conflicts better than client-side apply.
</Tip>

***

## Health & Revisions

### Strict Health Check

When enabled, ArgoCD requires **all** resources created by the add-on to report a healthy status before considering the deployment successful. This is useful for production-critical add-ons where partial deployments are unacceptable.

When disabled (default), ArgoCD considers the sync successful as soon as resources are applied, regardless of their health status.

### Revision History Limit

Controls how many previous application revisions ArgoCD retains (1--100). Higher values consume more storage but make it easier to audit changes and understand deployment history. The default is **10**.

***

## Retry Policy

The retry policy controls automatic retry behaviour when a sync operation fails.

| Field              | Description                                          | Default |
| ------------------ | ---------------------------------------------------- | ------- |
| **Retry Limit**    | Maximum number of retry attempts (0--100)            | 5       |
| **Backoff Factor** | Multiplier applied to delay between retries (1--10)  | 2       |
| **Initial Delay**  | Wait time before the first retry (e.g. `5s`, `1m`)   | 5s      |
| **Max Delay**      | Maximum wait time between retries (e.g. `3m`, `10m`) | 3m      |

Retries use exponential backoff: each retry waits longer than the previous one, up to the max delay. For example, with the defaults, retries happen at approximately 5s, 10s, 20s, 40s, and 80s (capped at 3m).

***

## Sync Window

Sync windows restrict when ArgoCD is allowed to synchronize your add-on. This is useful for enforcing change-management policies, such as only allowing deployments during business hours or maintenance windows.

| Field        | Description                                    | Example                              |
| ------------ | ---------------------------------------------- | ------------------------------------ |
| **Schedule** | Cron expression defining when the window opens | `0 22 * * *` (daily at 10 PM)        |
| **Duration** | How long the window stays open                 | `1h`, `30m`, `2h`                    |
| **Timezone** | Timezone for the cron schedule                 | `UTC`, `Europe/Berlin`, `US/Eastern` |

When a sync window is active, ArgoCD will only sync during the defined window. Outside the window, changes accumulate in Git and are applied when the next window opens.

***

## Ignore Differences

Ignore Differences lets you tell ArgoCD to skip specific fields when comparing the desired state (Git) with the live state (cluster). This prevents false "OutOfSync" reports caused by fields that are mutated at runtime by Kubernetes controllers, webhooks, or operators.

### Why Ignore Differences?

ArgoCD continuously compares your Git repository with the live cluster state. When they differ, ArgoCD reports the resource as **OutOfSync**. However, some fields are legitimately modified after deployment:

* **Webhook controllers** inject `caBundle` values into webhook configurations
* **Kubernetes** assigns `clusterIP` to Services automatically
* **Operators** update status fields and annotations on custom resources
* **Controllers** like `kube-controller-manager` set default values on resources

Without ignore rules, these runtime mutations cause constant OutOfSync status, triggering unnecessary syncs (with auto-sync) or masking real configuration drift.

### Resource Selectors

Each ignore rule can be scoped to specific resources using optional selectors:

| Field         | Description               | Example                          |
| ------------- | ------------------------- | -------------------------------- |
| **Kind**      | Kubernetes resource kind  | `ValidatingWebhookConfiguration` |
| **Group**     | API group of the resource | `admissionregistration.k8s.io`   |
| **Name**      | Specific resource name    | `istio-validator-istio-system`   |
| **Namespace** | Namespace of the resource | `istio-system`                   |

All selectors are optional. Omitting a selector means the rule matches all values for that field. For example, a rule with only `Kind: Service` and no name or namespace applies to every Service in the add-on.

### Matching Methods

Each rule must include at least one of the following methods to specify which fields to ignore.

#### JSON Pointers

JSON Pointers ([RFC 6901](https://datatracker.ietf.org/doc/html/rfc6901)) are path-based references into a JSON document. They use `/` as a separator and numeric indices for arrays.

**Syntax:** `/path/to/field` or `/path/0/arrayElement`

**Examples:**

| Pointer                                                                   | What it targets                                      |
| ------------------------------------------------------------------------- | ---------------------------------------------------- |
| `/spec/clusterIP`                                                         | The `clusterIP` field on a Service                   |
| `/webhooks/0/clientConfig/caBundle`                                       | The `caBundle` of the first webhook                  |
| `/metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration` | An annotation (note: `/` in keys is escaped as `~1`) |
| `/status`                                                                 | The entire status subresource                        |

<Tip>
  Use JSON Pointers when you need to target a specific array index or a straightforward field path. They are simple and well-suited for most use cases.
</Tip>

#### JQ Path Expressions

JQ path expressions use the [jq](https://jqlang.github.io/jq/) query language syntax to target fields. They are more powerful than JSON Pointers and support wildcards and array iteration.

**Syntax:** `.path.to.field` or `.path[0].arrayElement`

**Examples:**

| Expression                                                                  | What it targets                                  |
| --------------------------------------------------------------------------- | ------------------------------------------------ |
| `.spec.clusterIP`                                                           | The `clusterIP` field on a Service               |
| `.webhooks[0].clientConfig.caBundle`                                        | The `caBundle` of the first webhook              |
| `.webhooks[].clientConfig.caBundle`                                         | The `caBundle` of **all** webhooks (wildcard)    |
| `.metadata.annotations["kubectl.kubernetes.io/last-applied-configuration"]` | An annotation with special characters in the key |
| `.status`                                                                   | The entire status subresource                    |

<Tip>
  Use JQ Path Expressions when you need wildcards (e.g. `.webhooks[]` to match all array elements) or when targeting fields with special characters in their keys.
</Tip>

#### Managed Fields Managers

Instead of targeting specific fields, you can ignore all fields managed by a particular controller or process. Kubernetes tracks which controller "owns" each field through its [Server-Side Apply](https://kubernetes.io/docs/reference/using-api/server-side-apply/) mechanism.

**Examples:**

| Manager                              | What it covers                                                                        |
| ------------------------------------ | ------------------------------------------------------------------------------------- |
| `kube-controller-manager`            | Fields set by the Kubernetes controller manager (e.g. default values, status updates) |
| `clusterrole-aggregation-controller` | Aggregated rules on ClusterRoles                                                      |
| `cert-manager-cainjector`            | CA bundle fields injected by cert-manager                                             |

<Warning>
  Managed Fields Managers is the broadest matching method. It ignores **all** fields owned by that manager, which may include fields you want ArgoCD to track. Use it only when you trust the controller's mutations entirely.
</Warning>

### Common Examples

<AccordionGroup>
  <Accordion title="Webhook caBundle (ValidatingWebhookConfiguration)">
    Webhook controllers like cert-manager inject a `caBundle` into webhook configurations after deployment. This is one of the most common causes of false OutOfSync status.

    | Field            | Value                               |
    | ---------------- | ----------------------------------- |
    | **Kind**         | `ValidatingWebhookConfiguration`    |
    | **Group**        | `admissionregistration.k8s.io`      |
    | **JSON Pointer** | `/webhooks/0/clientConfig/caBundle` |

    Or to cover all webhooks in the configuration using JQ:

    | Field                  | Value                               |
    | ---------------------- | ----------------------------------- |
    | **Kind**               | `ValidatingWebhookConfiguration`    |
    | **Group**              | `admissionregistration.k8s.io`      |
    | **JQ Path Expression** | `.webhooks[].clientConfig.caBundle` |

    This also applies to `MutatingWebhookConfiguration` resources.
  </Accordion>

  <Accordion title="Service clusterIP and clusterIPs">
    Kubernetes assigns `clusterIP` and `clusterIPs` automatically when a Service is created. These values are not in your Helm chart but will appear in the live resource.

    | Field             | Value                                 |
    | ----------------- | ------------------------------------- |
    | **Kind**          | `Service`                             |
    | **JSON Pointers** | `/spec/clusterIP`, `/spec/clusterIPs` |
  </Accordion>

  <Accordion title="Aggregated ClusterRole Rules">
    When using ClusterRole aggregation, the `kube-controller-manager` merges rules from multiple ClusterRoles. The aggregated `rules` field will differ from what is defined in Git.

    | Field                      | Value                                |
    | -------------------------- | ------------------------------------ |
    | **Kind**                   | `ClusterRole`                        |
    | **Group**                  | `rbac.authorization.k8s.io`          |
    | **Managed Fields Manager** | `clusterrole-aggregation-controller` |
  </Accordion>

  <Accordion title="Status Fields on Custom Resources">
    Operators and controllers frequently update the `.status` subresource on CRDs. Since status is managed by controllers and not by your Helm chart, these changes cause false diffs.

    | Field                  | Value                                              |
    | ---------------------- | -------------------------------------------------- |
    | **Kind**               | Your CRD kind (e.g. `Certificate`, `IngressRoute`) |
    | **JQ Path Expression** | `.status`                                          |
  </Accordion>

  <Accordion title="Annotation Mutations by Controllers">
    Some controllers add or modify annotations on resources. For example, `kubectl.kubernetes.io/last-applied-configuration` is added by client-side apply.

    | Field            | Value                                                                     |
    | ---------------- | ------------------------------------------------------------------------- |
    | **JSON Pointer** | `/metadata/annotations/kubectl.kubernetes.io~1last-applied-configuration` |

    Or with JQ (no escaping needed):

    | Field                  | Value                                                                       |
    | ---------------------- | --------------------------------------------------------------------------- |
    | **JQ Path Expression** | `.metadata.annotations["kubectl.kubernetes.io/last-applied-configuration"]` |
  </Accordion>

  <Accordion title="StatefulSet VolumeClaimTemplates">
    Kubernetes mutates `volumeClaimTemplates` on StatefulSets after creation, adding defaults like `storageClassName`, `volumeMode`, and `status`. These fields are not in your Helm chart but appear in the live resource.

    | Field                  | Value                          |
    | ---------------------- | ------------------------------ |
    | **Kind**               | `StatefulSet`                  |
    | **Group**              | `apps`                         |
    | **JQ Path Expression** | `.spec.volumeClaimTemplates[]` |

    For more targeted ignoring, you can narrow to specific subfields:

    | Field             | Value                                                                                 |
    | ----------------- | ------------------------------------------------------------------------------------- |
    | **Kind**          | `StatefulSet`                                                                         |
    | **Group**         | `apps`                                                                                |
    | **JSON Pointers** | `/spec/volumeClaimTemplates/0/spec/volumeMode`, `/spec/volumeClaimTemplates/0/status` |
  </Accordion>

  <Accordion title="Fields Managed by kube-controller-manager">
    The Kubernetes controller manager sets default values on many resources (e.g. default service account tokens, pod tolerations). Use a Managed Fields Manager rule to ignore all of them at once.

    | Field                      | Value                     |
    | -------------------------- | ------------------------- |
    | **Managed Fields Manager** | `kube-controller-manager` |

    This applies broadly, so only use it on resources where you want to ignore all controller-managed fields.
  </Accordion>
</AccordionGroup>

### Important Behaviors

<Info>
  **Rules need a diff specifier.** Each ignore rule must include at least one JSON Pointer, JQ Path Expression, or Managed Fields Manager. Rules with only resource selectors (Kind, Group, Name, Namespace) and no diff specifier are silently ignored.
</Info>

<Info>
  **RespectIgnoreDifferences is automatic.** When you add ignore rules, the `RespectIgnoreDifferences=true` sync option is automatically enabled. You do not need to add it manually.
</Info>

<Info>
  **Custom profile.** Adding or modifying ignore rules automatically switches your settings profile to **Custom**.
</Info>

***

## Related

<CardGroup cols={2}>
  <Card title="Add-ons" icon="puzzle-piece" href="/concepts/addons">
    Learn about add-on architecture and deployment.
  </Card>

  <Card title="Stacks" icon="cubes" href="/concepts/stacks">
    Bundle add-ons into reusable stacks.
  </Card>

  <Card title="GitOps" icon="git-alt" href="/concepts/gitops">
    Understand the GitOps workflow.
  </Card>

  <Card title="SOPS Encryption" icon="lock" href="/guides/sops">
    Encrypt sensitive add-on values.
  </Card>
</CardGroup>
