Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes (the foundation of OpenShift). It is efficient, well supported, and well documented.
This document describes how to use Argo CD with your OpenShift project.
It is available to any team on the B.C. government's OpenShift platform and can help teams:
- Implement a GitOps-style deployment service
- Reduce the maintenance overhead of their pipelines
- Reduce resource consumption by using a shared service
- Why Argo CD is good for you
- Enable Argo CD for your project set
- Migration and setup
- Create Applications in Argo CD
- Configure your project
- Related links
There are a number of reasons for using Argo CD over other tools, such as Jenkins. Argo CD is designed specifically for Kubernetes and is efficient, well supported, and well documented. The YAML manifests that define all Kubernetes resources can be managed in a Git repository. Argo CD can monitor that repo and maintain application state on the cluster consistent with the desired state as defined by the manifests. Updates to applications involve updates to the manifest files. As a result of this architecture:
- All application changes are recorded as Git commits, providing a detailed change history.
- Rollbacks can be achieved by reverting to a previous commit.
- The configuration is portable, in the event the application is moved to another host.
- Argo CD can be easily integrated with CICD pipelines.
- Kustomize and Helm support satisfy the needs of most teams.
- When combined with pipeline tools such as GitHub Actions or OpenShift Pipelines, teams no longer need to maintain their own pipeline infrastructure.
A self-serve system is in place for the setup of Argo CD for your project set. To get started, follow these instructions. (If your project requires a ministry-wide grouping of projects within Argo CD, please contact the Platform Services Team.)
- Prepare a
- Note that GitHub IDs are CASE SENSITIVE...
- Use the template: https://github.com/BCDevOps/openshift-wiki/blob/master/docs/ArgoCD/gitopsteam_template.yaml
- Use the inline comments to populate this file
- Ensure that all users in the 'projectMembers' group have a Keycloak ID in the realm used by Argo CD. They can do this by attempting to access the Argo CD UI for the given cluster:
- Create the GitOpsTeam CustomResource in your tools namespace
oc -n myproject-tools create -f gitopsteam.yaml
After creation of the GitOpsTeam resource, an OpenShift operator will:
- Create a "gitops" repo for your project
- This is the repository that Argo CD will read for your Application manifests.
- Note: This repo is in the
bcgov-cGitHub Organization, which has a limited number of seats and requires that users reply to an invitation from GitHub to join the organization. Please limit access to this repo to just those team members that require access for manual updates. Most updates will be made by your pipeline.
- Your gitops repo will be called
- Create Keycloak groups used for controlling access to your Project in the ArgoCD UI
- Create the Argo CD Project
Once your GitHub repo has been created, you need to allow your pipeline to read from and write to it. Do this by creating an SSH key pair and adding it as a Deploy Key in the repo.
Create an SSH key - the following can be done on a Linux or Mac system. Use a descriptive name for the key.
ssh-keygen -f tenant-gitops-mylicenseplate
In your "tenant-gitops-" repo, add the key as a Deploy Key:
Add deploy key
- Enter a descriptive name for the key, such as "read-write"
- Copy the contents of the PUBLIC key (the file with the .pub extension) into the key field, but remove the 'user@host' bit at the very end of the line.
- Check the checkbox for "allow write access"
- Save the deploy key
Add the private key as a Secret for your pipeline. If using GitHub Actions, add the Secret in the repository where the Action runs; if using OpenShift Pipelines (Tekton), add the Secret in your tools namespace.
Give the Secret a meaningful name, such as MANIFEST_REPO_DEPLOY_KEY, and copy the entire contents of the PRIVATE key file (having no file extension), incuding the BEGIN and END lines, into the value of the secret.
As Argo CD reads manifest files from a Git repository, this repo must be prepared before the application is configured in Argo CD. Depending on the application's current deployment strategy, the repo setup will vary.
Although no particular structure is required in the manifest repo, we suggest creating a directory for each application. In addition to setting a repo path for each application in Argo CD, you can also specify a branch or tag.
Argo CD supports several deployment strategies, including:
- Ksonnet (being deprecated)
This document focuses on Helm and Kustomize.
Helm users will already have a set of files prepared and these are easily migrated to the manifest repo. Create a top-level directory for your application. Place all Helm files in this directory. Also put your values files in the same directory, named according to environment. When configuring the app in the Argo CD UI, you will specify the path to the values file.
Kustomize is a more generic system, which allows you to declare a default set of resources and then configure just the differences from default for each environment.
If your application is already set up for Kustomize, then you just need to move your Kustomize files into the manifest repo.
If moving an existing application to Kustomize and Argo CD for the first time, some effort will have to be made to generate the manifest files. The live manifests can be fetched from OpenShift using the command line. Certain fields will have to be removed, however, as OpenShift adds a number of fields for internal resource management. A shell script has been prepared to help with the manifest creation.
Once the manifest files have been generated, the repo structure is prepared. Within the manifest repo, in the top-level directory for the given application, create the following directories:
Copy the manifest files to the
base directory. If you use custom SSL certificates for your routes, they will have to be removed from the manifest file and replaced with a reference to a Secret, from which they will be populated at deployment time. Do not include certificate info in your manifest repository.
Create a file
base/kustomization.yaml containing a list of all manifest files. For example:
resources: - configmap.my-app.yaml - deployment.my-app.yaml - route.my-app.yaml - service.my-app.yaml
overlays/dev directory, you'll need to:
- create any "patch" files that define differences from the default
- create kustomization.yaml
These files should contain individual modifications to a resource. For a larger resource, such as a Deployment, it is recommended to create multiple patch files, one for each change.
Each patch file starts with the apiVersion, kind, and metadata name of the resource, followed by the change. For example, to set the replica count for a Deployment:
apiVersion: apps.openshift.io/v1 kind: Deployment metadata: name: my-app1 spec: replicas: 2
The kustomization.yaml file will likely contain several sections. Firstly, it specifies the apiVersion and kind, similar to a patch file, and includes a list of resources, starting with the base directory.
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../../base
Patch files are included in a list under the heading patchesStrategicMerge, such as:
patchesStrategicMerge: - deployment.my-app1.replicas.yaml - route.my-app1.yaml
Images are also managed in kustomization.yaml. In an 'images' section, create an entry for each image that is likely to be updated by your pipeline. Each image listing has three parts:
- name - the placeholder name of the image that you use in your base file
- newName - the base URL of the image
- digest - the unique ID of the image In this way, your pipeline build will be able to update the image ID for a given environment.
A kustomization.yaml example with all three sections:
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../../base patchesStrategicMerge: - deployment.my-app1.replicas.yaml - route.my-app1.yaml images: - name: my-app1-image newName: image-registry.openshift-image-registry.svc:5000/mylicenseplate-tools/myapp1buildconfigname digest: sha256:7da096fa377221d82a28f9b7888130b89382f61ea54018f1b8d26218173ec4eb
Consult the Kustomize documentation for more information, as this doc is meant to just get you started.
If you have some resources that should be processed before others, you can use the Argo CD notion of 'sync-waves'. Resources having sync waves with lower numbers are processed before those having sync waves with higher numbers. To utilize this, add a sync-wave setting to metadata.annotations. For example:
metadata: annotations: argocd.argoproj.io/sync-wave: "2"
Once the manifest repo has a deploy key configured and the manifests themselves have been added, you are almost ready to add the application in Argo CD. Before you do, make sure that the target namespace can tolerate a disruption. Once you create the application in Argo CD and synchronize it, Argo CD will begin updating resources, so if there is a problem with your manifests, existing resources could be affected.
In the Argo CD UI, click the Applications link at the top of the left-side navigation. Click 'New App'.
- Application Name - Application names must be unique across all projects. Give your app a meaningful name that includes the target environment. A good naming convention would be to put the license plate or project name at the beginning, followed by the app name, followed by the environment, such as
- Project - Select your project from the dropdown menu.
- Sync Policy and Sync Options can be left alone until you know what you need.
- Source repository URL - Use the SSH style URL for your manifest repo, such as
- Source Revision - Leave this as "HEAD" if you are using the master branch, otherwise enter the branch name. You can also set the dropdown to TAG and enter a tag name.
- Source Path - Enter the path within the manifest repo, for example
- Destination Cluster URL - Select the local cluster URL from the dropdown. This is the only option.
- Destination Namespace - Enter the target namespace, such as
- Click 'Create'
If you get an error message when trying to create the application, read the error carefully and try to fix it, then recreate the app.
Once the application has been successfully created, and assuming you have not yet enabled automatic synchronization, click on the app on the application list page. Argo CD will have already scanned the files in the manifest repo at the path and branch/tag specified and will show 'out of sync'. To begin synchronizing the app, and thus (potentially) altering the resources in your OpenShift namespace, click the 'Sync' button, and then 'Synchronize'. It will take a little bit of time, depending on how many resources are defined for this app.
If the sync result shows 'failed', click the 'failed' message to view messages explaining why it failed. There could be a problem with your manifest files or repo configuration, for example.
If the sync has succeeded, but still shows as "progressing", or if there is an individual resource that is still not showing as successfully synced, click the resource that is not showing as healthy and click the 'Events' tab to see what the problem is.
Once you are satisfied with the setup, feel free to enable automatic synchronization.
It should be noted that there are some constraints placed on Projects and Applications in this shared Argo CD instance.
This is the repository that can be used as the source repo for an application and is limited to the new GitHub repo (tenant-gitops-licenseplate) that was created for you. You can use only this repo as the source for applications for this project. This limitation exists partly to prevent applications from being created from third-party sources that may not be safe, and partly to simplify automation associated with this service.
Each Argo CD Project is associated with an OpenShift project set (license plate). The destination of an Application is its namespace. A Project can deploy applications only to namespaces within its project set (tools, dev, test, prod).
There are a few namespace-scoped resources that you will not be able to modify. Mostly this is to avoid circumvention of quotas, and to also prevent the possible accidental deletion of an entire namespace.
Access to the gitops repository and the Argo CD UI is controlled by way of the GitOpsTeam resource in your
-tools namespace. After editing this resource, the operator will make any updates shortly after (typically less than a minute).
Access to the Git repository includes five sets of permissions.
Access to the Argo CD UI includes two sets of permissions: read/write and read-only
See the GitOpsTeam template for more details: https://github.com/BCDevOps/openshift-wiki/blob/master/docs/ArgoCD/gitopsteam_template.yaml