Create your FREE Codefresh account and start making pipelines fast. Create Account
Person waving at Argo mascot

Getting Started With GitOps and Argo CD

16 min read

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:

Argo UI Login

After logging in, click the “+ New App” button as shown below:

"Create New App” button

Give your app the name guestbook, use the project default, and leave the sync policy as Manual:

General App Settings

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:

Application Source

For Destination, set cluster to in-cluster and namespace to default:

Application Destination

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:

"Create App" button

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:

App Status - Out Of Sync

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”.

App "Synchronize" page

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!

App Status - In Sync
Hierarchical view of all Kubernetes resources

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!

Resync via UI - OutOfSync status

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.

UI - "App Diff" button

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.

UI - "App Diff" view

Follow the same steps to deploy an application by using the “Sync” button, and we should be back to a healthy app.

UI - App in "Healthy" green status

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.

Tracy P Holmes

Tracy is a self-proclaimed "jackie of all trades" currently learning about all things GitOps. She's a strong believer that open source is like gardening - pay attention to your conditions, and water only when needed.

Leave a Reply

* All fields are required. Your email address will not be published.