argocd This guide is for operators who have already installed Argo CD and have a new cluster and are looking to install many apps in that cluster Admins should review pull requests to that repository paying particular attention to the field in each Cluster Bootstrapping The ability to create Applications in arbitrary warning App of Apps is an admin only tool There s no one particular pattern to solve this problem e g you could write a script to create your apps or you could even manually create them However users of Argo CD tend to use the app of apps pattern is an admin level capability Only admins should have push access to the parent Application s source repository

Answer:
# Cluster Bootstrapping

This guide is for operators who have already installed Argo CD, and have a new cluster and are looking to install many apps in that cluster.

There's no one particular pattern to solve this problem, e.g. you could write a script to create your apps, or you could even manually create them. However, users of Argo CD tend to use the **app of apps pattern**.

!!!warning "App of Apps is an admin-only tool"
    The ability to create Applications in arbitrary [Projects](./declarative-setup.md#projects)
    is an admin-level capability. Only admins should have push access to the parent Application's source repository.
    Admins should review pull requests to that repository, paying particular attention to the `project` field in each
    Application. Projects with access to the namespace in which Argo CD is installed effectively have admin-level
    privileges.

## App Of Apps Pattern

[Declaratively](declarative-setup.md) specify one Argo CD app that consists only of other apps.

![Application of Applications](../assets/application-of-applications.png)

### Helm Example

This example shows how to use Helm to achieve this. You can, of course, use another tool if you like.

A typical layout of your Git repository for this might be:

```
├── Chart.yaml
├── templates
│   ├── guestbook.yaml
│   ├── helm-dependency.yaml
│   ├── helm-guestbook.yaml
│   └── kustomize-guestbook.yaml
└── values.yaml
```

`Chart.yaml` is boiler-plate.

`templates` contains one file for each child app, roughly:

```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: argocd
    server:
  project: default
  source:
    path: guestbook
    repoURL: https://github.com/argoproj/argocd-example-apps
    targetRevision: HEAD
```

The sync policy to automated + prune, so that child apps are automatically created, synced, and deleted when the manifest is changed, but you may wish to disable this. I've also added the finalizer, which will ensure that your apps are deleted correctly.

Fix the revision to a specific Git commit SHA to make sure that, even if the child apps repo changes, the app will only change when the parent app change that revision. Alternatively, you can set it to HEAD or a branch name.

As you probably want to override the cluster server, this is a templated values.

`values.yaml` contains the default values:

```yaml
spec:
  destination:
    server: https://kubernetes.default.svc
```

Next, you need to create and sync your parent app, e.g. via the CLI:

```bash
argocd app create apps \
    --dest-namespace argocd \
    --dest-server https://kubernetes.default.svc \
    --repo https://github.com/argoproj/argocd-example-apps.git \
    --path apps
argocd app sync apps
```

The parent app will appear as in-sync but the child apps will be out of sync:

![New App Of Apps](../assets/new-app-of-apps.png)

> NOTE: You may want to modify this behavior to bootstrap your cluster in waves; see [v1.8 upgrade notes](upgrading/1.7-1.8.md) for information on changing this.

You can either sync via the UI, firstly filter by the correct label:

![Filter Apps](../assets/filter-apps.png)

Then select the "out of sync" apps and sync:

![Sync Apps](../assets/sync-apps.png)

Or, via the CLI:

```bash
argocd app sync -l app.kubernetes.io/instance=apps
```

View [the example on GitHub](https://github.com/argoproj/argocd-example-apps/tree/master/apps).

### Cascading deletion

If you want to ensure that child-apps and all of their resources are deleted when the parent-app is deleted make sure to add the appropriate [finalizer](../user-guide/app_deletion.md#about-the-deletion-finalizer) to your `Application` definition

```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
 ...
```

### Ignoring differences in child applications

To allow changes in child apps without triggering an out-of-sync status, or modification for debugging etc, the app of apps pattern works with [diff customization](../user-guide/diffing/). The example below shows how to ignore changes to syncPolicy and other common values.

```yaml
spec:
  ...
  syncPolicy:
    ...
    syncOptions:
      - RespectIgnoreDifferences=true
    ...
  ignoreDifferences:
    - group: "*"
      kind: "Application"
      namespace: "*"
      jsonPointers:
        # Allow manually disabling auto sync for apps, useful for debugging.
        - /spec/syncPolicy/automated
        # These are automatically updated on a regular basis. Not ignoring last applied configuration since it's used for computing diffs after normalization.
        - /metadata/annotations/argocd.argoproj.io~1refresh
        - /operation
  ...
```

Cluster Bootstrapping  This guide is for operators who have already installed Argo CD  and have a new cluster and are looking to install many apps in that cluster   There s no one particular pattern to solve this problem  e g  you could write a script to create your apps  or you could even manually create them  However  users of Argo CD tend to use the   app of apps pattern        warning  App of Apps is an admin only tool      The ability to create Applications in arbitrary  Projects    declarative setup md projects       is an admin level capability  Only admins should have push access to the parent Application s source repository       Admins should review pull requests to that repository  paying particular attention to the  project  field in each      Application  Projects with access to the namespace in which Argo CD is installed effectively have admin level      privileges      App Of Apps Pattern   Declaratively  declarative setup md  specify one Argo CD app that consists only of other apps     Application of Applications     assets application of applications png       Helm Example  This example shows how to use Helm to achieve this  You can  of course  use another tool if you like   A typical layout of your Git repository for this might be           Chart yaml     templates         guestbook yaml         helm dependency yaml         helm guestbook yaml         kustomize guestbook yaml     values yaml       Chart yaml  is boiler plate    templates  contains one file for each child app  roughly      yaml apiVersion  argoproj io v1alpha1 kind  Application metadata    name  guestbook   namespace  argocd   finalizers      resources finalizer argocd argoproj io spec    destination      namespace  argocd     server     project  default   source      path  guestbook     repoURL  https   github com argoproj argocd example apps     targetRevision  HEAD       The sync policy to automated   prune  so that child apps are automatically created  synced  and deleted when the manifest is changed  but you may wish to disable this  I ve also added the finalizer  which will ensure that your apps are deleted correctly   Fix the revision to a specific Git commit SHA to make sure that  even if the child apps repo changes  the app will only change when the parent app change that revision  Alternatively  you can set it to HEAD or a branch name   As you probably want to override the cluster server  this is a templated values    values yaml  contains the default values      yaml spec    destination      server  https   kubernetes default svc      Next  you need to create and sync your parent app  e g  via the CLI      bash argocd app create apps         dest namespace argocd         dest server https   kubernetes default svc         repo https   github com argoproj argocd example apps git         path apps   argocd app sync apps        The parent app will appear as in sync but the child apps will be out of sync     New App Of Apps     assets new app of apps png     NOTE  You may want to modify this behavior to bootstrap your cluster in waves  see  v1 8 upgrade notes  upgrading 1 7 1 8 md  for information on changing this   You can either sync via the UI  firstly filter by the correct label     Filter Apps     assets filter apps png   Then select the  out of sync  apps and sync      Sync Apps     assets sync apps png   Or  via the CLI       bash argocd app sync  l app kubernetes io instance apps      View  the example on GitHub  https   github com argoproj argocd example apps tree master apps          Cascading deletion  If you want to ensure that child apps and all of their resources are deleted when the parent app is deleted make sure to add the appropriate  finalizer     user guide app deletion md about the deletion finalizer  to your  Application  definition     yaml apiVersion  argoproj io v1alpha1 kind  Application metadata    name  guestbook   namespace  argocd   finalizers      resources finalizer argocd argoproj io spec                Ignoring differences in child applications  To allow changes in child apps without triggering an out of sync status  or modification for debugging etc  the app of apps pattern works with  diff customization     user guide diffing    The example below shows how to ignore changes to syncPolicy and other common values      yaml spec          syncPolicy              syncOptions          RespectIgnoreDifferences true           ignoreDifferences        group            kind   Application        namespace            jsonPointers            Allow manually disabling auto sync for apps  useful for debugging             spec syncPolicy automated           These are automatically updated on a regular basis  Not ignoring last applied configuration since it s used for computing diffs after normalization             metadata annotations argocd argoproj io 1refresh            operation


argocd Installation Argo CD has two type of installations multi tenant and core The end users can access Argo CD via the API server using the Web UI or CLI The CLI has to be configured using command The multi tenant installation is the most common way to install Argo CD This type of installation is typically used to service multiple application developer teams in the organization and maintained by a platform team Multi Tenant

Answer:
# Installation

Argo CD has two type of installations: multi-tenant and core.

## Multi-Tenant

The multi-tenant installation is the most common way to install Argo CD. This type of installation is typically used to service multiple application developer teams
in the organization and maintained by a platform team.

The end-users can access Argo CD via the API server using the Web UI or `argocd` CLI. The `argocd` CLI has to be configured using `argocd login <server-host>` command
(learn more [here](../user-guide/commands/argocd_login.md)).

Two types of installation manifests are provided:

### Non High Availability:

Not recommended for production use. This type of installation is typically used during evaluation period for demonstrations and testing.

* [install.yaml](https://github.com/argoproj/argo-cd/blob/master/manifests/install.yaml) - Standard Argo CD installation with cluster-admin access. Use this
  manifest set if you plan to use Argo CD to deploy applications in the same cluster that Argo CD runs
  in (i.e. kubernetes.svc.default). It will still be able to deploy to external clusters with inputted
  credentials.

  > Note: The ClusterRoleBinding in the installation manifest is bound to a ServiceAccount in the argocd namespace.
  > Be cautious when modifying the namespace, as changing it may cause permission-related errors unless the ClusterRoleBinding is correctly adjusted to reflect the new namespace.

* [namespace-install.yaml](https://github.com/argoproj/argo-cd/blob/master/manifests/namespace-install.yaml) - Installation of Argo CD which requires only
  namespace level privileges (does not need cluster roles). Use this manifest set if you do not
  need Argo CD to deploy applications in the same cluster that Argo CD runs in, and will rely solely
  on inputted cluster credentials. An example of using this set of manifests is if you run several
  Argo CD instances for different teams, where each instance will be deploying applications to
  external clusters. It will still be possible to deploy to the same cluster (kubernetes.svc.default)
  with inputted credentials (i.e. `argocd cluster add <CONTEXT> --in-cluster --namespace <YOUR NAMESPACE>`).

  > Note: Argo CD CRDs are not included into [namespace-install.yaml](https://github.com/argoproj/argo-cd/blob/master/manifests/namespace-install.yaml).
  > and have to be installed separately. The CRD manifests are located in the [manifests/crds](https://github.com/argoproj/argo-cd/blob/master/manifests/crds) directory.
  > Use the following command to install them:
  > ```
  > kubectl apply -k https://github.com/argoproj/argo-cd/manifests/crds\?ref\=stable
  > ```

### High Availability:

High Availability installation is recommended for production use. This bundle includes the same components but tuned for high availability and resiliency.

* [ha/install.yaml](https://github.com/argoproj/argo-cd/blob/master/manifests/ha/install.yaml) - the same as install.yaml but with multiple replicas for
  supported components.

* [ha/namespace-install.yaml](https://github.com/argoproj/argo-cd/blob/master/manifests/ha/namespace-install.yaml) - the same as namespace-install.yaml but
  with multiple replicas for supported components.

## Core

The Argo CD Core installation is primarily used to deploy Argo CD in
headless mode. This type of installation is most suitable for cluster
administrators who independently use Argo CD and don't need
multi-tenancy features. This installation includes fewer components
and is easier to setup. The bundle does not include the API server or
UI, and installs the lightweight (non-HA) version of each component.

Installation manifest is available at [core-install.yaml](https://github.com/argoproj/argo-cd/blob/master/manifests/core-install.yaml).

For more details about Argo CD Core please refer to the [official
documentation](./core.md)

## Kustomize

The Argo CD manifests can also be installed using Kustomize. It is recommended to include the manifest as a remote resource and apply additional customizations
using Kustomize patches.

```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: argocd
resources:
- https://raw.githubusercontent.com/argoproj/argo-cd/v2.7.2/manifests/install.yaml
```

For an example of this, see the [kustomization.yaml](https://github.com/argoproj/argoproj-deployments/blob/master/argocd/kustomization.yaml)
used to deploy the [Argoproj CI/CD infrastructure](https://github.com/argoproj/argoproj-deployments#argoproj-deployments).

#### Installing Argo CD in a Custom Namespace
If you want to install Argo CD in a namespace other than the default argocd, you can use Kustomize to apply a patch that updates the ClusterRoleBinding to reference the correct namespace for the ServiceAccount. This ensures that the necessary permissions are correctly set in your custom namespace.

Below is an example of how to configure your kustomization.yaml to install Argo CD in a custom namespace:
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: <your-custom-namespace>
resources:
  - https://raw.githubusercontent.com/argoproj/argo-cd/v2.7.2/manifests/install.yaml

patches:
  - patch: |-
      - op: replace
        path: /subjects/0/namespace
        value: <your-custom-namespace>
    target:
      kind: ClusterRoleBinding
```

This patch ensures that the ClusterRoleBinding correctly maps to the ServiceAccount in your custom namespace, preventing any permission-related issues during the deployment.

## Helm

The Argo CD can be installed using [Helm](https://helm.sh/). The Helm chart is currently community maintained and available at
[argo-helm/charts/argo-cd](https://github.com/argoproj/argo-helm/tree/main/charts/argo-cd).

## Supported versions

For detailed information regarding Argo CD's version support policy, please refer to the [Release Process and Cadence documentation](https://argo-cd.readthedocs.io/en/stable/developer-guide/release-process-and-cadence/).

## Tested versions

The following table shows the versions of Kubernetes that are tested with each version of Argo CD.

{!docs/operator-manual/tested-kubernetes-versions.md!}

Installation  Argo CD has two type of installations  multi tenant and core      Multi Tenant  The multi tenant installation is the most common way to install Argo CD  This type of installation is typically used to service multiple application developer teams in the organization and maintained by a platform team   The end users can access Argo CD via the API server using the Web UI or  argocd  CLI  The  argocd  CLI has to be configured using  argocd login  server host   command  learn more  here     user guide commands argocd login md     Two types of installation manifests are provided       Non High Availability   Not recommended for production use  This type of installation is typically used during evaluation period for demonstrations and testing      install yaml  https   github com argoproj argo cd blob master manifests install yaml    Standard Argo CD installation with cluster admin access  Use this   manifest set if you plan to use Argo CD to deploy applications in the same cluster that Argo CD runs   in  i e  kubernetes svc default   It will still be able to deploy to external clusters with inputted   credentials       Note  The ClusterRoleBinding in the installation manifest is bound to a ServiceAccount in the argocd namespace       Be cautious when modifying the namespace  as changing it may cause permission related errors unless the ClusterRoleBinding is correctly adjusted to reflect the new namespace      namespace install yaml  https   github com argoproj argo cd blob master manifests namespace install yaml    Installation of Argo CD which requires only   namespace level privileges  does not need cluster roles   Use this manifest set if you do not   need Argo CD to deploy applications in the same cluster that Argo CD runs in  and will rely solely   on inputted cluster credentials  An example of using this set of manifests is if you run several   Argo CD instances for different teams  where each instance will be deploying applications to   external clusters  It will still be possible to deploy to the same cluster  kubernetes svc default    with inputted credentials  i e   argocd cluster add  CONTEXT    in cluster   namespace  YOUR NAMESPACE          Note  Argo CD CRDs are not included into  namespace install yaml  https   github com argoproj argo cd blob master manifests namespace install yaml       and have to be installed separately  The CRD manifests are located in the  manifests crds  https   github com argoproj argo cd blob master manifests crds  directory      Use the following command to install them              kubectl apply  k https   github com argoproj argo cd manifests crds  ref  stable              High Availability   High Availability installation is recommended for production use  This bundle includes the same components but tuned for high availability and resiliency      ha install yaml  https   github com argoproj argo cd blob master manifests ha install yaml    the same as install yaml but with multiple replicas for   supported components      ha namespace install yaml  https   github com argoproj argo cd blob master manifests ha namespace install yaml    the same as namespace install yaml but   with multiple replicas for supported components      Core  The Argo CD Core installation is primarily used to deploy Argo CD in headless mode  This type of installation is most suitable for cluster administrators who independently use Argo CD and don t need multi tenancy features  This installation includes fewer components and is easier to setup  The bundle does not include the API server or UI  and installs the lightweight  non HA  version of each component   Installation manifest is available at  core install yaml  https   github com argoproj argo cd blob master manifests core install yaml    For more details about Argo CD Core please refer to the  official documentation    core md      Kustomize  The Argo CD manifests can also be installed using Kustomize  It is recommended to include the manifest as a remote resource and apply additional customizations using Kustomize patches       yaml apiVersion  kustomize config k8s io v1beta1 kind  Kustomization  namespace  argocd resources    https   raw githubusercontent com argoproj argo cd v2 7 2 manifests install yaml      For an example of this  see the  kustomization yaml  https   github com argoproj argoproj deployments blob master argocd kustomization yaml  used to deploy the  Argoproj CI CD infrastructure  https   github com argoproj argoproj deployments argoproj deployments         Installing Argo CD in a Custom Namespace If you want to install Argo CD in a namespace other than the default argocd  you can use Kustomize to apply a patch that updates the ClusterRoleBinding to reference the correct namespace for the ServiceAccount  This ensures that the necessary permissions are correctly set in your custom namespace   Below is an example of how to configure your kustomization yaml to install Argo CD in a custom namespace     yaml apiVersion  kustomize config k8s io v1beta1 kind  Kustomization  namespace   your custom namespace  resources      https   raw githubusercontent com argoproj argo cd v2 7 2 manifests install yaml  patches      patch             op  replace         path   subjects 0 namespace         value   your custom namespace      target        kind  ClusterRoleBinding      This patch ensures that the ClusterRoleBinding correctly maps to the ServiceAccount in your custom namespace  preventing any permission related issues during the deployment      Helm  The Argo CD can be installed using  Helm  https   helm sh    The Helm chart is currently community maintained and available at  argo helm charts argo cd  https   github com argoproj argo helm tree main charts argo cd       Supported versions  For detailed information regarding Argo CD s version support policy  please refer to the  Release Process and Cadence documentation  https   argo cd readthedocs io en stable developer guide release process and cadence        Tested versions  The following table shows the versions of Kubernetes that are tested with each version of Argo CD     docs operator manual tested kubernetes versions md


argocd Both protocols are exposed by the argocd server service object on the following ports Ingress Configuration 443 gRPC HTTPS Argo CD API server runs both a gRPC server used by the CLI as well as a HTTP HTTPS server used by the UI 80 HTTP redirects to HTTPS There are several ways how Ingress can be configured

Answer:
# Ingress Configuration

Argo CD API server runs both a gRPC server (used by the CLI), as well as a HTTP/HTTPS server (used by the UI).
Both protocols are exposed by the argocd-server service object on the following ports:

* 443 - gRPC/HTTPS
* 80 - HTTP (redirects to HTTPS)

There are several ways how Ingress can be configured.

## [Ambassador](https://www.getambassador.io/)

The Ambassador Edge Stack can be used as a Kubernetes ingress controller with [automatic TLS termination](https://www.getambassador.io/docs/latest/topics/running/tls/#host) and routing capabilities for both the CLI and the UI.

The API server should be run with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md). Given the `argocd` CLI includes the port number in the request `host` header, 2 Mappings are required.
Note: Disabling TLS in not required if you are using grpc-web

### Option 1: Mapping CRD for Host-based Routing
```yaml
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
  name: argocd-server-ui
  namespace: argocd
spec:
  host: argocd.example.com
  prefix: /
  service: https://argocd-server:443
---
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
  name: argocd-server-cli
  namespace: argocd
spec:
  # NOTE: the port must be ignored if you have strip_matching_host_port enabled on envoy
  host: argocd.example.com:443
  prefix: /
  service: argocd-server:80
  regex_headers:
    Content-Type: "^application/grpc.*$"
  grpc: true
```

Login with the `argocd` CLI:

```shell
argocd login <host>
```

### Option 2: Mapping CRD for Path-based Routing

The API server must be configured to be available under a non-root path (e.g. `/argo-cd`). Edit the `argocd-server` deployment to add the `--rootpath=/argo-cd` flag to the argocd-server command.

```yaml
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
  name: argocd-server
  namespace: argocd
spec:
  prefix: /argo-cd
  rewrite: /argo-cd
  service: https://argocd-server:443
```

Example of `argocd-cmd-params-cm` configmap
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cmd-params-cm
  namespace: argocd
  labels:
    app.kubernetes.io/name: argocd-cmd-params-cm
    app.kubernetes.io/part-of: argocd
data:
  ## Server properties
  # Value for base href in index.html. Used if Argo CD is running behind reverse proxy under subpath different from / (default "/")
  server.basehref: "/argo-cd"
  # Used if Argo CD is running behind reverse proxy under subpath different from /
  server.rootpath: "/argo-cd"
```

Login with the `argocd` CLI using the extra `--grpc-web-root-path` flag for non-root paths.

```shell
argocd login <host>:<port> --grpc-web-root-path /argo-cd
```

## [Contour](https://projectcontour.io/)
The Contour ingress controller can terminate TLS ingress traffic at the edge.

The Argo CD API server should be run with TLS disabled. Edit the `argocd-server` Deployment to add the `--insecure` flag to the argocd-server container command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md).

It is also possible to provide an internal-only ingress path and an external-only ingress path by deploying two instances of Contour: one behind a private-subnet LoadBalancer service and one behind a public-subnet LoadBalancer service. The private Contour deployment will pick up Ingresses annotated with `kubernetes.io/ingress.class: contour-internal` and the public Contour deployment will pick up Ingresses annotated with `kubernetes.io/ingress.class: contour-external`.

This provides the opportunity to deploy the Argo CD UI privately but still allow for SSO callbacks to succeed.

### Private Argo CD UI with  Multiple Ingress Objects and BYO Certificate
Since Contour Ingress supports only a single protocol per Ingress object, define three Ingress objects. One for private HTTP/HTTPS, one for private gRPC, and one for public HTTPS SSO callbacks.

Internal HTTP/HTTPS Ingress:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-http
  annotations:
    kubernetes.io/ingress.class: contour-internal
    ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  rules:
  - host: internal.path.to.argocd.io
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              name: http
  tls:
  - hosts:
    - internal.path.to.argocd.io
    secretName: your-certificate-name
```

Internal gRPC Ingress:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-grpc
  annotations:
    kubernetes.io/ingress.class: contour-internal
spec:
  rules:
  - host: grpc-internal.path.to.argocd.io
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              name: https
  tls:
  - hosts:
    - grpc-internal.path.to.argocd.io
    secretName: your-certificate-name
```

External HTTPS SSO Callback Ingress:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-external-callback-http
  annotations:
    kubernetes.io/ingress.class: contour-external
    ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  rules:
  - host: external.path.to.argocd.io
    http:
      paths:
      - path: /api/dex/callback
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              name: http
  tls:
  - hosts:
    - external.path.to.argocd.io
    secretName: your-certificate-name
```

The argocd-server Service needs to be annotated with `projectcontour.io/upstream-protocol.h2c: "https,443"` to wire up the gRPC protocol proxying.

The API server should then be run with TLS disabled. Edit the `argocd-server` deployment to add the
`--insecure` flag to the argocd-server command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md).

Contour httpproxy CRD:

Using a contour httpproxy CRD allows you to use the same hostname for the GRPC and REST api.

```yaml
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: argocd-server
  namespace: argocd
spec:
  ingressClassName: contour
  virtualhost:
    fqdn: path.to.argocd.io
    tls:
      secretName: wildcard-tls
  routes:
    - conditions:
        - prefix: /
        - header:
            name: Content-Type
            contains: application/grpc
      services:
        - name: argocd-server
          port: 80
          protocol: h2c # allows for unencrypted http2 connections
      timeoutPolicy:
        response: 1h
        idle: 600s
        idleConnection: 600s
    - conditions:
        - prefix: /
      services:
        - name: argocd-server
          port: 80
```

## [kubernetes/ingress-nginx](https://github.com/kubernetes/ingress-nginx)

### Option 1: SSL-Passthrough

Argo CD serves multiple protocols (gRPC/HTTPS) on the same port (443), this provides a
challenge when attempting to define a single nginx ingress object and rule for the argocd-service,
since the `nginx.ingress.kubernetes.io/backend-protocol` [annotation](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#backend-protocol)
accepts only a single value for the backend protocol (e.g. HTTP, HTTPS, GRPC, GRPCS).

In order to expose the Argo CD API server with a single ingress rule and hostname, the
`nginx.ingress.kubernetes.io/ssl-passthrough` [annotation](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#ssl-passthrough)
must be used to passthrough TLS connections and terminate TLS at the Argo CD API server.

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: argocd.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              name: https
```

The above rule terminates TLS at the Argo CD API server, which detects the protocol being used,
and responds appropriately. Note that the `nginx.ingress.kubernetes.io/ssl-passthrough` annotation
requires that the `--enable-ssl-passthrough` flag be added to the command line arguments to
`nginx-ingress-controller`.

#### SSL-Passthrough with cert-manager and Let's Encrypt

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-ingress
  namespace: argocd
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    # If you encounter a redirect loop or are getting a 307 response code
    # then you need to force the nginx ingress to connect to the backend using HTTPS.
    #
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  ingressClassName: nginx
  rules:
  - host: argocd.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              name: https
  tls:
  - hosts:
    - argocd.example.com
    secretName: argocd-server-tls # as expected by argocd-server
```

### Option 2: SSL Termination at Ingress Controller

An alternative approach is to perform the SSL termination at the Ingress. Since an `ingress-nginx` Ingress supports only a single protocol per Ingress object, two Ingress objects need to be defined using the `nginx.ingress.kubernetes.io/backend-protocol` annotation, one for HTTP/HTTPS and the other for gRPC.

Each ingress will be for a different domain (`argocd.example.com` and `grpc.argocd.example.com`). This requires that the Ingress resources use different TLS `secretName`s to avoid unexpected behavior.

HTTP/HTTPS Ingress:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-http-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              name: http
    host: argocd.example.com
  tls:
  - hosts:
    - argocd.example.com
    secretName: argocd-ingress-http
```

gRPC Ingress:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-grpc-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              name: https
    host: grpc.argocd.example.com
  tls:
  - hosts:
    - grpc.argocd.example.com
    secretName: argocd-ingress-grpc
```

The API server should then be run with TLS disabled. Edit the `argocd-server` deployment to add the
`--insecure` flag to the argocd-server command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md).

The obvious disadvantage to this approach is that this technique requires two separate hostnames for
the API server -- one for gRPC and the other for HTTP/HTTPS. However it allows TLS termination to
happen at the ingress controller.

## [Traefik (v3.0)](https://docs.traefik.io/)

Traefik can be used as an edge router and provide [TLS](https://docs.traefik.io/user-guides/grpc/) termination within the same deployment.

It currently has an advantage over NGINX in that it can terminate both TCP and HTTP connections _on the same port_ meaning you do not require multiple hosts or paths.

The API server should be run with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command or set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md).

### IngressRoute CRD
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: argocd-server
  namespace: argocd
spec:
  entryPoints:
    - websecure
  routes:
    - kind: Rule
      match: Host(`argocd.example.com`)
      priority: 10
      services:
        - name: argocd-server
          port: 80
    - kind: Rule
      match: Host(`argocd.example.com`) && Header(`Content-Type`, `application/grpc`)
      priority: 11
      services:
        - name: argocd-server
          port: 80
          scheme: h2c
  tls:
    certResolver: default
```

## AWS Application Load Balancers (ALBs) And Classic ELB (HTTP Mode)
AWS ALBs can be used as an L7 Load Balancer for both UI and gRPC traffic, whereas Classic ELBs and NLBs can be used as L4 Load Balancers for both.

When using an ALB, you'll want to create a second service for argocd-server. This is necessary because we need to tell the ALB to send the GRPC traffic to a different target group then the UI traffic, since the backend protocol is HTTP2 instead of HTTP1.

```yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
    alb.ingress.kubernetes.io/backend-protocol-version: GRPC # This tells AWS to send traffic from the ALB using GRPC. Plain HTTP2 can be used, but the health checks wont be available because argo currently downgrade non-grpc calls to HTTP1
  labels:
    app: argogrpc
  name: argogrpc
  namespace: argocd
spec:
  ports:
  - name: "443"
    port: 443
    protocol: TCP
    targetPort: 8080
  selector:
    app.kubernetes.io/name: argocd-server
  sessionAffinity: None
  type: NodePort
```

Once we create this service, we can configure the Ingress to conditionally route all `application/grpc` traffic to the new HTTP2 backend, using the `alb.ingress.kubernetes.io/conditions` annotation, as seen below. Note: The value after the . in the condition annotation _must_ be the same name as the service that you want traffic to route to - and will be applied on any path with a matching serviceName.

```yaml
  apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    annotations:
      alb.ingress.kubernetes.io/backend-protocol: HTTPS
      # Use this annotation (which must match a service name) to route traffic to HTTP2 backends.
      alb.ingress.kubernetes.io/conditions.argogrpc: |
        [{"field":"http-header","httpHeaderConfig":{"httpHeaderName": "Content-Type", "values":["application/grpc"]}}]
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
    name: argocd
    namespace: argocd
  spec:
    rules:
    - host: argocd.argoproj.io
      http:
        paths:
        - path: /
          backend:
            service:
              name: argogrpc # The grpc service must be placed before the argocd-server for the listening rules to be created in the correct order
              port:
                number: 443
          pathType: Prefix
        - path: /
          backend:
            service:
              name: argocd-server
              port:
                number: 443
          pathType: Prefix
    tls:
    - hosts:
      - argocd.argoproj.io
```

## [Istio](https://www.istio.io)
You can put Argo CD behind Istio using following configurations. Here we will achieve both serving Argo CD behind istio and using subpath on Istio

First we need to make sure that we can run Argo CD with subpath (ie /argocd). For this we have used install.yaml from argocd project as is

```bash
curl -kLs -o install.yaml https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
```

save following file as kustomization.yml

```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./install.yaml

patches:
- path: ./patch.yml
```

And following lines as patch.yml

```yaml
# Use --insecure so Ingress can send traffic with HTTP
# --bashref /argocd is the subpath like https://IP/argocd
# env was added because of https://github.com/argoproj/argo-cd/issues/3572 error
---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: argocd-server
spec:
 template:
   spec:
     containers:
     - args:
       - /usr/local/bin/argocd-server
       - --staticassets
       - /shared/app
       - --redis
       - argocd-redis:6379
       - --insecure
       - --basehref
       - /argocd
       - --rootpath
       - /argocd
       name: argocd-server
       env:
       - name: ARGOCD_MAX_CONCURRENT_LOGIN_REQUESTS_COUNT
         value: "0"
```

After that install Argo CD  (there should be only 3 yml file defined above in current directory )

```bash
kubectl apply -k ./ -n argocd --wait=true
```

Be sure you create secret for Istio ( in our case secretname is argocd-server-tls on argocd Namespace). After that we create Istio Resources

```yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: argocd-gateway
  namespace: argocd
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
    tls:
     httpsRedirect: true
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - "*"
    tls:
      credentialName: argocd-server-tls
      maxProtocolVersion: TLSV1_3
      minProtocolVersion: TLSV1_2
      mode: SIMPLE
      cipherSuites:
        - ECDHE-ECDSA-AES128-GCM-SHA256
        - ECDHE-RSA-AES128-GCM-SHA256
        - ECDHE-ECDSA-AES128-SHA
        - AES128-GCM-SHA256
        - AES128-SHA
        - ECDHE-ECDSA-AES256-GCM-SHA384
        - ECDHE-RSA-AES256-GCM-SHA384
        - ECDHE-ECDSA-AES256-SHA
        - AES256-GCM-SHA384
        - AES256-SHA
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: argocd-virtualservice
  namespace: argocd
spec:
  hosts:
  - "*"
  gateways:
  - argocd-gateway
  http:
  - match:
    - uri:
        prefix: /argocd
    route:
    - destination:
        host: argocd-server
        port:
          number: 80
```

And now we can browse http:///argocd (it will be rewritten to https:///argocd

## Google Cloud load balancers with Kubernetes Ingress

You can make use of the integration of GKE with Google Cloud to deploy Load Balancers using just Kubernetes objects.

For this we will need these five objects:
- A Service
- A BackendConfig
- A FrontendConfig
- A secret with your SSL certificate
- An Ingress for GKE

If you need detail for all the options available for these Google integrations, you can check the [Google docs on configuring Ingress features](https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features)

### Disable internal TLS

First, to avoid internal redirection loops from HTTP to HTTPS, the API server should be run with TLS disabled.

Edit the `--insecure` flag in the `argocd-server` command of the argocd-server deployment, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md).

### Creating a service

Now you need an externally accessible service. This is practically the same as the internal service Argo CD has, but with Google Cloud annotations. Note that this service is annotated to use a [Network Endpoint Group](https://cloud.google.com/load-balancing/docs/negs) (NEG) to allow your load balancer to send traffic directly to your pods without using kube-proxy, so remove the `neg` annotation if that's not what you want.

The service:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: argocd-server
  namespace: argocd
  annotations:
    cloud.google.com/neg: '{"ingress": true}'
    cloud.google.com/backend-config: '{"ports": {"http":"argocd-backend-config"}}'
spec:
  type: ClusterIP
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app.kubernetes.io/name: argocd-server
```

### Creating a BackendConfig

See that previous service referencing a backend config called `argocd-backend-config`? So lets deploy it using this yaml:

```yaml
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: argocd-backend-config
  namespace: argocd
spec:
  healthCheck:
    checkIntervalSec: 30
    timeoutSec: 5
    healthyThreshold: 1
    unhealthyThreshold: 2
    type: HTTP
    requestPath: /healthz
    port: 8080
```

It uses the same health check as the pods.

### Creating a FrontendConfig

Now we can deploy a frontend config with an HTTP to HTTPS redirect:

```yaml
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: argocd-frontend-config
  namespace: argocd
spec:
  redirectToHttps:
    enabled: true
```

---
!!! note

    The next two steps (the certificate secret and the Ingress) are described supposing that you manage the certificate yourself, and you have the certificate and key files for it. In the case that your certificate is Google-managed, fix the next two steps using the [guide to use a Google-managed SSL certificate](https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs#creating_an_ingress_with_a_google-managed_certificate).

---

### Creating a certificate secret

We need now to create a secret with the SSL certificate we want in our load balancer. It's as easy as executing this command on the path you have your certificate keys stored:

```
kubectl -n argocd create secret tls secret-yourdomain-com \
  --cert cert-file.crt --key key-file.key
```

### Creating an Ingress

And finally, to top it all, our Ingress. Note the reference to our frontend config, the service, and to the certificate secret.

---
!!! note

   GKE clusters running versions earlier than `1.21.3-gke.1600`, [the only supported value for the pathType field](https://cloud.google.com/kubernetes-engine/docs/how-to/load-balance-ingress#creating_an_ingress) is `ImplementationSpecific`. So you must check your GKE cluster's version. You need to use different YAML depending on the version.

---

If you use the version earlier than `1.21.3-gke.1600`, you should use the following Ingress resource:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd
  namespace: argocd
  annotations:
    networking.gke.io/v1beta1.FrontendConfig: argocd-frontend-config
spec:
  tls:
    - secretName: secret-example-com
  rules:
    - host: argocd.example.com
      http:
        paths:
        - pathType: ImplementationSpecific
          path: "/*"   # "*" is needed. Without this, the UI Javascript and CSS will not load properly
          backend:
            service:
              name: argocd-server
              port:
                number: 80
```

If you use the version `1.21.3-gke.1600` or later, you should use the following Ingress resource:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd
  namespace: argocd
  annotations:
    networking.gke.io/v1beta1.FrontendConfig: argocd-frontend-config
spec:
  tls:
    - secretName: secret-example-com
  rules:
    - host: argocd.example.com
      http:
        paths:
        - pathType: Prefix
          path: "/"
          backend:
            service:
              name: argocd-server
              port:
                number: 80
```

As you may know already, it can take some minutes to deploy the load balancer and become ready to accept connections. Once it's ready, get the public IP address for your Load Balancer, go to your DNS server (Google or third party) and point your domain or subdomain (i.e. argocd.example.com) to that IP address.

You can get that IP address describing the Ingress object like this:

```
kubectl -n argocd describe ingresses argocd | grep Address
```

Once the DNS change is propagated, you're ready to use Argo with your Google Cloud Load Balancer

## Authenticating through multiple layers of authenticating reverse proxies

Argo CD endpoints may be protected by one or more reverse proxies layers, in that case, you can provide additional headers through the `argocd` CLI `--header` parameter to authenticate through those layers.

```shell
$ argocd login <host>:<port> --header 'x-token1:foo' --header 'x-token2:bar' # can be repeated multiple times
$ argocd login <host>:<port> --header 'x-token1:foo,x-token2:bar' # headers can also be comma separated
```
## ArgoCD Server and UI Root Path (v1.5.3)

Argo CD server and UI can be configured to be available under a non-root path (e.g. `/argo-cd`).
To do this, add the `--rootpath` flag into the `argocd-server` deployment command:

```yaml
spec:
  template:
    spec:
      name: argocd-server
      containers:
      - command:
        - /argocd-server
        - --repo-server
        - argocd-repo-server:8081
        - --rootpath
        - /argo-cd
```
NOTE: The flag `--rootpath` changes both API Server and UI base URL.
Example nginx.conf:

```
worker_processes 1;

events { worker_connections 1024; }

http {

    sendfile on;

    server {
        listen 443;

        location /argo-cd/ {
            proxy_pass         https://localhost:8080/argo-cd/;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
            # buffering should be disabled for api/v1/stream/applications to support chunked response
            proxy_buffering off;
        }
    }
}
```
Flag ```--grpc-web-root-path ``` is used to provide a non-root path (e.g. /argo-cd)

```shell
$ argocd login <host>:<port> --grpc-web-root-path /argo-cd
```

## UI Base Path

If the Argo CD UI is available under a non-root path (e.g. `/argo-cd` instead of `/`) then the UI path should be configured in the API server.
To configure the UI path add the `--basehref` flag into the `argocd-server` deployment command:

```yaml
spec:
  template:
    spec:
      name: argocd-server
      containers:
      - command:
        - /argocd-server
        - --repo-server
        - argocd-repo-server:8081
        - --basehref
        - /argo-cd
```

NOTE: The flag `--basehref` only changes the UI base URL. The API server will keep using the `/` path so you need to add a URL rewrite rule to the proxy config.
Example nginx.conf with URL rewrite:

```
worker_processes 1;

events { worker_connections 1024; }

http {

    sendfile on;

    server {
        listen 443;

        location /argo-cd {
            rewrite /argo-cd/(.*) /$1  break;
            proxy_pass         https://localhost:8080;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
            # buffering should be disabled for api/v1/stream/applications to support chunked response
            proxy_buffering off;
        }
    }
}
```

Ingress Configuration  Argo CD API server runs both a gRPC server  used by the CLI   as well as a HTTP HTTPS server  used by the UI   Both protocols are exposed by the argocd server service object on the following ports     443   gRPC HTTPS   80   HTTP  redirects to HTTPS   There are several ways how Ingress can be configured       Ambassador  https   www getambassador io    The Ambassador Edge Stack can be used as a Kubernetes ingress controller with  automatic TLS termination  https   www getambassador io docs latest topics running tls  host  and routing capabilities for both the CLI and the UI   The API server should be run with TLS disabled  Edit the  argocd server  deployment to add the    insecure  flag to the argocd server command  or simply set  server insecure   true   in the  argocd cmd params cm  ConfigMap  as described here  server commands additional configuration method md   Given the  argocd  CLI includes the port number in the request  host  header  2 Mappings are required   Note  Disabling TLS in not required if you are using grpc web      Option 1  Mapping CRD for Host based Routing    yaml apiVersion  getambassador io v2 kind  Mapping metadata    name  argocd server ui   namespace  argocd spec    host  argocd example com   prefix      service  https   argocd server 443     apiVersion  getambassador io v2 kind  Mapping metadata    name  argocd server cli   namespace  argocd spec      NOTE  the port must be ignored if you have strip matching host port enabled on envoy   host  argocd example com 443   prefix      service  argocd server 80   regex headers      Content Type    application grpc       grpc  true      Login with the  argocd  CLI      shell argocd login  host           Option 2  Mapping CRD for Path based Routing  The API server must be configured to be available under a non root path  e g    argo cd    Edit the  argocd server  deployment to add the    rootpath  argo cd  flag to the argocd server command      yaml apiVersion  getambassador io v2 kind  Mapping metadata    name  argocd server   namespace  argocd spec    prefix   argo cd   rewrite   argo cd   service  https   argocd server 443      Example of  argocd cmd params cm  configmap    yaml apiVersion  v1 kind  ConfigMap metadata    name  argocd cmd params cm   namespace  argocd   labels      app kubernetes io name  argocd cmd params cm     app kubernetes io part of  argocd data       Server properties     Value for base href in index html  Used if Argo CD is running behind reverse proxy under subpath different from    default        server basehref    argo cd      Used if Argo CD is running behind reverse proxy under subpath different from     server rootpath    argo cd       Login with the  argocd  CLI using the extra    grpc web root path  flag for non root paths      shell argocd login  host   port    grpc web root path  argo cd          Contour  https   projectcontour io   The Contour ingress controller can terminate TLS ingress traffic at the edge   The Argo CD API server should be run with TLS disabled  Edit the  argocd server  Deployment to add the    insecure  flag to the argocd server container command  or simply set  server insecure   true   in the  argocd cmd params cm  ConfigMap  as described here  server commands additional configuration method md    It is also possible to provide an internal only ingress path and an external only ingress path by deploying two instances of Contour  one behind a private subnet LoadBalancer service and one behind a public subnet LoadBalancer service  The private Contour deployment will pick up Ingresses annotated with  kubernetes io ingress class  contour internal  and the public Contour deployment will pick up Ingresses annotated with  kubernetes io ingress class  contour external    This provides the opportunity to deploy the Argo CD UI privately but still allow for SSO callbacks to succeed       Private Argo CD UI with  Multiple Ingress Objects and BYO Certificate Since Contour Ingress supports only a single protocol per Ingress object  define three Ingress objects  One for private HTTP HTTPS  one for private gRPC  and one for public HTTPS SSO callbacks   Internal HTTP HTTPS Ingress     yaml apiVersion  networking k8s io v1 kind  Ingress metadata    name  argocd server http   annotations      kubernetes io ingress class  contour internal     ingress kubernetes io force ssl redirect   true  spec    rules      host  internal path to argocd io     http        paths          path            pathType  Prefix         backend            service              name  argocd server             port                name  http   tls      hosts        internal path to argocd io     secretName  your certificate name      Internal gRPC Ingress     yaml apiVersion  networking k8s io v1 kind  Ingress metadata    name  argocd server grpc   annotations      kubernetes io ingress class  contour internal spec    rules      host  grpc internal path to argocd io     http        paths          path            pathType  Prefix         backend            service              name  argocd server             port                name  https   tls      hosts        grpc internal path to argocd io     secretName  your certificate name      External HTTPS SSO Callback Ingress     yaml apiVersion  networking k8s io v1 kind  Ingress metadata    name  argocd server external callback http   annotations      kubernetes io ingress class  contour external     ingress kubernetes io force ssl redirect   true  spec    rules      host  external path to argocd io     http        paths          path   api dex callback         pathType  Prefix         backend            service              name  argocd server             port                name  http   tls      hosts        external path to argocd io     secretName  your certificate name      The argocd server Service needs to be annotated with  projectcontour io upstream protocol h2c   https 443   to wire up the gRPC protocol proxying   The API server should then be run with TLS disabled  Edit the  argocd server  deployment to add the    insecure  flag to the argocd server command  or simply set  server insecure   true   in the  argocd cmd params cm  ConfigMap  as described here  server commands additional configuration method md    Contour httpproxy CRD   Using a contour httpproxy CRD allows you to use the same hostname for the GRPC and REST api      yaml apiVersion  projectcontour io v1 kind  HTTPProxy metadata    name  argocd server   namespace  argocd spec    ingressClassName  contour   virtualhost      fqdn  path to argocd io     tls        secretName  wildcard tls   routes        conditions            prefix              header              name  Content Type             contains  application grpc       services            name  argocd server           port  80           protocol  h2c   allows for unencrypted http2 connections       timeoutPolicy          response  1h         idle  600s         idleConnection  600s       conditions            prefix          services            name  argocd server           port  80          kubernetes ingress nginx  https   github com kubernetes ingress nginx       Option 1  SSL Passthrough  Argo CD serves multiple protocols  gRPC HTTPS  on the same port  443   this provides a challenge when attempting to define a single nginx ingress object and rule for the argocd service  since the  nginx ingress kubernetes io backend protocol   annotation  https   kubernetes github io ingress nginx user guide nginx configuration annotations  backend protocol  accepts only a single value for the backend protocol  e g  HTTP  HTTPS  GRPC  GRPCS    In order to expose the Argo CD API server with a single ingress rule and hostname  the  nginx ingress kubernetes io ssl passthrough   annotation  https   kubernetes github io ingress nginx user guide nginx configuration annotations  ssl passthrough  must be used to passthrough TLS connections and terminate TLS at the Argo CD API server      yaml apiVersion  networking k8s io v1 kind  Ingress metadata    name  argocd server ingress   namespace  argocd   annotations      nginx ingress kubernetes io force ssl redirect   true      nginx ingress kubernetes io ssl passthrough   true  spec    ingressClassName  nginx   rules      host  argocd example com     http        paths          path            pathType  Prefix         backend            service              name  argocd server             port                name  https      The above rule terminates TLS at the Argo CD API server  which detects the protocol being used  and responds appropriately  Note that the  nginx ingress kubernetes io ssl passthrough  annotation requires that the    enable ssl passthrough  flag be added to the command line arguments to  nginx ingress controller         SSL Passthrough with cert manager and Let s Encrypt     yaml apiVersion  networking k8s io v1 kind  Ingress metadata    name  argocd server ingress   namespace  argocd   annotations      cert manager io cluster issuer  letsencrypt prod     nginx ingress kubernetes io ssl passthrough   true        If you encounter a redirect loop or are getting a 307 response code       then you need to force the nginx ingress to connect to the backend using HTTPS            nginx ingress kubernetes io backend protocol   HTTPS  spec    ingressClassName  nginx   rules      host  argocd example com     http        paths          path            pathType  Prefix         backend            service              name  argocd server             port                name  https   tls      hosts        argocd example com     secretName  argocd server tls   as expected by argocd server          Option 2  SSL Termination at Ingress Controller  An alternative approach is to perform the SSL termination at the Ingress  Since an  ingress nginx  Ingress supports only a single protocol per Ingress object  two Ingress objects need to be defined using the  nginx ingress kubernetes io backend protocol  annotation  one for HTTP HTTPS and the other for gRPC   Each ingress will be for a different domain   argocd example com  and  grpc argocd example com    This requires that the Ingress resources use different TLS  secretName s to avoid unexpected behavior   HTTP HTTPS Ingress     yaml apiVersion  networking k8s io v1 kind  Ingress metadata    name  argocd server http ingress   namespace  argocd   annotations      nginx ingress kubernetes io force ssl redirect   true      nginx ingress kubernetes io backend protocol   HTTP  spec    ingressClassName  nginx   rules      http        paths          path            pathType  Prefix         backend            service              name  argocd server             port                name  http     host  argocd example com   tls      hosts        argocd example com     secretName  argocd ingress http      gRPC Ingress     yaml apiVersion  networking k8s io v1 kind  Ingress metadata    name  argocd server grpc ingress   namespace  argocd   annotations      nginx ingress kubernetes io backend protocol   GRPC  spec    ingressClassName  nginx   rules      http        paths          path            pathType  Prefix         backend            service              name  argocd server             port                name  https     host  grpc argocd example com   tls      hosts        grpc argocd example com     secretName  argocd ingress grpc      The API server should then be run with TLS disabled  Edit the  argocd server  deployment to add the    insecure  flag to the argocd server command  or simply set  server insecure   true   in the  argocd cmd params cm  ConfigMap  as described here  server commands additional configuration method md    The obvious disadvantage to this approach is that this technique requires two separate hostnames for the API server    one for gRPC and the other for HTTP HTTPS  However it allows TLS termination to happen at the ingress controller        Traefik  v3 0   https   docs traefik io    Traefik can be used as an edge router and provide  TLS  https   docs traefik io user guides grpc   termination within the same deployment   It currently has an advantage over NGINX in that it can terminate both TCP and HTTP connections  on the same port  meaning you do not require multiple hosts or paths   The API server should be run with TLS disabled  Edit the  argocd server  deployment to add the    insecure  flag to the argocd server command or set  server insecure   true   in the  argocd cmd params cm  ConfigMap  as described here  server commands additional configuration method md        IngressRoute CRD    yaml apiVersion  traefik io v1alpha1 kind  IngressRoute metadata    name  argocd server   namespace  argocd spec    entryPoints        websecure   routes        kind  Rule       match  Host  argocd example com         priority  10       services            name  argocd server           port  80       kind  Rule       match  Host  argocd example com      Header  Content Type    application grpc         priority  11       services            name  argocd server           port  80           scheme  h2c   tls      certResolver  default         AWS Application Load Balancers  ALBs  And Classic ELB  HTTP Mode  AWS ALBs can be used as an L7 Load Balancer for both UI and gRPC traffic  whereas Classic ELBs and NLBs can be used as L4 Load Balancers for both   When using an ALB  you ll want to create a second service for argocd server  This is necessary because we need to tell the ALB to send the GRPC traffic to a different target group then the UI traffic  since the backend protocol is HTTP2 instead of HTTP1      yaml apiVersion  v1 kind  Service metadata    annotations      alb ingress kubernetes io backend protocol version  GRPC   This tells AWS to send traffic from the ALB using GRPC  Plain HTTP2 can be used  but the health checks wont be available because argo currently downgrade non grpc calls to HTTP1   labels      app  argogrpc   name  argogrpc   namespace  argocd spec    ports      name   443      port  443     protocol  TCP     targetPort  8080   selector      app kubernetes io name  argocd server   sessionAffinity  None   type  NodePort      Once we create this service  we can configure the Ingress to conditionally route all  application grpc  traffic to the new HTTP2 backend  using the  alb ingress kubernetes io conditions  annotation  as seen below  Note  The value after the   in the condition annotation  must  be the same name as the service that you want traffic to route to   and will be applied on any path with a matching serviceName      yaml   apiVersion  networking k8s io v1   kind  Ingress   metadata      annotations        alb ingress kubernetes io backend protocol  HTTPS         Use this annotation  which must match a service name  to route traffic to HTTP2 backends        alb ingress kubernetes io conditions argogrpc               field   http header   httpHeaderConfig    httpHeaderName    Content Type    values    application grpc            alb ingress kubernetes io listen ports      HTTPS  443        name  argocd     namespace  argocd   spec      rules        host  argocd argoproj io       http          paths            path              backend              service                name  argogrpc   The grpc service must be placed before the argocd server for the listening rules to be created in the correct order               port                  number  443           pathType  Prefix           path              backend              service                name  argocd server               port                  number  443           pathType  Prefix     tls        hosts          argocd argoproj io          Istio  https   www istio io  You can put Argo CD behind Istio using following configurations  Here we will achieve both serving Argo CD behind istio and using subpath on Istio  First we need to make sure that we can run Argo CD with subpath  ie  argocd   For this we have used install yaml from argocd project as is     bash curl  kLs  o install yaml https   raw githubusercontent com argoproj argo cd stable manifests install yaml      save following file as kustomization yml     yaml apiVersion  kustomize config k8s io v1beta1 kind  Kustomization resources      install yaml  patches    path    patch yml       And following lines as patch yml     yaml   Use   insecure so Ingress can send traffic with HTTP     bashref  argocd is the subpath like https   IP argocd   env was added because of https   github com argoproj argo cd issues 3572 error     apiVersion  apps v1 kind  Deployment metadata   name  argocd server spec   template     spec       containers         args            usr local bin argocd server            staticassets           shared app            redis          argocd redis 6379            insecure            basehref           argocd            rootpath           argocd        name  argocd server        env           name  ARGOCD MAX CONCURRENT LOGIN REQUESTS COUNT          value   0       After that install Argo CD   there should be only 3 yml file defined above in current directory       bash kubectl apply  k     n argocd   wait true      Be sure you create secret for Istio   in our case secretname is argocd server tls on argocd Namespace   After that we create Istio Resources     yaml apiVersion  networking istio io v1alpha3 kind  Gateway metadata    name  argocd gateway   namespace  argocd spec    selector      istio  ingressgateway   servers      port        number  80       name  http       protocol  HTTP     hosts                tls       httpsRedirect  true     port        number  443       name  https       protocol  HTTPS     hosts                tls        credentialName  argocd server tls       maxProtocolVersion  TLSV1 3       minProtocolVersion  TLSV1 2       mode  SIMPLE       cipherSuites            ECDHE ECDSA AES128 GCM SHA256           ECDHE RSA AES128 GCM SHA256           ECDHE ECDSA AES128 SHA           AES128 GCM SHA256           AES128 SHA           ECDHE ECDSA AES256 GCM SHA384           ECDHE RSA AES256 GCM SHA384           ECDHE ECDSA AES256 SHA           AES256 GCM SHA384           AES256 SHA     apiVersion  networking istio io v1alpha3 kind  VirtualService metadata    name  argocd virtualservice   namespace  argocd spec    hosts            gateways      argocd gateway   http      match        uri          prefix   argocd     route        destination          host  argocd server         port            number  80      And now we can browse http    argocd  it will be rewritten to https    argocd      Google Cloud load balancers with Kubernetes Ingress  You can make use of the integration of GKE with Google Cloud to deploy Load Balancers using just Kubernetes objects   For this we will need these five objects    A Service   A BackendConfig   A FrontendConfig   A secret with your SSL certificate   An Ingress for GKE  If you need detail for all the options available for these Google integrations  you can check the  Google docs on configuring Ingress features  https   cloud google com kubernetes engine docs how to ingress features       Disable internal TLS  First  to avoid internal redirection loops from HTTP to HTTPS  the API server should be run with TLS disabled   Edit the    insecure  flag in the  argocd server  command of the argocd server deployment  or simply set  server insecure   true   in the  argocd cmd params cm  ConfigMap  as described here  server commands additional configuration method md        Creating a service  Now you need an externally accessible service  This is practically the same as the internal service Argo CD has  but with Google Cloud annotations  Note that this service is annotated to use a  Network Endpoint Group  https   cloud google com load balancing docs negs   NEG  to allow your load balancer to send traffic directly to your pods without using kube proxy  so remove the  neg  annotation if that s not what you want   The service      yaml apiVersion  v1 kind  Service metadata    name  argocd server   namespace  argocd   annotations      cloud google com neg     ingress   true       cloud google com backend config     ports     http   argocd backend config     spec    type  ClusterIP   ports      name  http     port  80     protocol  TCP     targetPort  8080   selector      app kubernetes io name  argocd server          Creating a BackendConfig  See that previous service referencing a backend config called  argocd backend config   So lets deploy it using this yaml      yaml apiVersion  cloud google com v1 kind  BackendConfig metadata    name  argocd backend config   namespace  argocd spec    healthCheck      checkIntervalSec  30     timeoutSec  5     healthyThreshold  1     unhealthyThreshold  2     type  HTTP     requestPath   healthz     port  8080      It uses the same health check as the pods       Creating a FrontendConfig  Now we can deploy a frontend config with an HTTP to HTTPS redirect      yaml apiVersion  networking gke io v1beta1 kind  FrontendConfig metadata    name  argocd frontend config   namespace  argocd spec    redirectToHttps      enabled  true              note      The next two steps  the certificate secret and the Ingress  are described supposing that you manage the certificate yourself  and you have the certificate and key files for it  In the case that your certificate is Google managed  fix the next two steps using the  guide to use a Google managed SSL certificate  https   cloud google com kubernetes engine docs how to managed certs creating an ingress with a google managed certificate             Creating a certificate secret  We need now to create a secret with the SSL certificate we want in our load balancer  It s as easy as executing this command on the path you have your certificate keys stored       kubectl  n argocd create secret tls secret yourdomain com       cert cert file crt   key key file key          Creating an Ingress  And finally  to top it all  our Ingress  Note the reference to our frontend config  the service  and to the certificate secret           note     GKE clusters running versions earlier than  1 21 3 gke 1600    the only supported value for the pathType field  https   cloud google com kubernetes engine docs how to load balance ingress creating an ingress  is  ImplementationSpecific   So you must check your GKE cluster s version  You need to use different YAML depending on the version        If you use the version earlier than  1 21 3 gke 1600   you should use the following Ingress resource     yaml apiVersion  networking k8s io v1 kind  Ingress metadata    name  argocd   namespace  argocd   annotations      networking gke io v1beta1 FrontendConfig  argocd frontend config spec    tls        secretName  secret example com   rules        host  argocd example com       http          paths            pathType  ImplementationSpecific           path               is needed  Without this  the UI Javascript and CSS will not load properly           backend              service                name  argocd server               port                  number  80      If you use the version  1 21 3 gke 1600  or later  you should use the following Ingress resource     yaml apiVersion  networking k8s io v1 kind  Ingress metadata    name  argocd   namespace  argocd   annotations      networking gke io v1beta1 FrontendConfig  argocd frontend config spec    tls        secretName  secret example com   rules        host  argocd example com       http          paths            pathType  Prefix           path                backend              service                name  argocd server               port                  number  80      As you may know already  it can take some minutes to deploy the load balancer and become ready to accept connections  Once it s ready  get the public IP address for your Load Balancer  go to your DNS server  Google or third party  and point your domain or subdomain  i e  argocd example com  to that IP address   You can get that IP address describing the Ingress object like this       kubectl  n argocd describe ingresses argocd   grep Address      Once the DNS change is propagated  you re ready to use Argo with your Google Cloud Load Balancer     Authenticating through multiple layers of authenticating reverse proxies  Argo CD endpoints may be protected by one or more reverse proxies layers  in that case  you can provide additional headers through the  argocd  CLI    header  parameter to authenticate through those layers      shell   argocd login  host   port    header  x token1 foo    header  x token2 bar    can be repeated multiple times   argocd login  host   port    header  x token1 foo x token2 bar    headers can also be comma separated        ArgoCD Server and UI Root Path  v1 5 3   Argo CD server and UI can be configured to be available under a non root path  e g    argo cd    To do this  add the    rootpath  flag into the  argocd server  deployment command      yaml spec    template      spec        name  argocd server       containers          command             argocd server             repo server           argocd repo server 8081             rootpath            argo cd     NOTE  The flag    rootpath  changes both API Server and UI base URL  Example nginx conf       worker processes 1   events   worker connections 1024     http        sendfile on       server           listen 443           location  argo cd                proxy pass         https   localhost 8080 argo cd               proxy redirect     off              proxy set header   Host  host              proxy set header   X Real IP  remote addr              proxy set header   X Forwarded For  proxy add x forwarded for              proxy set header   X Forwarded Host  server name                buffering should be disabled for api v1 stream applications to support chunked response             proxy buffering off                        Flag      grpc web root path     is used to provide a non root path  e g   argo cd      shell   argocd login  host   port    grpc web root path  argo cd         UI Base Path  If the Argo CD UI is available under a non root path  e g    argo cd  instead of      then the UI path should be configured in the API server  To configure the UI path add the    basehref  flag into the  argocd server  deployment command      yaml spec    template      spec        name  argocd server       containers          command             argocd server             repo server           argocd repo server 8081             basehref            argo cd      NOTE  The flag    basehref  only changes the UI base URL  The API server will keep using the     path so you need to add a URL rewrite rule to the proxy config  Example nginx conf with URL rewrite       worker processes 1   events   worker connections 1024     http        sendfile on       server           listen 443           location  argo cd               rewrite  argo cd        1  break              proxy pass         https   localhost 8080              proxy redirect     off              proxy set header   Host  host              proxy set header   X Real IP  remote addr              proxy set header   X Forwarded For  proxy add x forwarded for              proxy set header   X Forwarded Host  server name                buffering should be disabled for api v1 stream applications to support chunked response             proxy buffering off


argocd Observed generation is equal to desired generation specific types of Kubernetes resources surfaced to the overall Application health status as a whole The following checks are made for Deployment ReplicaSet StatefulSet DaemonSet Resource Health Argo CD provides built in health assessment for several standard Kubernetes types which is then Overview Number of updated replicas equals the number of desired replicas

Answer:
# Resource Health

## Overview
Argo CD provides built-in health assessment for several standard Kubernetes types, which is then
surfaced to the overall Application health status as a whole. The following checks are made for
specific types of Kubernetes resources:

### Deployment, ReplicaSet, StatefulSet, DaemonSet
* Observed generation is equal to desired generation.
* Number of **updated** replicas equals the number of desired replicas.

### Service
* If service type is of type `LoadBalancer`, the `status.loadBalancer.ingress` list is non-empty,
with at least one value for `hostname` or `IP`.

### Ingress
* The `status.loadBalancer.ingress` list is non-empty, with at least one value for `hostname` or `IP`.

### Job
* If job `.spec.suspended` is set to 'true', then the job and app health will be marked as suspended.
### PersistentVolumeClaim
* The `status.phase` is `Bound`

### Argocd App

The health assessment of `argoproj.io/Application` CRD has been removed in argocd 1.8 (see [#3781](https://github.com/argoproj/argo-cd/issues/3781) for more information).
You might need to restore it if you are using app-of-apps pattern and orchestrating synchronization using sync waves. Add the following resource customization in
`argocd-cm` ConfigMap:

```yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
  labels:
    app.kubernetes.io/name: argocd-cm
    app.kubernetes.io/part-of: argocd
data:
  resource.customizations.health.argoproj.io_Application: |
    hs = {}
    hs.status = "Progressing"
    hs.message = ""
    if obj.status ~= nil then
      if obj.status.health ~= nil then
        hs.status = obj.status.health.status
        if obj.status.health.message ~= nil then
          hs.message = obj.status.health.message
        end
      end
    end
    return hs
```

## Custom Health Checks

Argo CD supports custom health checks written in [Lua](https://www.lua.org/). This is useful if you:

* Are affected by known issues where your `Ingress` or `StatefulSet` resources are stuck in `Progressing` state because of bug in your resource controller.
* Have a custom resource for which Argo CD does not have a built-in health check.

There are two ways to configure a custom health check. The next two sections describe those ways.

### Way 1. Define a Custom Health Check in `argocd-cm` ConfigMap

Custom health checks can be defined in
```yaml
  resource.customizations.health.<group>_<kind>: |
```
field of `argocd-cm`. If you are using argocd-operator, this is overridden by [the argocd-operator resourceCustomizations](https://argocd-operator.readthedocs.io/en/latest/reference/argocd/#resource-customizations).

The following example demonstrates a health check for `cert-manager.io/Certificate`.

```yaml
data:
  resource.customizations.health.cert-manager.io_Certificate: |
    hs = {}
    if obj.status ~= nil then
      if obj.status.conditions ~= nil then
        for i, condition in ipairs(obj.status.conditions) do
          if condition.type == "Ready" and condition.status == "False" then
            hs.status = "Degraded"
            hs.message = condition.message
            return hs
          end
          if condition.type == "Ready" and condition.status == "True" then
            hs.status = "Healthy"
            hs.message = condition.message
            return hs
          end
        end
      end
    end

    hs.status = "Progressing"
    hs.message = "Waiting for certificate"
    return hs
```

In order to prevent duplication of custom health checks for potentially multiple resources, it is also possible to
specify a wildcard in the resource kind, and anywhere in the resource group, like this:

```yaml
  resource.customizations: |
    ec2.aws.crossplane.io/*:
      health.lua: |
        ...
```

```yaml
  # If a key _begins_ with a wildcard, please ensure that the GVK key is quoted.
  resource.customizations: |
    "*.aws.crossplane.io/*":
      health.lua: |
        ...
```

!!!important
    Please, note that wildcards are only supported when using the `resource.customizations` key, the `resource.customizations.health.<group>_<kind>`
style keys do not work since wildcards (`*`) are not supported in Kubernetes configmap keys.

The `obj` is a global variable which contains the resource. The script must return an object with status and optional message field.
The custom health check might return one of the following health statuses:

  * `Healthy` - the resource is healthy
  * `Progressing` - the resource is not healthy yet but still making progress and might be healthy soon
  * `Degraded` - the resource is degraded
  * `Suspended` - the resource is suspended and waiting for some external event to resume (e.g. suspended CronJob or paused Deployment)

By default, health typically returns a `Progressing` status.

NOTE: As a security measure, access to the standard Lua libraries will be disabled by default. Admins can control access by
setting `resource.customizations.useOpenLibs.<group>_<kind>`. In the following example, standard libraries are enabled for health check of `cert-manager.io/Certificate`.

```yaml
data:
  resource.customizations.useOpenLibs.cert-manager.io_Certificate: true
  resource.customizations.health.cert-manager.io_Certificate: |
    # Lua standard libraries are enabled for this script
```

### Way 2. Contribute a Custom Health Check

A health check can be bundled into Argo CD. Custom health check scripts are located in the `resource_customizations` directory of [https://github.com/argoproj/argo-cd](https://github.com/argoproj/argo-cd). This must have the following directory structure:

```
argo-cd
|-- resource_customizations
|    |-- your.crd.group.io               # CRD group
|    |    |-- MyKind                     # Resource kind
|    |    |    |-- health.lua            # Health check
|    |    |    |-- health_test.yaml      # Test inputs and expected results
|    |    |    +-- testdata              # Directory with test resource YAML definitions
```

Each health check must have tests defined in `health_test.yaml` file. The `health_test.yaml` is a YAML file with the following structure:

```yaml
tests:
- healthStatus:
    status: ExpectedStatus
    message: Expected message
  inputPath: testdata/test-resource-definition.yaml
```

To test the implemented custom health checks, run `go test -v ./util/lua/`.

The [PR#1139](https://github.com/argoproj/argo-cd/pull/1139) is an example of Cert Manager CRDs custom health check.

Please note that bundled health checks with wildcards are not supported.

## Overriding Go-Based Health Checks

Health checks for some resources were [hardcoded as Go code](https://github.com/argoproj/gitops-engine/tree/master/pkg/health)
because Lua support was introduced later. Also, the logic of health checks for some resources were too complex, so it
was easier to implement it in Go.

It is possible to override health checks for built-in resource. Argo will prefer the configured health check over the
Go-based built-in check.

The following resources have Go-based health checks:

* PersistentVolumeClaim
* Pod
* Service
* apiregistration.k8s.io/APIService
* apps/DaemonSet
* apps/Deployment
* apps/ReplicaSet
* apps/StatefulSet
* argoproj.io/Workflow
* autoscaling/HorizontalPodAutoscaler
* batch/Job
* extensions/Ingress
* networking.k8s.io/Ingress

## Health Checks

An Argo CD App's health is inferred from the health of its immediate child resources (the resources represented in
source control). The App health will be the worst health of its immediate child sources. The priority of most to least
healthy statuses is: `Healthy`, `Suspended`, `Progressing`, `Missing`, `Degraded`, `Unknown`. So, for example, if an App
has a `Missing` resource and a `Degraded` resource, the App's health will be `Missing`.

But the health of a resource is not inherited from child resources - it is calculated using only information about the
resource itself. A resource's status field may or may not contain information about the health of a child resource, and
the resource's health check may or may not take that information into account.

The lack of inheritance is by design. A resource's health can't be inferred from its children because the health of a
child resource may not be relevant to the health of the parent resource. For example, a Deployment's health is not
necessarily affected by the health of its Pods.

```
App (healthy)
└── Deployment (healthy)
    └── ReplicaSet (healthy)
        └── Pod (healthy)
    └── ReplicaSet (unhealthy)
        └── Pod (unhealthy)
```

If you want the health of a child resource to affect the health of its parent, you need to configure the parent's health
check to take the child's health into account. Since only the parent resource's state is available to the health check,
the parent resource's controller needs to make the child resource's health available in the parent resource's status
field.

```
App (healthy)
└── CustomResource (healthy) <- This resource's health check needs to be fixed to mark the App as unhealthy
    └── CustomChildResource (unhealthy)
```
## Ignoring Child Resource Health Check in Applications

To ignore the health check of an immediate child resource within an Application, set the annotation `argocd.argoproj.io/ignore-healthcheck` to `true`. For example:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    argocd.argoproj.io/ignore-healthcheck: "true"
```

By doing this, the health status of the Deployment will not affect the health of its parent Application

Resource Health     Overview Argo CD provides built in health assessment for several standard Kubernetes types  which is then surfaced to the overall Application health status as a whole  The following checks are made for specific types of Kubernetes resources       Deployment  ReplicaSet  StatefulSet  DaemonSet   Observed generation is equal to desired generation    Number of   updated   replicas equals the number of desired replicas       Service   If service type is of type  LoadBalancer   the  status loadBalancer ingress  list is non empty  with at least one value for  hostname  or  IP        Ingress   The  status loadBalancer ingress  list is non empty  with at least one value for  hostname  or  IP        Job   If job   spec suspended  is set to  true   then the job and app health will be marked as suspended      PersistentVolumeClaim   The  status phase  is  Bound       Argocd App  The health assessment of  argoproj io Application  CRD has been removed in argocd 1 8  see   3781  https   github com argoproj argo cd issues 3781  for more information   You might need to restore it if you are using app of apps pattern and orchestrating synchronization using sync waves  Add the following resource customization in  argocd cm  ConfigMap      yaml     apiVersion  v1 kind  ConfigMap metadata    name  argocd cm   namespace  argocd   labels      app kubernetes io name  argocd cm     app kubernetes io part of  argocd data    resource customizations health argoproj io Application        hs          hs status    Progressing      hs message          if obj status    nil then       if obj status health    nil then         hs status   obj status health status         if obj status health message    nil then           hs message   obj status health message         end       end     end     return hs         Custom Health Checks  Argo CD supports custom health checks written in  Lua  https   www lua org    This is useful if you     Are affected by known issues where your  Ingress  or  StatefulSet  resources are stuck in  Progressing  state because of bug in your resource controller    Have a custom resource for which Argo CD does not have a built in health check   There are two ways to configure a custom health check  The next two sections describe those ways       Way 1  Define a Custom Health Check in  argocd cm  ConfigMap  Custom health checks can be defined in    yaml   resource customizations health  group   kind         field of  argocd cm   If you are using argocd operator  this is overridden by  the argocd operator resourceCustomizations  https   argocd operator readthedocs io en latest reference argocd  resource customizations    The following example demonstrates a health check for  cert manager io Certificate       yaml data    resource customizations health cert manager io Certificate        hs          if obj status    nil then       if obj status conditions    nil then         for i  condition in ipairs obj status conditions  do           if condition type     Ready  and condition status     False  then             hs status    Degraded              hs message   condition message             return hs           end           if condition type     Ready  and condition status     True  then             hs status    Healthy              hs message   condition message             return hs           end         end       end     end      hs status    Progressing      hs message    Waiting for certificate      return hs      In order to prevent duplication of custom health checks for potentially multiple resources  it is also possible to specify a wildcard in the resource kind  and anywhere in the resource group  like this      yaml   resource customizations        ec2 aws crossplane io          health lua                        yaml     If a key  begins  with a wildcard  please ensure that the GVK key is quoted    resource customizations           aws crossplane io           health lua                        important     Please  note that wildcards are only supported when using the  resource customizations  key  the  resource customizations health  group   kind   style keys do not work since wildcards       are not supported in Kubernetes configmap keys   The  obj  is a global variable which contains the resource  The script must return an object with status and optional message field  The custom health check might return one of the following health statuses        Healthy    the resource is healthy      Progressing    the resource is not healthy yet but still making progress and might be healthy soon      Degraded    the resource is degraded      Suspended    the resource is suspended and waiting for some external event to resume  e g  suspended CronJob or paused Deployment   By default  health typically returns a  Progressing  status   NOTE  As a security measure  access to the standard Lua libraries will be disabled by default  Admins can control access by setting  resource customizations useOpenLibs  group   kind    In the following example  standard libraries are enabled for health check of  cert manager io Certificate       yaml data    resource customizations useOpenLibs cert manager io Certificate  true   resource customizations health cert manager io Certificate          Lua standard libraries are enabled for this script          Way 2  Contribute a Custom Health Check  A health check can be bundled into Argo CD  Custom health check scripts are located in the  resource customizations  directory of  https   github com argoproj argo cd  https   github com argoproj argo cd   This must have the following directory structure       argo cd     resource customizations          your crd group io                 CRD group               MyKind                       Resource kind                    health lua              Health check                    health test yaml        Test inputs and expected results                    testdata                Directory with test resource YAML definitions      Each health check must have tests defined in  health test yaml  file  The  health test yaml  is a YAML file with the following structure      yaml tests    healthStatus      status  ExpectedStatus     message  Expected message   inputPath  testdata test resource definition yaml      To test the implemented custom health checks  run  go test  v   util lua     The  PR 1139  https   github com argoproj argo cd pull 1139  is an example of Cert Manager CRDs custom health check   Please note that bundled health checks with wildcards are not supported      Overriding Go Based Health Checks  Health checks for some resources were  hardcoded as Go code  https   github com argoproj gitops engine tree master pkg health   because Lua support was introduced later  Also  the logic of health checks for some resources were too complex  so it  was easier to implement it in Go   It is possible to override health checks for built in resource  Argo will prefer the configured health check over the Go based built in check   The following resources have Go based health checks     PersistentVolumeClaim   Pod   Service   apiregistration k8s io APIService   apps DaemonSet   apps Deployment   apps ReplicaSet   apps StatefulSet   argoproj io Workflow   autoscaling HorizontalPodAutoscaler   batch Job   extensions Ingress   networking k8s io Ingress     Health Checks  An Argo CD App s health is inferred from the health of its immediate child resources  the resources represented in  source control   The App health will be the worst health of its immediate child sources  The priority of most to least  healthy statuses is   Healthy    Suspended    Progressing    Missing    Degraded    Unknown   So  for example  if an App has a  Missing  resource and a  Degraded  resource  the App s health will be  Missing    But the health of a resource is not inherited from child resources   it is calculated using only information about the  resource itself  A resource s status field may or may not contain information about the health of a child resource  and  the resource s health check may or may not take that information into account   The lack of inheritance is by design  A resource s health can t be inferred from its children because the health of a child resource may not be relevant to the health of the parent resource  For example  a Deployment s health is not necessarily affected by the health of its Pods        App  healthy      Deployment  healthy          ReplicaSet  healthy              Pod  healthy          ReplicaSet  unhealthy              Pod  unhealthy       If you want the health of a child resource to affect the health of its parent  you need to configure the parent s health check to take the child s health into account  Since only the parent resource s state is available to the health check  the parent resource s controller needs to make the child resource s health available in the parent resource s status  field       App  healthy      CustomResource  healthy     This resource s health check needs to be fixed to mark the App as unhealthy         CustomChildResource  unhealthy         Ignoring Child Resource Health Check in Applications  To ignore the health check of an immediate child resource within an Application  set the annotation  argocd argoproj io ignore healthcheck  to  true   For example      yaml apiVersion  apps v1 kind  Deployment metadata    annotations      argocd argoproj io ignore healthcheck   true       By doing this  the health status of the Deployment will not affect the health of its parent Application