Manage ArgoCD Resources Programmatically with Golang šŸ¹

Emre Ɩnal
7 min readMay 3, 2023

--

In this article, we will examine how to manage ArgoCD resources with Go for programmatically creating projects, clusters, and destinations with example codes.

Prerequisites

  • Go for developing a resource manager program.
  • Docker Desktop for virtualization.
  • Minikube for creating a local Kubernetes cluster.
  • Kubectl for a Kubernetes command-line tool.
  • ArgoCD CLI for generating a account token.

Steps

Open a terminal window and execute the following commands:

Start Docker Desktop

This command initiates the Docker engine for virtualization.

open -a docker

Create a local Kubernetes cluster

This command launches the local Kubernetes cluster and adds the Minikube context to the ~/.kube/config file.

minikube start

Switch to Minikube context

In an environment with multiple clusters, we will switch to the Minikube context using this command.

This step is typically performed automatically after installing Minikube.

kubectl config use-context minikube

Create a namespace

Namespaces serve as a logical grouping of objects within a Kubernetes cluster. This command establishes a new namespace in the current Minikube Kubernetes context, where the ArgoCD installation will take place.

kubectl create namespace argocd

Install the latest version of ArgoCD

This command deploys ArgoCD on the current Minikube Kubernetes context, enabling access to ArgoCD in a local environment.

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

Check deployments

Letā€™s see what happens on the cluster after the ArgoCD installation.

kubectl get all -n argocd

Add a new fully authorized account

While our admin account typically possesses comprehensive permissions, it cannot generate tokens for security reasons.

Consequently, we must create a fully authorized account to modify ArgoCD resources. This command introduces an account named foo:

EDITOR=nano kubectl edit configmap argocd-cm -n argocd

Append the following fields to the YAML file in the opened editorĀ andĀ save:

data:
accounts.foo: apiKey, login

This action successfully generates a new account.

Next, configure the permissions for the account we created by running the following command to open the editor:

EDITOR=nano kubectl edit configmap argocd-rbac-cm -n argocd

Append the following fields to the YAML file in the opened editor and save:

data:
policy.csv: |
g, foo, role:admin

We now have a foo account with full permissions.

Obtain the default admin password

Upon installation, ArgoCD provides an admin user. To log in to ArgoCD using the admin user, we require the password.

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

Forward argocd-server port to local machine network

To access ArgoCD from our browser, we must forward the argocd-server port to our local machine. Port forwarding terminates when the terminal closes.

To execute other commands in the same terminal, add a &to the end of the following command:

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

This command forwards the ArgoCD serverā€™s port to our local machineā€™s port 8080. We can now access the ArgoCD web interface by launching a browser and navigating to localhost:8080.

Generate an account token

A token is required for ArgoCD resource operations within the Go program. Letā€™s log in using the ArgoCD CLI:

argocd login localhost:8080 --insecure

When prompted for a username and password, enter admin the username and the previously acquired password for the admin user.

After logging in, generate an account token for the foo account with the following command:

argocd account generate-token --account foo

Develop Golang Resource Manager Program

We have completed the necessary installations. Now, letā€™s start building our application to manage ArgoCD resources using Golang.

In this project, we perform resource operations over gRPC using the ArgoCD Go library. Because it is more type-safe and fast. You can do the same using REST API. If you want to see the ArgoCD Swagger: http://localhost:8080/swagger-ui

Create project with folder structure

We may need to manage multiple resources in a project using ArgoCD or another tool. Therefore, we must establish a project structure that supports multiple tools and avoids complexity as it grows.

We will use the Standard Go Project Layout for this purpose and include a few useful tools, such as a linter. As an example, we will name our project engine.

Create client connection definitions

This code defines two structs: Connection and Client. The Connection struct has two fields, Address and Token, both of type string. This struct is used to store information about the connection to an ArgoCD server, such as its address and authentication token.

The Client struct also has two fields: projectClient and clusterClient. These fields are of type project.ProjectServiceClient and cluster.ClusterServiceClient, respectively. This struct is used to perform operations related to projects and clusters on the ArgoCD API.

The NewClient function takes a pointer to a Connection struct as input and returns a pointer to a Client struct and an error (if any). This function creates a new ArgoCD API client using the apiclient.NewClient() function from the apiclient package. The values in the Connection struct are used to configure the clientā€™s connection to the ArgoCD server.

Next, the NewProjectClient() and NewClusterClient() methods are called on the API client object to create clients for projects and clusters. These methods return a context, a client, and an error. The project and cluster clients are then used to initialize the Client struct.

Overall, this code demonstrates how to set up an ArgoCD API client using Go, allowing you to perform operations related to projects and clusters.

Hereā€™s the code for the /internal/driver/argocd/client.go file:

Create cluster resource definitions

The Client struct has a method called GetClusters() that returns a slice of v1alpha1.Cluster objects and any errors encountered. This method takes no arguments.

To retrieve the list of available clusters, the method uses the clusterClient field of the Client struct to call the List() method from the cluster package.

The resulting cl object has an Items field, which contains the list of available clusters. The method returns this Items field as a slice of v1alpha1.Cluster objects, along with a nil error.

These steps demonstrate how to retrieve the list of available clusters from an ArgoCD server using Go.

Hereā€™s the code for the /internal/driver/argocd/cluster.go file:

Create destination resource definitions

The Client struct has a method called AddDestination() that takes four arguments: projectName, server, namespace, and name.

The method first calls the GetProject() method from the project package, passing in the projectName argument. This method returns the project with the provided name.

Next, the GetProject() method updates the projectā€™s destinations by creating a new v1alpha1.ApplicationDestination object and setting its fields to the values of the provided arguments.

Finally, the method calls the Update() method from the project package, passing in a new ProjectUpdateRequest object containing the updated project. This updates the projectā€™s destinations to include the newly added destination.

These steps demonstrate how to add a destination to an ArgoCD project using Go.

Hereā€™s the code for the /internal/driver/argocd/destination.go file:

Create project resource definitions

The Client struct, which is used to interact with the ArgoCD API, has several methods defined for managing projects.

The CreateProject method creates a new project with a given name and returns a pointer to the created AppProject object, along with any errors encountered. This is achieved by calling the Create() method from the project package, which takes a ProjectCreateRequest object containing the AppProject with its Name field set to the provided name.

The DeleteProject() method deletes a project with a given name by calling the Delete() method from the project package. This method returns an error if the project cannot be deleted.

The GetProject() method retrieves a project with a given name by calling the Get() method from the project package. This method returns a pointer to the AppProject object and any errors encountered.

These methods demonstrate how to interact with the ArgoCD project API using Go.

Hereā€™s the code for the /internal/driver/argocd/project.go file:

Trying to execute some driver resource operations

In the main() function, we create an connection object with the ArgoCD serverā€™s address and token. Then, using this connection object, we create an client object through which we can interact with the ArgoCD API.

The code continues by creating a new project named foo and displaying its unique identifier. It then adds a destination to the project and retrieves the projectā€™s namespace field.

Finally, the code deletes the foo project and retrieves the names of all available clusters.

Overall, this code performs a set of operations on the ArgoCD server, demonstrating how to interact with it using the provided API methods.

Hereā€™s the code for the /cmd/engine/main.go file:

Summary

In this project, we utilized some resource definitions as examples. You can perform any ArgoCD resource operations you desire using these code samples.

For example, I am trying these example PoC codes to develop the CD processes of a serverless FaaS project similar to OpenFaaS, which can also be used for SRE automations and other purposes.

You can access the full code here.

--

--