ArgoCD, a power­ful Git­Ops tool, sim­pli­fies the con­tinu­ous deliv­ery and syn­chron­iz­a­tion of applic­a­tions on Kuber­netes clusters. In this blog post, we focus on deploy­ing ArgoCD with Ter­ra­form on a private Azure Kuber­netes Ser­vice (AKS) cluster. By util­iz­ing Ter­ra­form, we pro­vi­sion the infra­struc­ture and AKS cluster, and then deploy ArgoCD. ArgoCD is con­nec­ted to a repos­it­ory that holds the cluster’s con­fig­ur­a­tion and applic­a­tion defin­i­tions, enabling auto­mated deploy­ments based on changes to the repos­it­ory. This approach ensures that the cluster’s desired state is con­sist­ently maintained.

Why ArgoCD?

ArgoCD provides a declar­at­ive approach to man­aging Kuber­netes deploy­ments. It allows you to define your desired applic­a­tion state in Git, and ArgoCD takes care of ensur­ing that your applic­a­tions are deployed and main­tained accord­ing to that desired state.

We will explore how ArgoCD can be used to man­age net­work policies, deploy addi­tional applic­a­tions such as Cert-Man­ager and Ingress Nginx, handle secrets, and per­form other AKS-spe­cific con­fig­ur­a­tions. This allows for a cent­ral­ized and auto­mated approach to man­aging your AKS cluster, redu­cing manual inter­ven­tion and ensur­ing consistency.

By lever­aging the cap­ab­il­it­ies of ArgoCD, we can auto­mate the deploy­ment of applic­a­tions, enforce ver­sion con­trol, and eas­ily roll back changes if needed. This blog post will guide you through the pro­cess of set­ting up ArgoCD on a private AKS cluster, provid­ing you with a power­ful Git­Ops-based deploy­ment solution.

Pre­par­ing the Infrastructure

Before we can deploy ArgoCD on our private AKS cluster, we need to set up the neces­sary infra­struc­ture. This involves cre­at­ing two resource groups: “Resource Group Deploy­ment” and “Resource Group AKS”.

Cloud Infrastructure Diagramm

Resource Group Deployment

The pur­pose of this resource group is to house the resources required for deploy­ing the private AKS cluster. It includes a Vir­tual Machine (VM) with a Git­Hub run­ner, a Key Vault to securely store secrets, and a Stor­age Account where we will save the Ter­ra­form state for the AKS infrastructure.

Resource Group AKS

The second resource group, “Resource Group AKS,” will con­tain the AKS cluster itself, along with addi­tional resources such as a Key Vault and Stor­age Account that can be used by the AKS cluster. It will also include a Con­tainer Registry to store private images and a private DNS zone for the AKS cluster.

Peered Vir­tual Networks

To estab­lish a dir­ect con­nec­tion to the vir­tual net­work where our private AKS cluster resides, the vir­tual net­works of both resource groups will be peered. This allows for secure com­mu­nic­a­tion between the AKS cluster and other resources in the “Resource Group Deploy­ment” resource group.

Ser­vice Prin­cipal Preparation

Before deploy­ing the AKS cluster, we need to pre­pare a ser­vice prin­cipal. This ser­vice prin­cipal will be assigned the Con­trib­utor role at the sub­scrip­tion level or the Con­trib­utor role on the “Resource Group AKS” to enable AKS resource deploy­ment. Addi­tion­ally, the ser­vice prin­cipal must have the Blob Data Con­trib­utor role on the Stor­age Account in the “Resource Group Deploy­ment” to save the Ter­ra­form state.

Deploy­ment Steps

The first step in the deploy­ment pro­cess is to run a Ter­ra­form script from your local com­puter. This script will deploy the “Resource Group Deploy­ment” and estab­lish the con­nec­tion of the Vir­tual Machine (Git­Hub run­ner) to Git­Hub. Once deployed, we will save the ser­vice prin­cipal ID and secret in the Key Vault for use in the next step.

Next, the AKS resources will be deployed using a Git­Hub Work­flow. The Vir­tual Machine (Git­Hub run­ner) will read the ser­vice prin­cipal secrets from the Key Vault and util­ize them to authen­tic­ate and deploy resources to the “Resource Group AKS” resource group.

GitHub Workflow diagram

We will not go into detail on how to deploy Azure resources with Ter­ra­form, as the pro­cess is fairly straight­for­ward and there are numer­ous examples avail­able. How­ever, it is import­ant to high­light some key con­sid­er­a­tions when deploy­ing the AKS cluster using Terraform.

When deploy­ing AKS, ensure that you enable the neces­sary con­fig­ur­a­tion options to sup­port the desired func­tion­al­ity. These options may include enabling work­load iden­tity, CSI blob driver, OIDC issuer, RBAC (Role-Based Access Con­trol), and spe­cify­ing the admin group ID.

The detailed inform­a­tion how to deploy AKS with Ter­ra­form you can find in the Microsoft documentation

Quick­start: Cre­ate an Azure Kuber­netes Ser­vice (AKS) cluster by using Ter­ra­form – Azure Kuber­netes Ser­vice | Microsoft Learn.

In the example below we poin­ted to the neces­sary con­fig­ur­a­tion options that should be enabled:

configuration options

ArgoCD deploy­ment

Once our AKS cluster is deployed with the neces­sary con­fig­ur­a­tion options enabled, we can pro­ceed with the deploy­ment and con­fig­ur­a­tion of ArgoCD. In this sec­tion, we will focus on the deploy­ment pro­cess and the struc­ture of the ArgoCD repository.

ArgoCD repos­it­ory structure

The ArgoCD deploy­ment requires us to have a repos­it­ory pre­pared with the neces­sary configurations.

Here’s an example of the repository:

ArgoCD repository structure

In this struc­ture, we have a folder named app-of-apps which con­tains the Helm chart for cre­at­ing the “argocd” pro­ject inside ArgoCD. The argocd-project.yaml tem­plate defines the pro­ject and its con­fig­ur­a­tion. An ArgoCD pro­ject serves as a logical group­ing of applic­a­tions and provides a way to organ­ize and man­age them within ArgoCD. It allows for fine-grained access con­trol and enables dif­fer­ent levels of per­mis­sions for dif­fer­ent teams or users.

Addi­tion­ally, the argocd-applications.yaml tem­plate points to the argocd-apps Helm chart. The argocd-apps folder con­tains the Helm chart for the argocd-apps applic­a­tion. An ArgoCD applic­a­tion rep­res­ents a spe­cific deploy­ment or con­fig­ur­a­tion that needs to be man­aged by ArgoCD. In this case, the argocd-apps applic­a­tion includes tem­plates for vari­ous applic­a­tions required to run ArgoCD, such as argocd, argocd-con­fig, argo-work­flows, argo-events, external-oper­at­ors, cert-man­ager, ingress-nginx, and more.

When ArgoCD syn­chron­izes with the repos­it­ory, it will auto­mat­ic­ally deploy these applic­a­tions and con­fig­ur­a­tions onto the AKS cluster, ensur­ing that the desired state of the cluster is main­tained. This allows for a declar­at­ive approach to man­aging the infra­struc­ture and applic­a­tions, where changes made to the repos­it­ory are auto­mat­ic­ally reflec­ted in the deployed environment.

nested dependencies between applications in ArgoCD

This dia­gram shows an example of the nes­ted depend­en­cies between applic­a­tions in ArgoCD.

Using the sug­ges­ted repos­it­ory struc­ture as a blue­print, you can adapt and extend it to suit the spe­cific needs of your project.

Deploy­ing ArgoCD helm chart with Terraform

The ArgoCD applic­a­tion serves as the core com­pon­ent of our deploy­ment pro­cess. Once we have pro­vi­sioned the AKS infra­struc­ture, the next step is to deploy ArgoCD, which will seam­lessly syn­chron­ize with the repos­it­ory and deploy all the neces­sary applic­a­tions and con­fig­ur­a­tions. To stream­line the deploy­ment of ArgoCD using Ter­ra­form, we can lever­age the helm_release resource. Below is an example illus­trat­ing this approach. Please note that it’s cru­cial to ensure that the ver­sion of ArgoCD spe­cified in the Ter­ra­form script matches or is com­pat­ible with the ver­sion spe­cified in the chart.yaml file of the argocd-helm in the repository.

helm_release

Con­nect­ing repos­it­ory to ArgoCD

To con­fig­ure the private repos­it­ory for ArgoCD syn­chron­iz­a­tion, we can use the Ter­ra­form resource kubernetes_secret. This resource allows us to cre­ate Kuber­netes secrets dir­ectly using Terraform.

Here’s an example of how we can use the kubernetes_secret resource to con­fig­ure the repos­it­ory for ArgoCD synchronization:

kubernetes_secret

The label “argocd.argoproj.io/secret-type” = “repos­it­ory” in the metadata sec­tion instructs ArgoCD to treat this secret as the repos­it­ory con­nector, res­ult­ing in its imme­di­ate addi­tion to the list of avail­able repositories.

Deploy­ing the first ArgoCD application

Now that we have suc­cess­fully con­nec­ted the repos­it­ory to ArgoCD, we can pro­ceed with cre­at­ing our first applic­a­tion that will util­ize the app-of-apps Helm chart. While we have briefly men­tioned the repos­it­ory struc­ture earlier, let’s dive into it in more detail since ArgoCD plays a cent­ral role in our deploy­ment process.

ArgoCD is already installed on the AKS cluster, but it requires spe­cific con­fig­ur­a­tion and syn­chron­iz­a­tion with the repos­it­ory. To estab­lish this con­nec­tion, we need to cre­ate an ArgoCD applic­a­tion. This applic­a­tion will encom­pass cru­cial inform­a­tion such as the repos­it­ory details, the applic­a­tion type (helm, kus­tom­ize, or plain YAML files), and any val­ues files required for cus­tom­iz­a­tion. Since we are util­iz­ing helm charts in our deploy­ment, we must provide a val­ues file con­tain­ing all the neces­sary cus­tom­iz­a­tion prop­er­ties for the applic­a­tions within our repository.

To sim­plify applic­a­tion man­age­ment and con­fig­ur­a­tion, we have organ­ized the argocd applic­a­tion and its cor­res­pond­ing con­fig­ur­a­tion into sep­ar­ate helm charts: argocd-helm and argocd-config, respect­ively. Once we add the first applic­a­tion, app-of-apps, to ArgoCD, it will auto­mat­ic­ally syn­chron­ize with the repos­it­ory and ini­ti­ate the applic­a­tion deploy­ment process.

To deploy the first applic­a­tion using Ter­ra­form, we can lever­age the kubernetes_manifest resource. This resource enables us to apply Kuber­netes mani­fests dir­ectly through Ter­ra­form, stream­lin­ing the deploy­ment process.

Here’s an example of how we can use the kubernetes_manifest resource to cre­ate the first applic­a­tion in ArgoCD:

kubernetes_manifest

As ArgoCD syn­chron­izes with the repos­it­ory, it will detect the changes in the app-of-apps chart and auto­mat­ic­ally ini­ti­ate the deploy­ment pro­cess for all the applic­a­tions spe­cified within it. This allows us to define and man­age our entire AKS infra­struc­ture and related applic­a­tions using Git­Ops principles.

Man­aging AKS with Git­Ops and ArgoCD

The core concept behind our approach is to util­ize ArgoCD as the cent­ral con­fig­ur­a­tion tool for our AKS cluster. Rather than manu­ally apply­ing policies and con­fig­ur­ing applic­a­tions, we can lever­age ArgoCD’s auto­ma­tion cap­ab­il­it­ies to ensure con­sist­ency and reli­ab­il­ity through­out the deploy­ment process.

With ArgoCD, we can define AKS con­fig­ur­a­tions such as net­work policies, secur­ity policies, roles, secrets, and more as ArgoCD applic­a­tions. These applic­a­tions encap­su­late all the neces­sary con­fig­ur­a­tion details, includ­ing the repos­it­ory and cus­tom­iz­a­tion val­ues. The repos­it­ory itself can con­tain plain YAML Kuber­netes mani­fests or be a Helm chart with con­fig­ur­able val­ues, allow­ing us to reuse the same applic­a­tion defin­i­tion with dif­fer­ent configurations.

By struc­tur­ing our applic­a­tions within ArgoCD’s app-of-apps or nes­ted applic­a­tions, we can main­tain a declar­at­ive approach to applic­a­tion deploy­ment. This enables us to eas­ily man­age updates and roll­backs, ensur­ing that our AKS cluster remains in the desired state at all times.

Con­clu­sion

Using ArgoCD as the cent­ral con­fig­ur­a­tion tool not only sim­pli­fies the deploy­ment pro­cess but also pro­motes con­sist­ency and reli­ab­il­ity. By defin­ing AKS con­fig­ur­a­tions as ArgoCD applic­a­tions, we can enforce desired policies, eas­ily track changes, and revert to pre­vi­ous con­fig­ur­a­tions if needed.

With ArgoCD’s auto­ma­tion cap­ab­il­it­ies, man­aging AKS con­fig­ur­a­tions becomes more effi­cient, allow­ing us to focus on deliv­er­ing applic­a­tions rather than manual con­fig­ur­a­tion tasks. As a res­ult, we can accel­er­ate the deploy­ment pro­cess, reduce human errors, and ensure a high level of con­sist­ency and reli­ab­il­ity through­out our AKS cluster.