Skip to content

4.7. Deploying With ArgoCD (GitOps)

When to Read This Chapter

  • When deployment history has to be kept in Git so you can trace who changed what and when
  • When you want to keep the cluster state from deviating from what was defined
  • When deploying the same application to several environments (development, staging, production)
  • When you want to control deployment permission through a Git approval process

What GitOps Is

GitOps is the approach of writing down in a Git repository what should be running in the cluster and having a tool match it.

In the approaches so far, a person or a CI tool sends a command to the cluster: "switch to this image". GitOps is the reverse. You write the desired state in Git, and a tool inside the cluster reads it and matches it itself.

Three things follow from that difference.

PropertyDescription
History is keptA Git commit is the deployment record. Who changed what and when remains
Rolling back is easyReverting to an earlier commit returns the cluster to that state
Deviations are correctedEven if someone edits the cluster directly, it is returned to the state written in Git

What ArgoCD Is

ArgoCD is the program that actually performs GitOps. It runs inside the cluster and repeats the following.

  1. Reads the designated Git repository periodically.
  2. Compares the state written there with the cluster's current state.
  3. If they differ, matches the Git side (automatically, or when a person selects it, depending on the settings).

COP installs ArgoCD as a cluster component. There is nothing to prepare separately.

How It Differs From the Deployments So Far

So far (chapters 4.2-4.6)ArgoCD (this chapter)
What triggers the deploymentA person selects a button, or a CI tool issues a commandA change in the Git repository
Who edits the clusterPushed in from outside with kubectlArgoCD inside the cluster pulls it in itself
Cluster access permissionThe CI tool must have itThe CI tool does not need it (only Git write access)
Deployment historyDeployment revisionsGit commit history
Settings edited by handRemain as they areAre reverted (depending on the settings)

Not having to give cluster credentials to the CI tool matters a great deal. The CI tool only writes to Git, and only ArgoCD holds cluster permissions.

It Uses Two Repositories

GitOps separates the source repository from the configuration repository.

RepositoryWhat it holdsWho edits it
Source repository (egov)Application source codeDevelopers
Configuration repository (egov-argocd)Deployment YAML for Deployments, Services, and so onThe deployment tool, or operations staff

The reason for separating them is that their change frequency and approval processes differ. Source changes several times a day, while deployment configuration changes rarely. Separated, "what is deployed in production" can be seen from the configuration repository alone, and deployment approval can be controlled through merge requests on that repository.

The Overall Flow

ArgoCD GitOps deployment flow

The first half is the same as before. Up to building and pushing to the registry, the scripts from 4.5 are used unchanged. What differs is what comes after — instead of editing the cluster directly with build-deploy.sh, you edit the image tag in the configuration repository and push it.

COP includes a script that does this. It generates the image tag from the source repository, changes the image value in deployment.yaml in the configuration repository, and commits and pushes, all in one go.

Adopting the Scripts for Your Own Project

The ArgoCD scripts are created only for the sample application. They appear at the path below during installation, and are not created for other applications.

Where the ArgoCD scripts are created

With a default install path of /data, that is /data/workspaces/apps/egov/egov/.

The Jenkins New Project Job Does Not Create These Scripts

The Jenkins new project job unpacks only the build and deploy script bundle. That bundle contains the following seven items, and the ArgoCD scripts are not included.

What the new project job createsWhat it does not create
env.sh · build-app.sh · build-push.sh · build-deploy.sh · build-history.sh · build-rollback.sh · values.yamlcreate-*-argocd.sh · deploy-*-argocd.sh · sync-*-argocd.sh · glab_git_push-argocd.sh · git-argocd/

The new project job only substitutes the namespace, Deployment name, and Git URL in env.sh from your inputs. To use ArgoCD, you have to copy the sample's scripts and edit them yourself.

The Jenkins ArgoCD deploy Job (70-egov-argocd-deploy) is also sample-only. To use it for another project, clone that Job and change the paths and script names.

Steps for Copying and Using Them

Suppose you are deploying an application called my-app to the my-ns namespace.

1. Copy the scripts.

SRC=<install path>/workspaces/apps/egov/egov
DST=<install path>/workspaces/apps/my-ns/my-app

cp $SRC/create-egov-argocd.sh $DST/create-my-app-argocd.sh
cp $SRC/deploy-egov-argocd.sh $DST/deploy-my-app-argocd.sh
cp $SRC/sync-egov-argocd.sh $DST/sync-my-app-argocd.sh
cp $SRC/glab_git_push-argocd.sh $DST/glab_git_push-argocd.sh
cp -r $SRC/git-argocd $DST/git-argocd
chmod +x $DST/*.sh

2. Change the names inside the scripts. The sample names are embedded in several places.

FileWhat to change
create-my-app-argocd.shThe ArgoCD application name, the configuration repository URL, the target namespace
deploy-my-app-argocd.shThe source repository path, the configuration repository path, the container name, the image address
sync-my-app-argocd.shThe ArgoCD application name
glab_git_push-argocd.shThe configuration repository path and remote URL

Be sure to check the container name in deploy-*.sh. This script changes the image value of the container whose name matches in deployment.yaml. The sample's container name is egov, so leaving it unchanged means my-app's image is not changed — and it passes silently, without an error.

3. Edit the YAML in the configuration repository. In deployment.yaml, service.yaml, and ingress.yaml under git-argocd/, adjust names, namespace, ports, and addresses to your application.

4. Create and push the configuration repository.

cd $DST
./glab_git_push-argocd.sh

5. Register it with ArgoCD. This is a one-time step that registers the repository and the application.

./create-my-app-argocd.sh

That is the preparation. From then on, deployment takes these two lines.

./deploy-my-app-argocd.sh # writes the new image tag into the configuration repository
./sync-my-app-argocd.sh # only when you want it applied immediately (can be skipped with automatic sync)

Putting It in a CI Tool

These are shell scripts too, so any CI tool can call them (see 4.6). You only replace the deployment stage after the build.

# before (edits the cluster directly)
- cd $APP_DIR && ./build-deploy.sh

# ArgoCD (edits the configuration repository)
- cd $APP_DIR && ./deploy-my-app-argocd.sh

Do not keep both build-deploy.sh and deploy-*-argocd.sh. The former edits the cluster directly and the latter edits Git. With both running and self-healing enabled, deployments oscillate.

If This Is Too Cumbersome

Rather than copying and editing scripts, the essence is changing the image tag in the configuration repository and committing it. If you have a standard CI tool internally, you can do the same thing with that tool's Git integration. The scripts are a starting point showing one way to do it.

Three Ways to Deploy

Method 1 — Selecting It on the ArgoCD Screen

  1. Connect to the ArgoCD screen. Ask operations staff for the address and account.
  2. Choose the application.
  3. Select SYNC.

This applies the state written in Git to the cluster. You can preview what will change, which suits first use.

Method 2 — Running It From a CI Tool

Among the Jenkins Jobs COP provides by default there is an ArgoCD deploy Job. Its content is one line: the script that edits the image tag in the configuration repository and pushes. With another CI tool, call the same script (see 4.6).

Method 3 — Running It From the Command Line

The argocd command is available on the Bastion. Running the sync script is the same as selecting SYNC on the screen.

argocd app sync <application name> # synchronize
argocd app wait <application name> # wait until it finishes
argocd app get <application name> # check status

The Three Automatic Sync Settings

Applications created by COP have automatic sync enabled. Three settings are configured together.

SettingWhat it doesWhat changes when it is on
Automatic syncApplies Git changes without anyone selecting a buttonA push becomes a deployment
Automatic pruningDeletes resources from the cluster when they are removed from GitDeleting YAML removes the actual resource
Self-healingReverts direct cluster edits to the Git stateSomething changed with kubectl disappears shortly after

With self-healing on, editing the cluster directly is pointless. For example, raising the replica count in the Console returns to the value written in Git after a few minutes. To change it, edit the configuration repository.

Take care when also using autoscaling (HPA). The HPA changes the replica count, and if ArgoCD sees that as a deviation and reverts it, the two fight each other. In that case, remove the replica count field entirely from the YAML in the configuration repository (see 3.5).

Reading the Statuses

ArgoCD shows two statuses separately. They have to be distinguished.

StatusMeaning
SyncedThe cluster matches Git
OutOfSyncIt differs from Git. Either it has not been applied yet or someone edited it directly
StatusMeaning
HealthyThe deployed resources are operating normally
ProgressingThe deployment is in progress
DegradedIt was deployed but is not healthy
MissingIt exists in Git but not in the cluster

Synced together with Degraded is confusing. It means what Git said was applied, but that content itself has a problem. The image name may be wrong, required configuration data may be missing, or resources may be short. In that case you have to look at pod logs and events (see 3.1).

Checking in the Console

Even when deploying with ArgoCD, the places to see the result are the same as before.

What to checkWhere
Whether the new image was appliedThe image tag on the Deployment detail (see 3.2)
Whether pods started normallyThe pod list and status badges (see 3.1)
What was deployed, at a glanceMap (see 2.2)
The cause of a failurePod logs and events (see 3.1)

The resources ArgoCD itself creates (application definitions) are custom resources, so they can also be seen on the Custom Resources screen in the Console (see 8.2).

Rolling Back

In GitOps, rolling back means reverting Git.

SituationMethod
The deployment just made was wrongRevert to the previous commit in the configuration repository and push
You have to go back several stepsRevert to the YAML of that commit and push
You have to stop right nowTurn off automatic sync on the ArgoCD screen and roll back to an earlier revision

Do not roll back from Deployment History in the Console. It does revert, but Git stays as it was, so with self-healing on it comes back a few minutes later. On the surface it looks like "I rolled back and it undid itself", which makes the cause hard to find.

When It Does Not Work

SymptomCauseWhat to check
Stuck at OutOfSyncAutomatic sync is offSelect SYNC on the ArgoCD screen
Pushed to Git but nothing changedArgoCD has not read it yetWait a moment or select refresh
Cannot read the repositoryThe repository access information is wrongAsk operations staff to confirm the repository registration
Synced but DegradedThe Git content itself has a problemPod logs and events, the image name and tag
Edited it but it revertedSelf-healing is onEdit the configuration repository, not the cluster
A resource suddenly disappearedYAML was deleted with automatic pruning onRecent commits in the configuration repository

Which Method to Choose

SituationRecommended method
Trying it for the first time or during developmentConsole build (see 4.2) or Bastion (see 4.5)
A team deploying through a defined procedureA CI tool (see 4.4, 4.6)
A production environment where history, approval, and recovery matterArgoCD (this chapter)
Deploying the same thing to several environmentsArgoCD (this chapter)

Do not use two methods for one application. Editing an ArgoCD-managed resource with kubectl or the Console gets reverted by self-healing. If you are migrating, turn automatic sync off during the move and turn it back on afterwards.