Today we are going to explore getting started using Argo CD. This post is going to assume you know a bit about containers, and that you already have an empty cluster in place (or know how to create one). If any of this is unfamiliar, head over to Understanding the Basics to get a bit of practice. Before we get started, let’s talk about GitOps.
What is GitOps?
If you are not familiar with GitOps, head over to https://opengitops.dev which is the official page of the GitOps working group. In short, GitOps is a paradigm that incorporates best practices applied to the application development workflow all the way to the operating infrastructure of a system. The principles of GitOps are the following:
- The system is described in a declarative manner.
- The definition of the system is versioned and audited. This tends to be Git.
- A software agent automatically pulls the Git state and matches the platform state.
- The state is continuously reconciled. This means that any changes happening in Git should also be reflected in the system.
A GitOps tool that follows this approach of a Git-based workflow is Argo CD. It’s a continuous delivery tool for Kubernetes that is essentially a GitOps controller that does two-way synchronization. Argo continuously monitors running applications, compares the live state against the desired state in Git, and applies it to the cluster. Please note this monitoring is for both directions: Git > cluster AND cluster > Git!
GitOps relies on Git as the single source of truth for declarative configuration and active reconciliation. What does this mean?
This means Argo CD implements active reconciliation by automatically monitoring your cluster and detecting any manual changes that are not in the Git state. Adopting the GitOps methodology provides transparency between the application configuration deployed in a cluster and the one residing in Git.
Additionally, some benefits of GitOps are deploying faster and more often, easier and quicker error handling and recovery, and self-documenting deployments. And most importantly? You also get the complete elimination of configuration drift. These benefits make it easier to handle the applications and allow teams to deliver quality software faster.
Prerequisites
For this exercise, you can absolutely use a local cluster such as Docker Desktop, minikube, k3s, etc. And if you have access to a cloud cluster? That’s even better.
However, if you don’t have access to those things, let’s make sure we have kubectl installed. kubectl
is a Kubernetes command-line tool that allows you to run commands against Kubernetes clusters.
We also need a kubeconfig
file. If you already have an empty cluster, then that part of things has most likely already been done for you! In case you want to check, the default location for the config file is ~/.kube/config
Install Argo CD
Let’s start off by installing Argo CD. To do this, we’ll first create a new namespace, argocd
, where Argo CD services and application resources will live.
kubectl create namespace argocd
Next, let’s apply our resource configuration file on the argocd
namespace we just created.
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Once your installation completes, you can use the watch command to check the status of your Kubernetes pods and make sure they are ready.
watch kubectl get pods -n argocd
Since we are using a stock Argo CD installation, you should see five pods with a Running
status.
NAME READY STATUS RESTARTS AGE argocd-redis-d486999b7-cd275 1/1 Running 0 8m57s argocd-dex-server-65bf5f4fc7-p6kv8 1/1 Running 0 8m57s argocd-repo-server-8465d84869-z4mqb 1/1 Running 0 8m57s argocd-application-controller-0 1/1 Running 0 8m56s argocd-server-87b47d787-pbnw8 1/1 Running 0 8m57s
Once things are up and running, you can use Ctrl+C
to exit the watch interface. This is only one of the possible ways to install Argo CD! You are also able to use a Helm chart or a smart installer like Argo Autopilot.
Access The Argo CD API Server
By default, the Argo CD API server is not exposed with an external IP. For the purposes of this post, we are going to utilize kubectl port-forwarding to connect to the API server without actually exposing the service. We do that using
kubectl port-forward svc/argocd-server -n argocd 8080:443
This will make things easier for us as we can now access the API server using localhost:8080
. Note: this method is only for local development or demonstration purposes.
There are two other techniques you can use to access the API server: Service Type Load Balancer and Ingress. If you’d like to learn more about those methods, definitely check out the Getting Started guide for more information.
Download Argo CD CLI
Now that we’ve gotten Argo CD downloaded, installed, and configured for access, it is time to login. There are two ways we can get this done: via the UI (or web interface) and the CLI. The UI and the CLI are mostly similar in capabilities. The CLI is great for changing settings and working with your Argo CD instance. Also, while you can deploy an application using the web interface, it’s typically quicker to deploy via the command line. I tend to use both depending on what I need. We will use both throughout this post.
I also work across different operating systems, so Homebrew is usually my goto installation method as it is available for Linux, Mac, and WSL. To install Argo CD using Homebrew, you will use the following:
brew install argocd
and check that it has installed correctly using
argocd version
You can also download the latest Argo CD version from https://github.com/argoproj/argo-cd/releases/latest. If you run into any issues, more detailed installation instructions can be found via the CLI installation documentation.
Login Using The CLI
We are going to login using an admin account. The initial password for this account is auto-generated and stored in your namespace as clear text in the field password and in a secret named argocd-initial-admin-secret
. Let’s retrieve this password using kubectl
:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo
I’ve added && echo
to the end of that command to make it easier for us to copy & paste the generated password. Make sure to save it, as we will need it in the next steps.
Now that we have that password, we can login! So, let’s do that using
argocd login <ARGOCD_SERVER>
You will substitute Argo CD’s IP or hostname where you see <ARGOCD_SERVER>
in that command. Remember when we set up port forwarding for easy access earlier in this post? Now it will come in handy!
argocd login localhost:8080
This will prompt you for a username and password. The default username is admin
, and the password is the one we exposed up above. You will not see the password while entering it.
We also want to change the password while we’re here as the generated one was in cleartext, and that’s not safe. The following command will ask you for your current password, the new password you’d like to use, and lastly, to confirm the new password.
argocd account update-password
Once you do so, make sure to place your new password somewhere safe, as you will need it.
Create An Application From A Git Repository
In order for us to create an application to demonstrate how Argo CD works, we are going to use an example repository containing a guestbook application. If you would like to check it out or follow along, it is available at https://github.com/argoproj/argocd-example-apps.git.
Remember how I said earlier there are two ways we can get things done? You can definitely use one or the other (or both!) according to personal preference. I am a big fan of using the UI when first learning something in order to get a better idea of things I can do. So let’s start there to create our app.
Creating Apps Via UI
Open a browser to the Argo CD external UI by visiting localhost:8080
, and login using the admin credentials we set up earlier. Your login page should look similar to this:
After logging in, click the “+ New App” button as shown below:
Give your app the name guestbook
, use the project default
, and leave the sync policy as Manual
:
Connect the https://github.com/argoproj/argocd-example-apps.git repo to Argo CD by setting repository URL to the GitHub repo URL, leave revision as HEAD
, and set the path to guestbook
:
For Destination, set cluster to in-cluster
and namespace to default
:
We use in-cluster
because when deploying internally (i.e. to the same cluster that Argo CD is running in), the https://kubernetes.default.svc
hostname should be used as the application’s Kubernetes API server address.
After filling out the information above, click Create at the top of the UI to create the guestbook application:
Creating Apps Via CLI
To create that same app using the CLI, you would use
argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default
When I do use the CLI, I still like to double-check myself using the UI occasionally. Do whichever is comfortable for you!
7. Sync (Deploy) The Application
Syncing via UI
Once the guestbook application is created, you can now view its status:
As you can see, the application status is OutOfSync
! OutOfSync
means the git state is different from the cluster state. You can see this information in multiple ways while in the UI. When the state is not in sync, you can usually tell as it is in a helpful yellow color. You can also filter by status on the left side of the dashboard. I highly recommend poking around the dashboard to see which configuration works for you!
That said, the application status is initially in OutOfSync
state since the application has yet to be deployed. Also, no Kubernetes resources have been created. To sync (deploy) the application, we’ll use the “Sync” button.
This will bring up a second set of options. Select “Synchronize”.
Synchronizing is how we deploy the application. When we “Sync” or “Synchronize”, it means we are updating the cluster state to match the Git state. This is one of the most important tenets of GitOps.
Once things are complete and you return to the dashboard, you will see the guestbook app is now running. Select the app and see what information you can find!
If you click on the application name, you will see a hierarchical view of all the Kubernetes resources that take part in the application. You will also see additional details related to the health and synchronization status.
Syncing via CLI
Of course, everything we have done via the UI, can be done via CLI. Since we created the guestbook application, you can now check the status of your application using argocd app get
:
argocd app get guestbook
Name: guestbook Project: default Server: https://kubernetes.default.svc Namespace: default URL: https://localhost:8080/applications/guestbook Repo: https://github.com/howmybrainworks/argocd-example-apps.git Target: Path: guestbook SyncWindow: Sync Allowed Sync Policy: <none> Sync Status: OutOfSync from (13b08f1) Health Status: Missing GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE Service default guestbook-ui OutOfSync Missing apps Deployment default guestbook-ui OutOfSync Missing
If you look at the “Sync Status” you will see the application status is initially in OutOfSync
state since the application has yet to be deployed, and no Kubernetes resources have been created. To sync (deploy) the application, run:
argocd app sync guestbook
Modifying and redeploying the Application
Here is where I feel Argo CD really shines. Now that we have a healthy system, let’s initiate a change. Let’s scale the deployment by modifying the replicas in the deployment.yaml
file.
In the deployment.yaml
file, increase the number of replicas from 1 to 2. Since we are following GitOps, we want our modification to be declarative. So, we are going to commit and submit this change via Git. This will show things OutOfSync
as well as identify configuration drift.
Resyncing (redeploying) via UI
If you go back to the UI, you should now see that we are now once again OutOfSync
!
I sincerely love this feature, because not only does Argo CD let us know the application is no longer in sync, it also gives you a nice “App Diff” view to give more detail about what was changed! Click on the application name again, and you will see this option at the top of the page.
Now, the default “Diff” view can potentially contain an enormous amount of information, so I like to select the “Compact Diff” option in order to immediately see any changes. As you can see, we increased our replicas from 1 > 2.
Follow the same steps to deploy an application by using the “Sync” button, and we should be back to a healthy app.
Resyncing (redeploying) via CLI
Let’s initiate another change. Let’s scale the deployment by modifying the number of replicas using kubectl
.
Using kubectl
, decrease the number of replicas from 2 to 1. You’ll do this using
kubectl scale --current-replicas=2 --replicas=1 deployment/guestbook-ui
Follow the same steps as above to retrieve our application status using
argocd app get guestbook
Name: guestbook Project: default Server: https://kubernetes.default.svc Namespace: default URL: https://localhost:8080/applications/guestbook Repo: https://github.com/howmybrainworks/argocd-example-apps.git Target: Path: guestbook SyncWindow: Sync Allowed Sync Policy: <none> Sync Status: OutOfSync from (13b08f1) Health Status: Healthy GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE Service default guestbook-ui Synced Healthy service/guestbook-ui created apps Deployment default guestbook-ui OutOfSync Healthy deployment.apps/guestbook-ui created
If you check your output, you will again see we are OutOfSync
. In order to see what’s changed, you’ll use argocd app diff
:
argocd app diff guestbook
===== apps/Deployment default/guestbook-ui ====== 109c109 < replicas: 1 -- > replicas: 2
Run the sync command once again to deploy:
argocd app sync guestbook
Everything should be back healthy and in order!
Conclusion
As you can see, adopting GitOps is beneficial in many ways! Among other things, you gain faster and more frequent deployments, the ability to avoid configuration drift, and easier error handling. This is shown especially when coupled with Argo CD as it can help leverage your deployment process by performing commits automatically and can also execute rollbacks if there are any issues.
Argo CD is great by itself, but it is even better when connected to other Argo projects such as Argo Workflows, Rollouts, or Events. Combined with any of these, you can elevate your continuous deployment process.