Argo CD: Up and Running

A Hands-On Guide to GitOps and Kubernetes

With Early Release ebooks, you get books in their earliest form—the author’s raw and unedited content as they write—so you can take advantage of these technologies long before the official release of these titles.

Andrew Block and Christian Hernandez

Argo CD: Up and Running

by Andrew Block and Christian Hernandez

Copyright © 2024 Andrew Block and Christian Hernandez. All rights reserved.

Printed in the United States of America.

Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.

O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://oreilly.com). For more information, contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com.

Acquisitions Editor: John Devins

Development Editor: Jill Leonard

Production Editor: Elizabeth Faerm

Copyeditor:

Proofreader:

Indexer:

Interior Designer: David Futato

Cover Designer: Karen Montgomery

Illustrator: Kate Dullea

March 2024: First Edition

Revision History for the Early Release

2023-05-04: First Release

2023-10-26: Second Release

See http://oreilly.com/catalog/errata.csp?isbn=9781098142001 for release details.

The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Argo CD: Up and Running, the cover image, and related trade dress are trademarks of O’Reilly Media, Inc.

The views expressed in this work are those of the authors and do not represent the publisher’s views. While the publisher and the authors have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the authors disclaim all responsibility for errors or omissions, including without limitation responsibility for damages resulting from the use of or reliance on this work. Use of the information and instructions contained in this work is at your own risk. If any code samples or other technology this work contains or describes is subject to open source licenses or the intellectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights.

978-1-098-14200-1

[LSI]

Chapter 1. Installing Argo CD

A Note for Early Release Readers

With Early Release ebooks, you get books in their earliest form—the author’s raw and unedited content as they write—so you can take advantage of these technologies long before the official release of these titles.

This will be the 2nd chapter of the final book

If you have comments about how we might improve the content and/or examples in this book, or if you notice missing material within this chapter, please reach out to the editor at jleonard@oreilly.com.

Like most cloud native applications, Argo CD features a microservices architecture that comprises multiple components and technologies. Each Argo CD component, working together, helps support a fault tolerant and robust system that helps enable the full set of features and capabilities. Understanding how all of these services work together in concert helps provide a greater awareness of the architecture, their significance, as well as how they are incorporated into the overall system as a whole. This chapter introduces the architecture and design of Argo CD along with detailing the various ways that it can be installed to a Kubernetes environment.

Argo CD Architecture

Since Argo CD is a GitOps based solution designed for Kubernetes, the architecture emphasizes the use of as many Kubernetes primitives as possible. As introduced in Chapter 1, Argo CD sources content stored in repositories and realizes those configurations within a Kubernetes cluster. But, what does that look like and what are the components involved?

Kubernetes Controller Pattern

One of the key benefits of using Argo CD aside from the capability to define Kubernetes resources within source repositories and applying them to a cluster is that Argo CD can be configured to enforce those configurations to stay in place, even if they are modified. This is known as drift management. Argo CD does this by implementing a Kubernetes concept called a Controller which executes a non-terminating control loop for managing and monitoring the desired state of at least one resource. Based on a defined configuration, the controller will ensure that the current state matches the desired state.

For example, Deployments are a common method for registering workloads into Kubernetes and as part of the creation of a Deployment resource, a ReplicaSet is created. One of the built-in Kubernetes controllers, the ReplicaSet controller, monitors all pods that have been created for a given ReplicaSet and ensures that the actual state of the resource(s) in the cluster match the expected and defined state. If the actual state does not match the expected state, the controller will reconcile the difference until the current state matches the defined state.

This controller pattern applies to not only the resources that end users manage, but are foundational for Argo CD itself. The properties that drive the core configurations of Argo CD (everything from how to connect to external entities to the various properties of the Argo CD server) are stored within ConfigMaps and Secrets. However, as one can imagine, there is a limitation of the types of properties that can be stored within the simple key/value constructs provided by not only these Kubernetes resources, but any resources that are part of a standard Kubernetes deployment.

Argo CD is not alone when it comes to solutions for adding new ways of managing resources within a Kubernetes environment. This need led to the creation of Custom Resources which are implemented through CustomResourceDefinitions (CRDs) and enable an end user to register a new resource type within Kubernetes. By defining a new resource type, not only can the properties of this resource be defined (so that consumers can become aware and comply with the acceptable fields and their rules), but a new API endpoint in the Kubernetes API server is registered to facilitate the management of these resources.

A concept similar to a Kubernetes controller, known as an operator, builds upon the primitives of a Kubernetes controller for managing the current and desired state of resources in a Kubernetes cluster and applies them to CRDs. Given that Custom Resources typically have domain specific values and meaning associated with them, an operator is built with this domain level knowledge of how to interpret those values and ensure the state of resources within Kubernetes match those defined values.

Argo CD makes use of several Custom Resources and their properties are the primary vehicle to enable end users to manage their Kubernetes resources using GitOps based principles. The use of Kubernetes Controllers and Custom Resource are fundamental to the overall Argo CD architecture.

Argo CD Architecture Overview

Given that Argo CD implements a microservices based architecture, there is no single Argo CD component, but instead multiple distributed systems that act in a coordinated fashion. Figure 1-1 depicts the overall Argo CD architecture including the relationship between each of the services and resources.

Figure 1-1. Overall Argo CD Architecture

Custom Resources

Argo CD makes use of several Custom Resources to declaratively define business logic and API’s to implement GitOps management capabilities. Three Custom Resources are provided with each installation of Argo CD:

Applications

AppProjects

ApplicationSets

The purpose of each Custom Resource will be described in more detail throughout the course of this book. However, it is important to note that Argo CD interacts with the Kubernetes cluster using these CRDs. This, effectively, makes these CRDs your interface for managing your Kubernetes cluster/clusters.

Application Controller / ApplicationSet Controller

The Application Controller and ApplicationSet Controller are both Kubernetes Operators (and by definition, also controllers) that continuously monitor the state of Application and ApplicationSet resources and compare the live state in the Kubernetes cluster to the desired state from source repositories. In addition to strictly monitoring for Custom Resources, they are also responsible for performing lifecycle events associated with the content that they are reconciling.

Repository Server

The Repository Server maintains a local cache of the remote content source that will be translated into Kubernetes manifests. It is responsible for generating resources based on parameters including:

Repository type

Repository source location

Path within the repository

Template tool specific parameters

In addition, Custom plugins are also executed within this component as they can influence the generation of the Kubernetes resources.

API Server

The API server is a gRPC/REST based server that exposes services for managing key configurations that are integral to the platform including:

Application management and status reporting

Invocation of Application operations including syncing, rollback and additional user defined actions

Cluster and repository management

RBAC enforcement

Several other components within the Argo CD ecosystem heavily rely on this asset for their normal operation including the User Interface, CLI, and external CI/CD systems.

In addition to acting as an API server, a web User Interface is also exposed which provides a method for visualizing Application activity as well as supporting the management and configuration of Argo CD.

Redis

Redis is an in-memory database and provides local caching capabilities to reduce the dependency on external systems. While its primary purpose is to cache the contents of remote repositories, it also supports the state of Kubernetes resources as well as connection status of remote repositories and clusters. The content of the cache is not persisted and is always rebuilt at startup.

Command Line Interface (CLI)

Command line based utility for interacting with Argo CD. Support is available to manage the configuration of the platform itself as well as the lifecycle of Applications. Communicates via the Argo CD API and includes a superset of the capabilities that are provided by the Argo CD user interface.

Single Sign On (SSO)

Argo CD provides user management capabilities for interacting with the platform. These users can be defined locally within Argo CD or can be sourced from an external source. When integrating with an external source, OpenID Connect (OIDC) based authentication is supported. For external identity providers that do not provide a direct OIDC integration, an instance of the Dex identity server is provided to act as a bridge between Argo CD and the remote identity provider.

Notifications

Included as part of a standard installation of Argo CD starting in version 2.3. This feature provides a mechanism for monitoring and triggering notifications to external systems based on the lifecycle of Applications through the use of templating capabilities and a catalog of included triggers. Argo CD Notifications can be configured to send information to (but not limited to) Slack, Email, and can also invoke other webhooks. Understanding the current state of systems and environments is key when running production systems and Argo CD notifications will be covered in greater detail within Chapter 13.

Argo CD Key Themes

As may be evident by this point, now that the foundational architecture has been introduced, Argo CD makes use of several key patterns and their significance will become even more apparent as each topic is described.

First, is an emphasis of defining resources in a declarative fashion; whether they be one of the provided Custom Resources, or a core configuration of the Argo CD server itself that is stored in a ConfigMap or Secret. Not only does trait implement one of the most important concepts in GitOps, it also enables the configuration of Argo CD itself to be managed via GitOps and Argo CD.

Building upon the first theme where each resource is managed in a declarative fashion, Argo CD also makes use of a stateless architecture, meaning that configurations are the state of the system that can be rebuilt at any time. This approach to a stateless architecture is achieved by using etcd, the key/value datastore of Kuberntes to act as the persistent store for the aforementioned resources. If there is either a desire or need for state to be tracked against a particular resource, the status field, a standard property and method found on many Kubernetes resources, can be used. In addition, while Redis is included as a caching mechanism within the Argo CD architecture, it is used as a volatile cache without any long term persistence.

Finally, Argo CD enables flexibility. Not only are there multiple repository types which GitOps related content can be sourced from, but there is built in support for templating resources using a number of popular tools including Kustomize, Helm and Jsonnet. Additional user defined tools can also be added to not only integrate with additional external resources, but enhance how assets are rendered.

Now that we’ve covered the basics of the Argo CD architecture including the primary components, let’s shift gears to the methods that are supported for installing Argo CD.

Installing Argo CD

Just as Argo CD supports the use of multiple methods and tools, such as Kustomize and Helm, to generate resources that can be applied to a Kubernetes cluster, many of these same tools and approaches can be used to install Argo CD itself. The determination of the particular approach depends largely on user preference as well as if there are any specific requirements or constraints, such as team or organizational guidance or restrictions. In addition to the tool that is used to facilitate the execution of the installation, Argo CD also supports several installation types which influences the resources that are included in the deployment as well as the configuration of the deployed resources. Some of these topics will be expanded upon in subsequent chapters.

Installation Types

Argo CD as a GitOps tool, similar to many other tools in this space, is utilized by a variety of personas who each have their own set of business domains and goals. Since there are a multitude of use cases and requirements that may be desired, Argo CD supports multiple installation configurations and the determination of a particular configuration depends on the answer to three key decision points:

Who are the users and consumers of the platform?

What is the scope Argo CD should manage?

Is high availability a concern?

These options are illustrated in Figure 1-2:

Figure 1-2. The options and considerations when installing Argo CD

The first decision point is the type of installation that Argo CD should serve. In most cases, Argo CD will be consumed by multiple individuals that may span across multiple teams within an organization. Additionally, most organizations desire to make use of the full set of features that are provided as part of a standard deployment of Argo CD (we covered these in the previous section). This is known as a multi-tenant type of installation and it is most commonly utilized as it provides the full set of capabilities provided by Argo CD.

Alternatively, an option is available to perform an installation that includes only the minimal set of components to support normal operation. This approach does not include the API server or user interface, SSO or notification features. In addition, each component is also optimized to consume a minimum amount of resources in a non-highly available configuration (more on the topic of high availability later in this chapter). While a core deployment is not intended to appease the masses, this approach is beneficial for individual users that manage Argo CD from both an administrative and end user perspective where there is not a desire to leverage the full featureset of Argo CD, but there is still a desire to take advantage of the primary GitOps capabilities.

The next decision point that must be addressed is the scope that Argo CD should manage. By default, Argo CD has the authority to control resources across an entire Kubernetes cluster. This is the preferred option, especially when Argo CD is being used by Kubernetes cluster administrators. However, another approach, known as “namespaced” mode, that is available is to deploy Argo CD within a specific namespace and to allow Argo CD to only manage resources within specific namespaces. This option is used in multi-tenant environments where individual application teams are given the autonomy to operate their own instance of Argo CD, but are not granted access to manage cluster scoped resources. An in depth look into the use of a namespaced deployment of Argo CD and its use case will be discussed in Chapter 8.

Finally, to support production environments, each of Argo CD’s components can be configured in an optimized manner to ensure greater resiliency and performance needs. This approach is accomplished through a combination of increasing the replica count as well as enabling tunable parameters within each component. However, there are certain considerations that must be followed so that Argo CD can operate in an optimized fashion as merely increasing the replica count of all components uniformly can actually cause a performance degradation. Fortunately, Argo CD provides manifests supporting both clustered and namespace scoped deployments illustrate the types of configurations necessary to enable a highly available deployment.

Now that both an overview of the Argo CD architecture as well as an understanding of the deployment approaches have been addressed, it’s time to see Argo CD in action by working through the first hands-on activity..

Deploying Argo CD

In due course throughout the remainder of this book, most of the installation types and approaches will be realized. However, to get started, let’s start off by performing a basic installation of Argo CD to the minikube environment.

We’ve covered multiple approaches for performing an installation of Argo CD. Each of these options are detailed within the installation section (https://argo-cd.readthedocs.io/en/stable/operator-manual/installation) of the Argo CD documentation.

Deploying Argo CD Using YAML Manifests

The simplest and most straightforward option is to use one of the raw YAML formatted manifests that include all of the resources and configurations within a single document, and in particular, a non-highly available, multi-tenant based deployment of Argo CD.

First, ensure that a fresh instance of minikube is running. Then, execute the following commands using kubectl to create a new namespace called argocd and to deploy Argo CD in the previously described configuration:

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

After a few moments for the associated images to be downloaded to the minikube instance, the pods in the argocd namespace can be queried with a result similar to the following:

kubectl get pods -n argocd

NAME                                                READY   STATUS    RESTARTS   AGE
argocd-application-controller-0                     1/1     Running   0          46s
argocd-applicationset-controller-74575b6959-8dc7l   1/1     Running   0          46s
argocd-dex-server-64897989f8-qg8pm                  1/1     Running   0          46s
argocd-notifications-controller-566bc99494-7vj82    1/1     Running   0          46s
argocd-redis-79c755c747-867nk                       1/1     Running   0          46s
argocd-repo-server-bc9c646dc-6sd86                  1/1     Running   0          46s

argocd-server-757fddb4d7-xgdxh                      1/1     Running   0          46s

The standard deployment of Argo CD depicted here contains each of the primary components that are included with Argo CD, so it is an ideal baseline to work from.

The User Interface is one of the key features that sets Argo CD apart from other GitOps solutions. Before moving on, confirm the successful installation of Argo CD by accessing the User Interface.

By default, the set of resources that were applied to the Kuberntes cluster did not include any configurations or resources to expose access to Argo CD outside the cluster. While there are several approaches that can be used to access Argo CD externally, such as creating a LoadBalancer service type or using an Ingress, to demonstrate baseline functionality, the port forwarding capability of the kubectl CLI can be used to connect to Argo CD without any additional actions.

Next, execute the following command to initiate the forwarding of port 8080 from the local machine to the Argo CD server service which will expose access to the User Interface.

kubectl port-forward svc/argocd-server -n argocd 8080:443

Once port forwarding has been established, launch a web browser and navigate to https://localhost:8080

By default, Argo CD generates a self signed TLS certificate to enable secure transmission between itself and the browser. Since this certificate is not trusted by the browser, a warning is displayed. Depending on the browser being used, there will be an option to proceed even though the certificate is not trusted and then the Argo CD login page will be displayed.

To login, admin is the username of the Argo CD administrator and the password is a secret with the name argocd-initial-admin-secret. Obtain the password by executing the following command:

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo

Login using admin as the username and the password that was obtained from the prior command. Upon successful login, the Argo CD dashboard is displayed, as shown in Figure 1-3.

Figure 1-3. The Argo CD Application Page

The dashboard contains a list of the current Applications that have been registered to Argo CD and their current status. Since this instance does not have any Applications registered, the dashboard is empty. Feel free to navigate around the user interface as you see fit. However, a more in depth overview of the user interface will be covered in Chapter 3.

High Availability

The standard deployment of Argo CD is ideal for getting started, but is not suitable for production environments due to the fact that there is only a single replica for each component. In case one of the components fails (due to an error or issue with the underlying infrastructure), it will cause a degradation of functionality as one or more of the resources will become unavailable. To mitigate these concerns, an alternate set of YAML definitions are available for both cluster and namespaced modes of operation. The key difference between these sets of resources and those that were deployed previously is that not only have additional tuning options been implemented, but multiple replicas of each service have also been defined. This means that if a failure does occur to one of the services, the remaining replica will be able to take on requests and continue normal operation in a degraded state until the original replica returns to normal operation.

Given that the topic of high availability is just one of the many traits of a production system, this topic will be expounded upon in Chapter 13 as part of a discussion on the considerations for operating Argo CD at scale.

Deploying Argo CD Using Helm

Argo CD can also be installed using a Helm chart. A Helm based installation approach has advantages over YAML manifests as the resources that are installed can be customized using the dynamic templating capabilities provided by Helm. For example, entire components can be enabled or disabled as well as specific properties can be tailored whereas these options would not be possible using the YAML based manifest approach.

To install Argo CD using Helm, first be sure that your minikube instance does not have any previously created resources deployed. If Argo CD is still running from the prior section, the minikube instance can be deleted and recreated or the contents from the prior section can be removed.

To delete and recreate the minikube instance, using the following commands:

minikube delete
minikube start

Alternatively, instead of needing to recreate the entire minikube instance, the YAML based manifest installation of Argo CD can be uninstalled by removing the resources from the same manifest and then deleting the argocd namespace:

kubectl delete -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl delete namespace argocd

With a fresh minikube environment available, proceed to deploy Argo CD using Helm.

First, add the Argo CD Helm repository:

helm repo add argo https://argoproj.github.io/argo-helm

Install the Helm chart using the default configuration and create a new namespace called argocd using the following command:

helm upgrade -i argo-cd argo/argo-cd -n argocd --create-namespace

Note

Either the helm install or helm upgrade command can be used to install the Argo CD chart. When the helm upgrade command is used with the -i parameter, Helm will check if there is an existing release found. If a release is not found, the chart will be installed instead of upgraded. The benefit of using helm upgrade in this situation is that the same command can be issued regardless of installing a chart for the first time, or upgrading an existing release. The helm install command can only be used when installing a chart for the first time.

Another benefit of Helm is that chart creators can include additional information that is displayed whenever a chart is installed or upgraded, known as NOTES. After executing the helm upgrade command previously, the contents of the NOTES document in the chart was displayed which provided a set of next steps, including how to access the Argo CD user interface and how to obtain the password for the Argo CD admin user.

Query the running pods from the argocd namespace and take note that the set of resources are available as they were using the YAML manifest approach (albeit with slightly different names as the Helm chart prefixes each resource with the name of the Helm release).

kubectl get pods -n argocd

If desired, the Argo CD user interface can be accessed in a similar manner as described in the previous section and the exact steps in this instance can be found within the provided Helm NOTES output.

While only a basic deployment of Argo CD was described in this section, the full set of tunable parameters provided by the Argo CD Helm chart can be viewed by listing the available chart Values:

helm show values argo/argo-cd

The use of Helm values within the Argo CD Helm chart enables a greater level of customization and simplifies the initial configuration when deploying Argo CD.

Summary

This chapter provided an overview of the architecture and components that are included as part of a deployment of Argo CD. In addition, two of the most common approaches for installing Argo CD, YAML manifests and Helm charts were introduced and used to deploy Argo CD to an instance of minikube. Finally, the Argo CD was accessed using the user interface to confirm a successful installation. The next chapter expands upon the use of the user interface and describes the various different methods available that can be used to manage and interact with Argo CD.

Chapter 2. Interacting with Argo CD

A Note for Early Release Readers

With Early Release ebooks, you get books in their earliest form—the author’s raw and unedited content as they write—so you can take advantage of these technologies long before the official release of these titles.

This will be the 3rd chapter of the final book

If you have comments about how we might improve the content and/or examples in this book, or if you notice missing material within this chapter, please reach out to the editor at jleonard@oreilly.com.

Argo CD includes a fully declarative configuration model which supports a hands-off approach to GitOps and the management of a GitOps server. However, in most cases, more direct methods will be needed for interacting with the Argo CD server. In the previous chapter, we covered the Argo CD user interface which is one method for interacting with the platform since it provides a visual approach to the current state of GitOps. While the user interface may be one of the most common methods for utilizing Argo CD, there are additional mechanisms to choose from. This chapter builds upon the foundational concepts established in Chapter 2 for accessing and configuring Argo CD along with introducing several additional approaches that can be employed depending on the use case or preference.

The User Interface In Depth

In Chapter 2, the TypeScript based user interface was used as a way to access Argo CD. However, when deployed to the instance of minikube, it required establishing a connection to the server component using the kubectl port-forward command. While this was acceptable for initial testing and validation, it is by no means how one should utilize a service long term. A more robust approach should be undertaken to provide a more reliable exposure of services.

One of the most common methods for exposing services and gaining access to resources within a Kubernetes cluster is to leverage an Ingress resource. An Ingress provides a means for exposing services outside of a cluster and they are enabled by the use of an Ingress Controller which will map the incoming request to the backend service. There are many options as it relates to the available Ingress controllers where some have additional features and integrations with the operating environment, such as a cloud provider.

NGINX is one such popular ingress controller and there is even direct support in minikube to facilitate the deployment process in a simplified manner. Addons are a feature included within minikube to extend the baseline installation with new features. The ingress minikube addon enables the deployment of the NGINX controller to allow for Ingress resources to be used with minikube.

Let’s add the ingress minikube addon so that Argo CD can be accessed using an Ingress resource instead of through a kubectl port-forward session.

Start a fresh minikube instance ensuring that any existing use of minikube, such as from the previous chapter is deleted beforehand:

minikube start

Once the minikube instance is running, enable the ingress addon.

minikube addons enable ingress

Once the addon has been enabled, the NGINX related resources can be found in the ingress-nginx namespace.

kubectl get pods -n ingress-nginx

NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-wv9lr        0/1     Completed   0          108s
ingress-nginx-admission-patch-ww2xg         0/1     Completed   0          108s
ingress-nginx-controller-5959f988fd-bfzqd   1/1     Running     0          108s

kubectl get svc -n ingress-nginx

NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.110.237.171   <none>        80:30607/TCP,443:32389/TCP   2m20s
ingress-nginx-controller-admission   ClusterIP   10.108.237.140   <none>        443/TCP                      2m20s

Access to the ingress controller when deployed to minikube is through the minikube IP address. This address can be located by running the minikube ip command.

Invoking the curl command by referencing the minikube IP address as shown below validates communication to the ingress controller is successful.

curl http://$(minikube ip)

<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

While the 404 error may appear to be a failure, given that no Ingress resource has yet to be created, the fact that a response was provided and that it included nginx in the response body confirms the ingress controller has been deployed and is operating correctly.

Note

Access to the ingress controller through the minikube IP address can only be achieved on Linux machines or when using the native docker desktop integration. If minikube is using another driver, such as docker or podman, access is achieved using a combination of the minikube tunnel command which will establish a connection to the minikube instance and then accessing resources at 127.0.0.1 instead of the minikube IP address. This step is noted on these platforms when enabling the ingress addon.

Now that access to the ingress controller has been confirmed, an Ingress resource must be created so that access can be achieved through the ingress controller. Fortunately, the Argo CD Helm chart includes functionality for configuring this task. When utilizing an ingress resource, one of the first steps that must be completed is to determine the hostname that is associated to the service.

Since NGINX is a OSI Layer 7 load balancer, routing is performed using the Host header in the request. As requests are received, NGINX will inspect this header, determine if any of the defined Ingress resource matches the request, and if so, route the request to the associated backend service.

The hostname that will need to be specific for the Argo CD instance will most likely not have an associated value in a publicly accessible DNS server. To solve this challenge, two options are available:

Modify the contents of the /etc/hosts file on the local machine

Use a hosted wildcard DNS service, such as nip.io

While using the hosted service eliminates the need to make modifications on the local machine, it potentially introduces an unnecessary dependency on an external. As such, the manual modification approach will be demonstrated here.

argocd.upandrunning.local is the hostname that will be used to refer to the Argo CD instance deployed in minikube. Modify the /etc/hosts file to add the minikube ip address and hostname so that queries are resolved and routed appropriately.

Append the following to the end of the /etc/hosts file

192.168.49.2 argocd.upandrunning.local

With the ingress controller and hostname prerequisites complete, the Argo CD helm chart has the capabilities available to support generating the necessary manifests to enable Argo CD to be accessed via an Ingress resource.

Create a file called values-argocd-ingress.yaml with the following content:

---

server:
  ingress:
    enabled: true
    hosts:
      - argocd.upandrunning.local
  extraArgs:
  - --insecure

Deploy the Helm chart using the values file created previously.

helm upgrade -i argo-cd argo/argo-cd --namespace argocd --create-namespace -f argocd-ingress.yaml

This Helm release will appear similar to the release that was completed in Chapter 2. However, by specifying the appropriate values, a new Ingress resource was created which can be verified by executing the following command:

kubectl get ingress -n argocd

NAME                    CLASS   HOSTS                   ADDRESS        PORTS   AGE
argo-cd-argocd-server   nginx   argocd.upandrunning.local   <IP_ADDRESS>   80      4h41m

Given that all of the pieces are in place in order to access Argo CD using an Ingress resource, open a web browser and navigate to http://argocd.upandrunning.local which should display the Argo CD User Interface login page.

Argo CD can also be accessed securely through the ingress controller by using the analogous https:// address Similar to when the user interface was accessed in Chpater 2, a warning will be displayed signifying that a connection is attempting to be established to an endpoint whose certificates are not trusted by the browser. One key difference is that the untrusted certificates are related to the ingress controller and not Argo CD. The default ingress configuration the Helm chart establishes terminates TLS traffic at the ingress controller instead of at Argo CD itself. A more in depth discussion on the TLS options that can be configured in Argo CD will be discussed in Chapter 9.

Once again obtain the password for the Argo CD admin user from the argocd-initial-admin-secret secret and login. Let’s take an opportunity to explore the various configuration options that are available within the user interface.

The default landing page upon login contains the list of Applications that have been registered to Argo CD. An Application is a source of GitOps content that targets a particular destination environment and is the primary focus for end users when using Argo CD. The user interface enables the creation, management and synchronization of Application resources in a visual, user friendly manner.

Aside from managing applications, the other primary purpose of the user interface is to facilitate the management of the Argo CD server itself – from within the Settings page.

Figure 2-1. Argo CD Settings Page

The following table details the configurable options that are made available from the Settings page of the user interface:

Table 2-1. Options available within the Argo CD Settings Page

Setting | Description
Repositories | Configure remote locations containing resources that will be translated into Kubernetes manifests
Certificates | Management of transport mechanisms to facilitate secure connectivity to remote repositories
GnuPG keys | Key management to enable the verification of source control content
Clusters | Kubernetes environments that have content from source repositories applied
Projects | Logical groupings of Applications with common configurations and permissions
Accounts | Management of local accounts stored within the Argo CD server
Appearance | Configure the look and feel of the user interface

In addition to being able to manage Application and server settings, information related to the current authenticated user is available from the User Info page which is helpful for associating identity details to enable Role Based Access permissions that are used to manage access to Argo CD resources.

Even with all of the parameters and settings that can be configured within the Argo CD user interface, there are still a large number of properties that either cannot be managed using the user interface or their values are read only. When those situations do arise, the solution can by typically facilitated by using the the Argo CD CLI. The next section introduces the capabilities included with the Argo CD CLI along with applying the appropriate settings to enable the management of the minikube Argo CD environment.

The Argo CD Command Line Interface

The Argo CD Command Line Interface (argocd) is a utility to control and manage the Argo CD server. Similar to the User Interface, the CLI leverages the API to facilitate the interaction with Argo CD. When certain options are not available from within the User Interface, the default option is to use the CLI as it includes a more in depth set of options and capabilities as compared to the user interface.

Installing the Argo CD CLI can be performed on most major operating systems as there are prebuilt binaries readily available. Other installation options are also available depending on the target operating system and the CLI is also available in a number of formats, including a container image with the CLI included. Consult the Argo CD CLI installation documentation (https://argo-cd.readthedocs.io/en/stable/cli_installation) for the list of supported platforms and necessary steps to complete the installation.

Once the CLI has been successfully installed, execute the argocd command to see a list of functions that can be managed using the tool. Unfortunately, the majority of the options enabled from within the CLI cannot be used unless a connection to an Argo CD environment is established. Connect the CLI to the minikube Argo CD instance using the argocd login command as shown below.

argocd login --insecure --grpc-web argocd.upandrunning.local

The –grpc-web parameter enables the use of the gRPC-web protool which enables communication through the ingress controller. Additional configuration steps are needed to enable native gRPC connectivity which will not be covered at this time.

When prompted, enter the Argo CD admin username and password to authenticate the CLI to the minikube Argo CD instance.

As soon as successful authentication is achieved, a configuration file containing details related to the user, the Kubernetes context and other connectivity data is created in a file located at $HOMEDIR/.config/argocd/config. $HOMEDIR uses either an environment variable named ARGOCD_CONFIG_DIR, HOME, or XDG_CONFIG_HOME (XDG Base Directory Specification) depending on which value is resolved first.

One of the first steps that is typically taken after logging in via the CLI is to change the default admin password. Changing the admin password is important step as it increases the security posture of the Argo CD server. Kubernetes Secrets are not encrypted, but base64 encoded which enables entities with access to query Secrets access to the default password.

Change the default admin password by executing the following command:

argocd account update-password

Enter the current admin password and the value of the desired password to reset the admin password.

Confirm the new password was applied properly by logging out of the current session and logging in once again with the updated password.

argocd logout <context>

The value of the <context> property refers to the argocd context to target. The list of argo cd contexts can be queried by executing the argocd context command. After logging out, login again using the argocd login command to confirm the password reset was successful.

Changing passwords for Argo CD users is just one action that cannot be accomplished using the User Interface and is one of the benefits provided by the CLI. The use of the CLI will become even more prevalent in upcoming chapters as it provides capabilities for not only administrators and users, but its inclusion and integration into other systems and workflows .

However, what if there was no reason at all to use either the User Interface or the CLI but still get the benefits of being able to manage Argo CD? The final section of this chapter explores two additional methods for interacting with Argo CD.

Additional Methods for Managing Argo CD

The Argo CD User Interface and CLI simplifies how users interact with Argo CD – either through visualization and accessibility features from the perspective of the User Interface or enabling a command line level approach with the CLI. One of the commonalities between these two components is that they both make use of the REST based API that Argo CD exposes. End users can invoke the same API’s that Argo CD exposes without being limited based on the features that are included in either the User Interface or CLI.

The first question that may come to mind is “what type of information does Argo CD make available via the API?” One approach could be to use the developer console included by the web browser to inspect the requests that are being invoked from the Web Console. But, that would be somewhat tedious for being able to determine the exact endpoint and parameters that need to be included.

Fortunately, Argo CD provides a OpenAPI Specification (Sometimes also called Swagger) which describes all of the API’s, including the acceptable inputs and provided outputs, that are exposed grealy reducing the burden on the end user.

The OpenAPI specification provided by Argo CD is located at the endpoint /swagger.json

Open a web browser and navigate to https://argocd.upandrunning.local/swagger.json to view the contents.

Upon loading the OpenAPI specification document, one quickly realizes how verbose a specification can be. With a mature API, such as Argo CD, the document is quite large.

One of the tools provided by the Swagger project is a visualization component for OpenAPI specifications which avoids needing to become familiar with the intricate details of the OpenAPI specification.. This utility is included with Argo CD and can be accessed by navigating to https://argocd.upandrunning.local/swagger-ui.

Now that there is an understanding of the API services to query, what are the steps necessary to invoke them? First, a session token must be generated by invoking the /api/v1/session endpoint with a valid username and password.

Execute the following command to obtain a session token substituting the username and password in the appropriate fields:

curl -k https://argocd.upandrunning.local/api/v1/session -d $'{"username":"<USERNAME>","password":"<TOKEN>"}'

Note

The -k argument disables TLS validation which would have thrown an error similar to what was seen previously when navigating to the Argo CD User Interface from the web browser.

A successful authentication attempt will result in a similar response to the following:

{"token":"<TOKEN>"}

With a valid session token, the available API endpoints can be invoked.

One of the most important endpoints that is frequently queried, especially during the initial configuration of Argo CD, from any of the invocation methods discussed. The Argo CD settings endpoint is exposed at /api/v1/settings which can also be verified within the Swagger UI interface by selecting SettingsService and viewing the GET request listed below.

By expanding the responses, it is a wealth of information, much more than is provided by the CLI or the User Interface.

Figure 2-2. The properties of the SettingsService as shown in the Swagger UI interface

To invoke this endpoint, execute the following command substituting the value of the Bearer (Session) token obtained previously:

curl -k -H "Authorization: Bearer <TOKEN>" https://argocd.upandrunning.local/api/v1/settings | jq -r

A response similar to the following should be displayed:

{
  "appLabelKey": "argocd.argoproj.io/instance",
  "resourceOverrides": {
    "apiextensions.k8s.io/CustomResourceDefinition": {
      "ignoreDifferences": "jqPathExpressions: null\njsonPointers:\n- /status\n- /spec/preserveUnknownFields\nmanagedFieldsManagers: null\n"
    }
  },
  "googleAnalytics": {
    "anonymizeUsers": true
  },
  "kustomizeOptions": {
    "BuildOptions": "",
    "BinaryPath": ""
  },
  "help": {
    "chatText": "Chat now!"
  },
  "passwordPattern": "^.{8,32}$",
  "controllerNamespace": "argocd"
}

Viewing server settings is just one of the many API endpoints that can be not only queried, but updated, and adds additional weapon to the already robust arenenal of tools that are used to manage Argo CD.

However, what if there was a desire to not leverage any of these tools or any services provided by Argo CD whatsoever, but still retain the benefits and assurances of a well maintained environment?

Recall back in Chapter 2, Argo CD supports a declarative model for managing GitOps and that the Argo CD implements the controller pattern to track the state of resources bassed on defined manifests. While Argo CD responds to changes to Custom Resources, such as Application’s and AppProject’s, it also tracks additional resources, such as ConfigMaps and Secrets which are used to influence the configuration of the entire platform. So instead of using the User Interface, CLI or invoking the API, the configurations can be applied directly to the Kubernetes cluster.

Each deployable in the Argo CD architecture makes use of configuration properties stored within ConfigMaps and Secrets in the same namespace that Argo CD are deployed within. Some of these resources use a well known and established name, like a ConfigMap with the name argocd-cm which contain the primary configuration properties for Argo CD, while others use metadata within each resource to signify their importance and intended capabilities. Indeed the server settings API endpoint that was invoked previously queried the contents of this ConfigMap.

There are a number of Argo CD configurations that can be defined within ConfigMaps and they are detailed in the following table:

Table 2-2. Common Argo CD Configurations

Resource Name(s) | Kind | Description
argocd-cm | ConfigMap | General Argo CD configuration
argocd-cmd-params | ConfigMap | Argo CD environment variable configurations
argocd-rbac-cm | ConfigMap | RBAC configuration
argocd-ssh-known-hosts-cm | ConfigMap | SSH known-host configuration data

Additional resources that influence the configuration of Argo CD are stored within Secrets and do not make use of a standardized naming convention for the resource. Instead, a label with the key argocd.argoproj.io/secret-type is placed on the Secret to denote their significance.

For example, a secret with the label argocd.argoproj.io/secret-type: repository contains connection details to a remote content source repository. As Argo CD can manage content from multiple remote repositories at a time, by using the label approach, similar content with distinct values for each repository can be applied within separate Secret resources and then correlated appropriately based on the content.

The following table provides an overview of the the different Secret types and their significance:

Table 2-3. Argo Secret Types

Label | Description
argocd.argoproj.io/secret-type: cluster | The definition, configuration and credentials associated with a remote cluster
argocd.argoproj.io/secret-type: repository | Consolidated configurations and credentials associated with a remote repository
argocd.argoproj.io/secret-type: repo-config | Configurations associated to a remote repository (Not widely used)
argocd.argoproj.io/secret-type: repo-creds | Credentials for communicating with a remote repository

As topics are introduced throughout the course of this book, the way in which these resources can be used will come into focus to enable an entirely hands off approach for managing Argo CD server configuration.

This chapter introduced several methods to aid in the management of Argo CD: a visual user interface, an interactive command line utility, a comprehensive API, as well as an entirely declarative model. These options empower a freedom of choice for Argo CD administrators and end users towards using a tool or approach they feel the most comfortable using. Chapter 4 focuses on one if not the most foundational topics in the realm of Argo CD and how it is the centerpoint for facilitating GitOps practices. Managing Applications.

Chapter 3. Managing Applications

A Note for Early Release Readers

With Early Release ebooks, you get books in their earliest form—the author’s raw and unedited content as they write—so you can take advantage of these technologies long before the official release of these titles.

This will be the 4th chapter of the final book.

If you have comments about how we might improve the content and/or examples in this book, or if you notice missing material within this chapter, please reach out to the editor at jleonard@oreilly.com.

Argo CD manages the lifecycle of Kubernetes resources using a construct called Applications. An Argo CD Application is a Custom Resource Definition that contains a logical collection of related Kubernetes resources (i.e. a collection of YAML or JSON files). An Argo CD Application is the smallest unit of work in Argo CD and is where Argo CD interfaces with Kubernetes in order to deploy Kubernetes Objects.

In this chapter, we will cover the basics of an Argo CD Application, the different components including an overview of the types of sources Applications can connect to, how to use different Kubernetes templating tools that Argo CD natively supports, and finally, the lifecycle of an Argo CD Application.

Application Basics

As previously mentioned, an Argo CD Application is the atomic working unit in Argo CD. It defines the end state of the desired set of resources within a Kubernetes cluster. Let’s take a look at an example of an Argo CD Application:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: bgd
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/redhat-scholars/argocd-tutorial
    targetRevision: main
    path: assets/examples/bgd-yaml/
  destination:
    server: https://kubernetes.default.svc
    namespace: bgd

The definition above is a minimal example of what is needed for an Argo CD Application to be functional within a cluster. For the time being, the two main pieces of information that you should focus on are the .spec.source and .spec.destination sections.

.spec.source

Defines the location containing resources that Argo CD should interface with. This property includes key options, such as repoURL, which defines where the Git repository or a Helm Chart Repository that holds the manifests are located. The targetRevision, where you can define what branch or tag should be targeted; or in the case of a Helm Chart, the version of the Helm Chart you want deployed. And finally, the path; which is where to find the Kubernetes manifests relative to the repoURL.

Note

The namespace in the Application YAML should match the namespace of where your Argo CD instance is installed - this is typically this is the argocd namespace. In our example, we are using the default argocd namespace. Starting in Argo CD version 2.5, support was added to enable sourcing Applications from namespaces other than where Argo CD is deployed. However, this feature will not be used in the examples found within this publication.

You can take a look at a comprehensive example in the Argo CD Project Git repository for all of the options available to you. Other sections of note which we will not cover in detail within this chapter, but in subsequent chapters, are the options for when Applications are synchronized against cluster(s) within the syncPolicy property as well as how differences between the expected rendered state of resources and the actual state within a cluster are handled. Understanding and managing resources beyond their initial creation is related to a concept called drift management and is one of the key benefits provided by Argo CD.

Application Sources

Argo CD takes the desired state defined in the Application CRD, and attempts to modify the current running state on the Kubernetes cluster based on the defined content. Argo CD was built from the ground up with GitOps in mind, it therefore supports two sources for the source of truth: Git and Helm.

The source field in an Argo CD Application has a 1:1 relationship with the Application specification. In other words, only one source can be configured per Application.

Starting with Argo CD v2.6, you can have a sources field now and specify more than one source. An example of a multi source Application can be found below:

spec:
  sources:
    - repoURL: https://github.com/christianh814/gitops-examples
      path: applicationsets/rollingsync/apps/pricelist-config
      targetRevision: main
    - chart: mysql
      repoURL: https://charts.bitnami.com/bitnami
      targetRevision: 9.2.0
      helm:
        releaseName: pricelist-db
        parameters:
          - name: serviceAccount.name
            value: "pricelist-db"
          - name: auth.database
            value: "pricelist"
          - name: auth.username
            value: "pricelist"
          - name: auth.password
            value: "pricelist"
          - name: secondary.replicaCount
    - repoURL: https://github.com/christianh814/gitops-examples
      path: applicationsets/rollingsync/apps/pricelist-frontend
      targetRevision: main

Note

Using sources field will cause Argo CD to ignore the source field

Let’s review the two source types of an Application.

Git

Using Git as a source is a natural starting point for Argo CD users as it’s the focal point of where “GitOps” gets its name. Git is not only the de facto source control management system (SCM) for developers, but is also the place where site reliability engineers (SREs) and platform engineers store their Infrastructure-as-Code (IaC) configurations. Many users making the switch to Argo CD and/or GitOps find that they are already storing a lot of things on Git already.

Storing resources in Git, as an Argo CD Application source, can be as simple as having raw YAML stored containing Kubernetes resources within a directory. However, it doesn’t have to be raw YAML. The declarations can also be stored and managed via templating tools, such as Kustomize (covered later) or Helm (covered next).

Helm

Helm has become the de facto package manager for Kubernetes applications and deployments. At its core, Helm includes a templating engine for use with Kubernetes manifests so that they are reusable, reproducible, and stable. Many organizations have adopted Helm and is a natural choice for developers and system administrators alike - its popularity stems from its ease of use and flexibility.

Since many organizations have widely adopted Helm, it was a natural fit for Argo CD. Argo CD can use Helm either by directly consuming the Helm Chart stored in a standard Helm repository, OCI registry, or embedded within a Git repository.

Destinations

In Argo CD, the “destination” is in reference to a Kubernetes cluster. This destination cluster can either be the cluster that is running Argo CD or another remote cluster (which can be thought of as “hub and spoke”).

Clusters

The destination cluster is noted under .spec.destination in the Argo CD Application manifest. Here is a snippet of the configuration.

spec:
  destination:
    server: https://kubernetes.default.svc
    namespace: bgd

In the example above, the server field is set to https://kubernetes.default.svc which refers to the cluster that Argo CD is running on. The namespace field indicates which namespace to target.

Note

The namespace field DOES NOT overwrite the .metadata.namespace field if they are declared within your manifests.

Clusters can be added either declaratively or via the argocd CLI resulting in a new Secret to be added to the namespace Argo CD is deployed within.

$ kubectl get secrets -n argocd -l argocd.argoproj.io/secret-type=cluster
NAME                               TYPE     DATA   AGE
cluster-192.168.1.254-1289728133   Opaque   3      31s

Notice in the command above, a label selector argocd.argoproj.io/secret-type=cluster is specified. Argo CD sources several types of configurations from Secrets and their type is denoted by the key argocd.argoproj.io/secret-type. Specifying a value of cluster indicates that the content of this Secret contains the definition representing a cluster for which Argo CD can manage. Other types of Argo CD secrets will be covered in subsequent chapters.

The Secret containing cluster configuration is formatted in the following way.

apiVersion: v1
kind: Secret
metadata:
  name: prod-cluster
  labels:
    argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
  name: prod-cluster
  server: https://prod.k8s.example.com:6443
  config: |
    {
      "bearerToken": "<authentication token>",
      "tlsClientConfig": {
        "insecure": false,
        "caData": "<base64 encoded certificate>"
      }
    }

Here the name field is the name that you can refer to in the .spec.destination.server field in the Argo CD Application manifest. The server field is the Kubernetes API endpoint that Argo CD will try to communicate with. The config field is a JSON object that contains information about how to connect to the Kubernetes API endpoint, the token that is needed and any TLS Configurations that you may need. Other options for authenticating with the target Kubernetes cluster are also available, but the use of a bearer token is the most straightforward and common method used.

Once the Secret has been created, the target cluster and its status will be available for inspection if desired using the UI or CLI.

Tools

One of the main tenets of GitOps is that declarations/configurations must exist in an immutate format. In a Kubernetes environment, this means that YAML is stored inside a Git repository. After a while, those who are just starting out in their GitOps journey, ask themselves: “How do I declaratively describe my resources in Git without copying and pasting the same YAML all over the place?”

It might seem like you’ll have to duplicate a lot of the same YAML after you take things like environments, clusters, regulatory restrictions, and anything else in your organization that might force you to create a lot of YAML with only slight variations between files into consideration. After a while this simple YAML that should be applicable “anywhere”...all of sudden doesn’t fit anywhere. Luckily, there are tools that can help you mitigate the issue of having to copy and paste the same YAML all over the place and making only small modifications.

Helm

Helm has become the de facto package manager and delivery mechanism for applications and controllers alike in a Kubernetes based environment. If you’ve ever worked on a Kubernetes cluster previously, you have most likely used Helm at some point to deploy ISV’s stacks or even deliver your own application by leveraging its automation benefits. Helm provides not only a method of packaging an application and parameterizing YAML manifests, but also a templating engine that can be used to deploy your application to different environments.

Helm consists of different parts; one of them is called “charts”, which are templatized versions of your application’s YAML manifests that are parameterized so that you can inject values into the defined templates. Helm combines the templatized manifests with parameters, called Values, to produce the resources to apply to the Kubernetes cluster. The specific installation of a chart within a cluster is known as a “release”. The endstate representation of the produced manifests of a release is stored as a secret within the installed namespace on the Kubernetes cluster.

Note

Secrets are the default backend storage for Helm 3. Other backends, such as ConfigMaps or a relational database. Consult the Helm documentation for more information.

Helm has a large ecosystem and many repositories that end users can draw on to deploy pre-built applications. If your organization uses Helm heavily, you’re in luck! Most GitOps tools support deploying Helm charts.

Kustomize

Kustomize is a framework built within the Kubernetes community that lets you patch Kubernetes manifests without a need to modify the original Kubernetes manifests. While patching can be done via JSON patches, the manifest that it modifies needs to be in YAML.

Kustomize is hierarchically organized using a directory structure based on a concept of “bases” and “overlays”. While each of these directories have their own purpose within Kustomize, they must contain a kustomization file (kustomization.yaml) which defines how to process the contents within the current directory along with importing content from other relative or remote sources. An “overlay” directory will include a reference to one or more bases, but a base directory can be included in one or more “overlays”.

The following is a simple example of a kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namePrefix: kustomize-

resources:
- guestbook-ui-deployment.yaml
- guestbook-ui-svc.yaml

When using Kustomize against the prior example, two Kubernetes resources will be produced with their names prefixed with “kustomize-” as defined in the namePrefix property.

Kustomize is a powerful tool, and since it is built within the Kubernetes community, support is available within the kubectl CLI. Adding the -k flag when using kubectl create and kubectl apply commands will activate Kustomize processing. However, by using the kubectl kustomize subcommand instead, the full featureset of the kustomize CLI can be achieved.

Kustomize truly is a powerful tool because it eliminates the duplication of YAML and enables the ability to reuse by providing a method of patching the YAML to fit the need of the deployment. This means that you can store differences (for example between environments) as deltas instead of copying the YAML for each use. The Kustomize structure provides flexibility by creating “overlays” that can leverage other bases and other overlays, almost creating a cascading sequence of files. Those overlays can refer to remote repositories as well. Kustomize can even process Helm charts and how this can be achieved within Argo CD in a subsequent chapter.

Beyond Helm and Kustomize

While Helm and Kustomize are the two primary tools that are used in Argo CD to render resources within a Kubernetes cluster (aside from raw YAML), other tools are also supported. Argo CD natively supports the JSON templating language Jsonnet and will process any file containing the *.jsonnet extension. Non-native tooling can also be included through the use of a Config Management Plugin eliminating restrictions to customizing how Kubernetes resources are produced. More information on Config Management Plugins and their use can be found in Chapter 11.

Deploying Your First Application

Now that you’ve gotten familiar with what an Argo CD Application is and its basic functionality, it’s now time to deploy your first Argo CD Application! Yes, we did walk through deploying an Application back in Chapter 2 when Argo CD was first installed, but by now, you have a better understanding of the purpose of an Application and how they can be used. Throughout the rest of this book, you’ll be exploring many ways of deploying an Application, but for this example, we’ll be going with the simplest way possible: Deploying from a Helm Chart.

For this example, create the the following Argo CD Application YAML in a file called quarkus-app.yaml:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: quarkus-app
  namespace: argocd
spec:
  project: default
  destination:
    namespace: demo
    name: in-cluster
  source:
    helm:
      parameters:
        - name: build.enabled
          value: "false"
        - name: deploy.route.enabled
          value: "false"
        - name: image.name
          value: quay.io/ablock/gitops-helm-quarkus
    chart: quarkus
    repoURL: https://redhat-developer.github.io/redhat-helm-charts
    targetRevision: 0.0.3
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true

Here, we are going to define the name of the Application to be quarkus-app and we will be deploying the Application to the same cluster as Argo CD is running (denoted by in-cluster in the .spec.destination.name field). We are targeting the demo namespace on the destination cluster (i.e. which namespace to deploy the manifests to)

Note

The keyword in-cluster is a special keyword that mean “target the cluster that the instance of Argo CD is running in”

We are deploying the quarkus chart version 0.0.3 from the repo denoted in the repoURL field. We are also providing any parameters in the .spec.source.helm.parameters field which represent Helm values being set against the chart. Also take note we are adding the CreateNamespace=true option in the syncOptions field (in order to make sure the namespace exits before deploying the manifests). This example deployment of a Helm Chart using an Argo CD Application is analogous to the following command

$ helm install quarkus-app --namespace demo --create-namespace --version 0.0.3 \
--set build.enabled=false \
--set deploy.route.enabled=false \
--set image.name=quay.io/ablock/gitops-helm-quarkus \
redhat-helm-charts/quarkus

Note

To make use of the sample helm install command from above, the Helm Chart repository containing the quarkus chart must be added to the local machine using the helm repo add https://redhat-developer.github.io/redhat-helm-charts command. If the chart is installed using the Helm CLI, be sure that it is uninstalled prior to defining the chart using Argo CD. Otherwise errors will be produced.

To create this Argo CD Application within the Kubernetes cluster, you can apply it using the following kubectl command.

kubectl apply -f quarkus-app.yaml

You should see the Application appear in the Argo CD UI:

Figure 3-1. Sample Helm Chart Application

Note

See Chapter 2 - Installing Argo CD and Chapter 3 - Interacting with Argo CD for more information about connecting to the Argo CD UI

You should also be able to see the manifests deployed on the cluster using the Kubernetes CLI client.

$ kubectl get deploy,service,pods -n demo
NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/quarkus-app   1/1     1            1           9m24s

NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/quarkus-app   ClusterIP   10.106.53.207   <none>        8080/TCP   9m24s

NAME                               READY   STATUS    RESTARTS   AGE
pod/quarkus-app-57cf4d4b5c-q5jb8   1/1     Running   0          9m24s

One very important thing to note is the behavior in comparison to using the Helm CLI directly. Running helm ls —n demo against the namespace that contains an Argo CD managed Helm chart will not return any results:

$ helm ls -n demo
NAME    NAMESPACE       REVISION        UPDATED STATUS  CHART   APP VERSION

Note

You may see other helm releases running, but you won’t see anything deployed via Argo CD

Why? Argo CD takes the philosophical approach of only working with “RAW Kubernetes manifests” directly. Meaning that Argo CD wants to “own” the manifests and not have to rely on trying to interface with another tool. Argo CD achieves this by doing the equivalent of running: helm template <options> | kubectl apply -f -

A release is only created whenever the install or upgrade subcommands of the Helm CLI is used which explains why a release is not present for Helm charts maintained by Argo CD.

Deleting Applications

Regardless of the tool being used to produce Kubernetes resources or the destination of where these resources will be created, there may be a need to remove the Application so that the generated resources are no longer managed by Argo CD. Deleting an Application, similar to creating an Application can be facilitated either using either of the methods that we have touched upon previously. Since we have used kubectl commands to create the Helm based Application in the prior section, we can use the same approach to delete the Application.

Execute the following command to delete the Application:

kubectl delete application quarkus-app -n argocd

Once the Application has been deleted, the tile representing the Application will no longer be present in the Argo CD interface.

What is important to note and you may have discovered this already is that even though the Application was deleted, the resources that were managed by the Application still remain within the argocd namespace.

Why is that the case you may wonder?

Argo CD makes the assumption that even though there is no longer a desire to manage these sets of resources, there will still be a need for them to remain within the cluster after the Application is deleted. This is mainly due to the motivation of avoiding data loss of the resources and anything dependent on them being available. This approach is similar to how PersistentVolumes are managed within StatefulSets upon the removal of the StatefulSet itself or one of the replicas.

To remove the resources that are managed by an Application, the resources-finalizer.argocd.argoproj.io finalizer can be set on the Application which is shown below:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: quarkus-app
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io

If an Application has this finalizer present, upon deletion, the Argo CD controller will perform a cascading deletion of all of the resources that it is managing..

Finalizers

Finalizers are a feature of Kubernetes associated with Garbage Collection that controls when a resource is deleted.When a resource is deleted, the .metadata.deletionTimestamp field is populated which triggers controllers to clean up any resource that is owned by the resource being deleted. Once the cleanup process completes, the associated controller will remove the finalizer from the resource. Only when all finalizers have been removed will the resource itself be deleted.

When deleting dependent resources, Argo CD makes use of the foreground cascade deletion policy which will delete the dependent resources first and then delete the Application afterward. If there is a desire to use the background cascade deletion policy which will delete the Application immediately while the controller deletes the associated resources, the resources-finalizer.argocd.argoproj.io/background finalizer can be set on the Application as shown below.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: quarkus-app
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
    - resources-finalizer.argocd.argoproj.io/background

About the Authors

Andrew Block is a Distinguished Architect at Red Hat who works with organizations throughout the world to design and implement solutions leveraging cloud native technologies. He specializes in embracing security at every phase of the Software Development Lifecycle and delivering software in a repeatable and consistent manner. Andrew has authored several publications related to the cloud native ecosystem including Managing Kubernetes Resources Using Helm and Kubernetes Secrets Management in order to share his knowledge with others. He holds several roles in the Open Source community and is a core maintainer of Helm, a package manager for Kubernetes.

Christian Hernandez currently is a Technical Product Manager at Red Hat and is a co-host of the biweekly stream called GitOps Guide to the Galaxy. A contributor to Argo CD and Maintainer of the OpenGitOps project, Christian is a technologist with experience in infrastructure engineering, systems administration, enterprise architecture, tech support, advocacy, and management. Lately, he has been focusing on Kubernetes, DevOps, cloud-native architecture, and GitOps practices. Christian is passionate about open source and containerizing the world one application at a time.