Kubernetes on AWS - Continuous Deployment with Argo CD

Introduction

In this blog post, we will install Argo CD. Argo CD is a continuous delivery tool for Kubernetes which follows the GitOps paradigm. That means, we will store application configurations in git repositories. Argo CD watches the repositories and deploys the applications to the Kubernetes cluster.
Argo CD is installed as a Kubernetes workload and ships custom resource definitions to store its configuration in Kubernetes. One of these resources is called Application. An Application has a source e.g. a path in a git repository and a Kubernetes cluster as a destination. We will create our Applications as yaml files or via Argo CD’s web dashboard.

Prerequisites

Kubernetes on AWS - From Zero To Production
  • A running Kubernetes cluster. Look into the below blog post for a setup guide on AWS.
Kubernetes on AWS - EKS Setup with Terraform
  • kubectl
  • git clone git@github.com:canida-software/k8s-on-aws.git

Argo CD Setup

We will bootstrap Argo CD from the applications/argocd folder. The directory is a kustomize directory. Kustomize is a solution to manage and customize Kubernetes configurations which is built into kubectl.
Please adapt at least the following files before following along:
argocd.yaml: Contains the resource definition for an Argo CD Application that manages our Argo CD app. Applying the Application will allow Argo CD to manage changes to itself.
ingress.yaml: Contains an ingress for Argo CD. This will be useful at a later stage to access Argo CD via a public web page after we installed a controller which spawns the corresponding load balancer. The ingress.yaml assumes an AWS Load Balancer Controller which we will install in a follow-up blog post.
 
We use the --kustomize or -k flag to apply the argocd kustomize directory. We first apply the argocd/bootstrap folder to install the custom resource definitions (CRDs). Then in a next step, we can install the custom resources (CRs) so that Argo CD can manage itself.
# Skip this if you already cloned the repository for the Kubernetes setup.
git clone git@github.com:canida-software/k8s-on-aws.git

cd ./k8s-on-aws/applications


kubectl apply -k argocd/bootstrap
kubectl apply -k argocd

Argo CD Web Dashboard

Argo CD ships with a web dashboard. However, unless you already installed a load balancer controller it is not yet publicly available. Instead, use a port forward to access the dashboard for now.
kubectl port-forward -n argocd service/argocd-server 8080:80
 
Dashboard Access:
url: localhost:8080
user: admin
password: Stored in a Kubernetes secret. Retrieve it via: kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

Configure Repository Access

Argo CD can use different methods to access your git repository. We choose to connect our Repository via SSH. Generate the SSH key via: ssh-keygen -t ed25519 -C "argocd@canida.io" -f my_ed25519_key. Then, store the public key my_ed25519_key.pub in your Github repo as a deploy key.
 
notion image
Afterwards, store the private key at Settings → Repositories → Connect Repo Using SSH to enable Github access.
notion image
After you press connect Argo CD will tell you if it could connect to your repository.
notion image
 
Lastly, you can go back to your applications and refresh argocd. Then Argo CD will check the git repository for updates to the argocd application and trigger a sync afterwards. If the sync succeeds Argo CD successfully manages itself.
notion image
Don’t worry if the sync succeeds but the state of argocd is still Progressing. The reason is that Argo CD performs health checks for resources to check that they were deployed successfully. However, the ingress is not recognized as healthy yet because we did not install a load balancer controller to spawn load balancers for our ingress resources. Therefore, status.loadBalancer.ingress is empty.

Kustomize vs Helm

Argo CD can deploy Kubernetes manifests via Kustomize or Helm. I prefer to use Kustomize over Helm for managing my own configurations. Helm: We deploy some external applications via Helm charts simply because its the advised and tested installation method. However, we don’t need most of Helm’s features. In this GitOps-based setup releases and rollbacks are managed via git instead of Helm. Additionally it’s hard to share configurations between environments.
Kustomize: A lightweight tool already built into kubectl to manage configurations. You need to put some thought into the directory setup (blogpost for inspiration). Afterward, its pretty simple to share configurations between environments.