Managing ArgoCD Application resources

We all reach a point when using ArgoCD where we get it up and running and get really excited about the Declarative GitOps buzzwords that…

Managing ArgoCD Application resources

We all reach a point when using ArgoCD where we get it up and running and get really excited about the Declarative GitOps buzzwords that comes with ArgoCD. However, after deploying ArgoCD on your Kubernetes cluster, the next question arises: How can I keep all my applications manageable?


What is an ArgoCD Application?

A quick summary of what an ArgoCD application is: It is a Custom Resource Definition (CRD) on the Kubernetes cluster hosting the ArgoCD deployment. The CRD contains all the settings for the application, such as:

  • What cluster to deploy to?
  • What Git repository to sync with?
  • Other deployment settings

The application YAML holds all the information needed to deploy your repository’s resources and serves as your application’s lifeline in ArgoCD.


Managing ArgoCD Applications

The simplest approach would be to access the ArgoCD UI, click on “New Application,” and fill in all the required fields. However, as we create more applications, along with other users, this will quickly lead to a mess and undermine the power of a Declarative tool or GitOps. If you lose your ArgoCD instance (e.g., due to cluster failure or namespace deletion), you will lose all your CRDs as well.

So, what better options do we have?

Application-in-application

Since ArgoCD applications are CRDs, they essentially function as Kubernetes resources. The application-in-application approach takes advantage of this by creating an ArgoCD application that syncs with a Git repository. This Git repository contains all your ArgoCD Application CRDs defined as Kubernetes YAMLs.

Whenever a user adds a new application to the repository, ArgoCD will automatically sync it to the ArgoCD namespace. This triggers ArgoCD to add these applications to their controller and monitor them.

Advantages

  • Allow individual teams to manage their applications via Git.
  • Uses the same approach for both applications and the application-in-application.
  • ArgoCD automatically prevents state drift by re-syncing with the repository.

Disadvantages

  • Depending on the number of teams, it requires a lot of Application-in-application objects to separate configuration data (e.g., when every team has its own Git repository to manage applications).
  • You would need a method to configure the initial Application-in-application CRD.

Terraform

Using the Terraform ArgoCD provider, it is also possible to store the ArgoCD applications in a Terraform repository. This repository can be synced either through Terraform Cloud or your own backend.

Terraform automatically syncs when you commit a new or changed application. Additionally, Terraform allows the definition of variables, making it easy to set default values for many configuration properties.

resource "argocd_application" "kustomize" { 
  metadata { 
    name      = "kustomize-app" 
    namespace = "argocd" 
    labels = { 
      test = "true" 
    } 
  } 
 
  spec { 
    project = "myproject" 
 
    destination { 
      server    = "https://kubernetes.default.svc" 
      namespace = "foo" 
    } 
 
    source { 
      repo_url        = "https://github.com/kubernetes-sigs/kustomize" 
      path            = "examples/helloWorld" 
      target_revision = "master" 
    } 
 
    sync_policy { 
      automated { 
        prune       = true 
        self_heal   = true 
        allow_empty = true 
      } 
 
      sync_options = ["CreateNamespace=true"] 
      retry { 
        limit = "5" 
        backoff { 
          duration     = "30s" 
          max_duration = "2m" 
          factor       = "2" 
        } 
      } 
    } 
  } 
}

Advantages

  • Using Terraform enables easy application creation and allows preset variable values.
  • There is no need for an “initial configuration” to be deployed anywhere.
  • Each team can set up additional Terraform repositories with RBAC without gaining access to manage applications in ArgoCD.

Disadvantages

  • If you are not already using Terraform for other purposes, you need to add another tool to your stack.
  • Drift does not automatically get synced because Terraform only checks for differences when a new run is planned or applied.

Application Set

ArgoCD also provides another CRD called ApplicationSet. This resource allows you to define the creation of one or more applications from a single configuration.

For example, suppose you have three Kubernetes clusters: UAT, SBX, and PRD. You need to deploy the same application to all three environments. By using the ApplicationSet, you can define the three target clusters and the application, while utilizing the cluster as a variable.

apiVersion: argoproj.io/v1alpha1 
kind: ApplicationSet 
metadata: 
  name: some-application 
spec: 
  generators: 
  - list: 
      elements: 
      - cluster: cluster-uat 
        url: https://1.2.3.4 
      - cluster: cluster-prd 
        url: https://2.4.6.8 
      - cluster: cluster-sbx 
        url: https://9.8.7.6 
  template: 
    metadata: 
      name: '{{cluster}}-guestbook' 
    spec: 
      project: default 
      source: 
        repoURL: https://github.com/argoproj/argo-cd.git 
        targetRevision: HEAD 
        path: applicationset/some-application/{{cluster}} 
      destination: 
        server: '{{url}}' 
        namespace: some-application

You can also utilize a Git repository’s folder structure to generate applications, or even combine both approaches. For more information about the supported generators, you can refer to the documentation here.

ApplicationSet also supports a Pull Request generator. In a future article, I would like to explore how you can use this generator to easily deploy Review Apps for open PRs.

Advantages:

  • The generator can automatically create applications based on the generator input.
  • You can define the same application configuration for multiple applications, making it easier to enforce your policy.
  • It reduces boilerplate and maintenance for individual applications.

Disadvantages:

  • Creating an ApplicationSet is slightly more complex than creating single applications.
  • You will either need to create multiple ApplicationSets or have a single Git repository for all your Kubernetes resources (which may not always belong together).
  • Applying the ApplicationSet in a GitOps way still requires someone to perform the task, as opposed to creating it through the UI.

Conclusion

I hope this comparison helps you make a decision on how to manage applications in your ArgoCD instance, and I hope it discourages you from relying solely on the UI for making changes.

All three solutions mentioned are viable options, and you can choose what works best for your team based on its size.

Keep in mind that these suggestions are not the only available options, and I would appreciate hearing from you about how you are managing your ArgoCD instance and the number of applications you need to handle.