Mastering GitOps: Seamlessly Deploying Your App Across Environments with ArgoCD

Talha Naeem
Emumba
Published in
6 min readOct 9, 2023

--

The combination of three tools for GitOps: argoCD, Git, K8s

If you’re unfamiliar with GitOps, let’s demystify it. GitOps is a comprehensive framework that advocates maintaining the source code for the entire software development process within a Git repository while also exercising version control over it. Within this framework, not only is application code managed as Git source code, but the entire infrastructure code is as well.

Evolution of GitOps

GitOps emerged as an evolution of Infrastructure as Code (IaC) and brings all DevOps practices on top of IaC, significantly reducing operational overhead costs.

Now that we’ve grasped the GitOps framework’s philosophy, let’s delve deeper into “How to Incorporate GitOps into Our Existing Software Development Process?” We’ll explore the tools that enable us to achieve the following goals through GitOps:

  1. Enhanced Collaboration with Development Teams
  2. Automated Release Management for Swift Delivery
  3. CI/CD for Application and Infrastructure Deployment
  4. Version Control for IaC and apply it to Infrastructure
  5. Automation and Application Deployment
  6. Operations Code in Git as Source of Truth; e.g. Configuration Files

GitOps for K8s:

ArgoCD simplifies our journey by providing a declarative tool set encompassing these features. As a GitOps-based solution, it offers the following capabilities:

  1. Automated Delivery and Deployment
  2. Deployment Roll out Strategies
  3. Single Sign-On (SSO) Authentication
  4. Role-Based Access Control (RBAC) Management and Multi-tenancy
  5. Multi-Cluster and Multi-Cloud Deployment
https://blog.searce.com/argocd-gitops-continuous-delivery-approach-on-google-kubernetes-engine-2a6b3f6813c0?gi=f3308421d3f7
ArgoCD: a GitOps tool

In this blog, we will focus on automating the delivery and deployment of applications with ArgoCD.

Getting Started: ArgoCD exclusively works with Kubernetes workloads, offering multiple options for deploying applications on a Kubernetes cluster. These options include:

  1. Kubernetes Manifests
  2. Kustomize
  3. Helm Charts

Note: ArgoCD supports the deployment og applications packaged via Kustomize or Helm Charts.

We will proceed with the Helm charts provided here in the public repository.

A repository of multiple helm charts of an application

Core Resources in ArgoCD:

ArgoCD introduces two custom resources: Application and Application Sets. The Application CRD represents a deployed application instance within an environment, while the Application Set CRD is a set of ArgoCD Applications, offering features such as multi-cluster support, cluster multi-tenancy, and enhanced monorepo support. This flexibility allows you to maintain a single manifest for the entire workload within Argo CD.

Refer to this https://github.com/yapily/helm-charts repository having multiple helm charts, that we are going to deploy using argoCD.

An argoCD application definition mainly consists of source (Repository; where the deployment files are located), destination (Target cluster; where you want to actually deploy it) and project along with the kubernetes essentials.

Let’s examine the process of defining an ArgoCD application for deploying an application from a Helm chart located in a GitHub/GitLab repository:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yapily/helm-charts.git
targetRevision: dev
path: charts/app
destination:
server: https://kubernetes.default.svc
namespace: dev

Let’s now create another application for base helm chart from the repository we have been using:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: base-helm
namespace: argocd
metadata:
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://github.com/yapily/helm-charts.git
targetRevision: main
path: charts/base
destination:
server: https://kubernetes.default.svc
namespace: dev

You can create similar application objects for each Helm chart in the charts/ directory. However, managing multiple manifests for numerous microservices can become overwhelming. To address this challenge, you can leverage ArgoCD Application Sets, offering greater flexibility and ease when deploying, scaling, or updating applications.

Let’s not worry much, we can leverage the argoCD Applications Set, with which we get a lot of more flexibility and comfort while deploying, scaling or updating the applications. To understand with analogy since you are familiar with kubernetes, argoCD Application is like a POD in K8s, while argoCD ApplicationSet is like a Deployment in K8s.

With application set, we get a lot more new features like:

  1. Managing Multiple Kubernetes Clusters with Argo CD from a Central Location
  2. Single Source of Truth for Deploying Multiple Applications from One or Multiple Git Repositories
  3. Enhanced Support for Monorepos
  4. Central Administrative Cluster for Controlling Deployments on Multiple Client Clusters (Supporting Multi-Tenancy)

Here’s how to create an application set for multiple Helm charts in the chart/ directory:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: helms
spec:
generators:
- git:
repoURL: https://github.com/yapily/helm-charts.git
revision: main
directories:
- path: charts/*
template:
metadata:
name: '{{path.basename}}'
spec:
project: default
source:
repoURL: https://github.com/yapily/helm-charts.git
targetRevision: main
path: '{{path}}'
destination:
server: https://kubernetes.default.svc
namespace: dev

By using this application set, you can effortlessly deploy multiple Helm charts with ease, simplifying the management of your application deployments.

Fine-Tuning Your CD Pipeline:

Now, let’s explore how to configure your CD pipelines for updates, delivery/deployment, resource management, and multi-environment deployments.

Control Between Continuous Delivery and Continuous Deployment: CD pipelines fall into two categories:

  1. Continuous Delivery: New updates are made ready for release but require manual intervention/control.
  2. Continuous Deployment: New updates are released and deployed immediately without manual intervention/control.

You can configure the syncPolicy section to enable or disable automated parameters based on your desired CD strategy.

.
.
.
# CD delivery
syncPolicy:
automated: null
# CD deployment
syncPolicy:
automated:
prune: true
selfHeal: true
.
.

During the development phase, components change frequently. Removing a component from your codebase may not remove it from the cluster, as ArgoCD doesn’t delete resources by default when they’re no longer defined in Git. To address this, you can enable the Prune option in automated sync to delete discarded resources from the cluster. Additionally, ArgoCD offers the Self-Heal parameter, acting as a safety control over deployments, automatically reverting manual changes to match the state defined in Git. Here’s an example of how to configure these two amazing parameters:

.
.
spec:
generators:
- git:
repoURL: https://github.com/yapily/helm-charts.git
revision: main
directories:
- path: charts/*
template:
metadata:
name: '{{path.basename}}'
spec:
project: default
syncPolicy:
syncOptions:
- CreateNamespace=true
automated:
prune: true
selfHeal: true
.
.

Multi-Cluster Deployments:

Managing Multiple Environments Centrally using single argoCD

Managing multiple clusters with Argo CD from a single application set involves leveraging the cluster-generator functionality. To add clusters for management, you can create cluster-type secrets, following recommended security practices i.e. IRSA in this case. This mechanism supports multi-tenancy and simplifies the management of multiple clusters from one central location. You can follow the guide to add the EKS clusters in argoCD you want to manage.

Let’s create the application set to deploy one of our helm charts in multiple clusters:

# Multi cluster deployment
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: helms-on-multiple-clusters
spec:
generators:
- clusters: {} # Selects all clusters configured
# For specific cluster, you can select by labels
# selector:
# matchLabels:
# type: 'staging'
template:
metadata:
name: '{{path.basename}}'
spec:
project: default
source:
repoURL: https://github.com/yapily/helm-charts.git
targetRevision: main
path: "charts/base"
destination:
server: https://kubernetes.default.svc
namespace: dev

Wait.. Have you noticed that only one helm chart was deployed on all of your clusters? 😱 All in vain? No

Deploying an app across multiple environments using argoCD

By using the Matrix generator provided by ArgoCD, you can efficiently deploy Helm charts across multiple clusters. Let’s use a Matrix generator provided by argocd that actually combines the parameters templated by multiple generators, iterating through every combination of each generator’s generated parameters formulating like a matrix.

We want the whole deployment architecture to look like shown below, so that our complete application gets deployed accross all environments:

Deploying complete app across multiple environments using argoCD

With the following application set, you are good to deploy all of your helm charts in all of your clusters:


# Multi cluster deployment of all helms
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: all-helms-on-multiple-clusters
spec:
generators:
- matrix:
generators:
- git:
repoURL: https://github.com/yapily/helm-charts.git
revision: main
directories:
- path: charts/*
- clusters: {}

template:
metadata:
name: '{{path.basename}}'
spec:
project: default
source:
repoURL: https://github.com/yapily/helm-charts.git
targetRevision: main
path: '{{path}}'
destination:
server: '{{server}}'
namespace: dev

Conclusion

With GitOps and ArgoCD, you can streamline your application deployment process, enhance collaboration, and maintain control over your infrastructure and applications. We have walked through controlling the deployments from a single SCM for multiple clusters and to start managing multiple environments with ease and centrally, which is basically a core concept of GitOps. This approach offers a robust foundation for managing your software development lifecycle effectively, making it an essential tool for modern DevOps practices.

thanks!!

--

--