Fully Declarative Cloud Infrastructure with ArgoCD

How to get a self-service environment for you developers, securely and effortlessly
November 28, 2023 by
Fully Declarative Cloud Infrastructure with ArgoCD
João Filipe Moura

 ArgoCD is the first tool that enables a fully declarative Continuous Delivery on Kubernetes. However, we've seen it often being used in a way that introduces (at least) one imperative step during the Application setup; this single mistake defeats the purpose of using ArgoCD. 

In case you are unfamiliar with Kubernetes Custom Resource Definition (CRD) and ArgoCD Applications, here is some context: Kubernetes CRD is a mechanism to extend the Kubernetes API; it allows, for example, to define new operations to be performed by a controller. ArgoCD defines an Application CRD that tells Argo where to find the manifests to apply to deploy a given application: which git repository and which folder, along with kustomize or helm parameters. 

There are many options for creating these CRDs, either from the web console, CLI, or by applying an Application Manifest in your Kubernetes cluster.

The first two approaches have one fatal flaw: store the Application records on the infrastructure that can be destroyed; therefore, all the manual steps will have to be performed again unless a backup of the Application manifests is maintained. 

Maintaining such backups is cumbersome and unnecessary, and it breaks the GitOps pattern of having part of the infrastructure definition out of a Git repository.  

Using Application Manifests can be made to work declaratively, but it brings many code replication and maintainability complexities that need to be more worth it existing a fourth and correct approach.

The fourth option is Application Sets. This Custom Resource Definition in Argo was created to allow one single manifest to be used as a template to create Applications based on a given rule. Let's see an example that will make things clear. 

One of the simplest and easiest to understand is the Git Generator (but there are others). It allows you to generate Applications based on a folder structure using path regex rules and gives you access to the path directive that will include the full path that matches the rules so you can use it in the Application spec. 

This is the structure you have defined in your Git repository: One service called app1 and one addon called app2 

services/ 
  app1/ 
    Chart.yaml 
    values.yaml 
    env/ 
      values.yaml 
      secrets.yaml 
addons/ 
  app2/ 
    Chart.yaml 
    values.yaml 
    env/ 
      values.yaml 
      secrets.yaml


On the other hand you have the following CRD defined in ArgoCD 

apiVersion: https://argoproj.io/v1alpha1

kind: ApplicationSet 
metadata: 
  name: general 
  namespace: argocd 
spec: 
  generators: 
  - git: 
      directories: 
      - path: services/**/env 
      - path: addons/**/env 
      repoURL: https://github.com/org/deployments-repo.git
      revision: HEAD 
  template: 
    metadata: 
      name: '{{path[1]}}' 
    spec: 
      destination: 
        namespace: '{{path[0]}}' 
        server: https://kubernetes.default.svc/
      project: '{{path[0]}}' 
      source: 
        helm: 
          releaseName: '{{path[1]}}' 
          valueFiles: 
          - /{{path[0]}}/{{path[1]}}/values.yaml 
          - /{{path}}/values.yaml 
          - /{{path}}/secrets.yaml 
        path: '{{path}}' 
        repoURL: https://github.com/org/deployments-repo.git
        targetRevision: HEAD 
      syncPolicy: 
        automated: 
          selfHeal: false 


The combination of both will render the following Applications CRDs 

apiVersion: argoproj.io/v1alpha1 
kind: Application 
metadata: 
name: app1 
namespace: argocd 
spec: 
destination: 
namespace: services 
server: https://kubernetes.default.svc 
project: services 
source: 
helm: 
releaseName: app1 
valueFiles: 
- /services/app1/values.yaml 
- /services/app1/env/values.yaml 
- /services/app1/env/secrets.yaml 
path: services/app1/env 
repoURL: https://github.com/org/deployments-repo.git 
targetRevision: HEAD 
syncPolicy: 
automated: {} 
--- 
apiVersion: argoproj.io/v1alpha1 
kind: Application 
metadata: 
name: app2 
namespace: argocd 
spec: 
destination: 
namespace: addons 
server: https://kubernetes.default.svc 
project: addons 
source: 
helm: 
releaseName: app2 
valueFiles: 
- /services/app2/values.yaml 
- /services/app2/env/values.yaml 
- /services/app2/env/secrets.yaml 
path: services/app2/env 
repoURL: https://github.com/org/deployments-repo.git 
targetRevision: HEAD 
syncPolicy: 
automated: {} 

 

As you can see, using Argos CRDs, you can define logic and structures for deploying applications quite easily. 

With this approach, the platform team can manage a single or a handful of files and scale the number of Applications effortlessly, enabling a genuine, transparent self-service mechanism for the developers in the organization. 

 

Fully Declarative Cloud Infrastructure with ArgoCD
João Filipe Moura November 28, 2023
Share this post