Manage ArgoCD Resources Programmatically with Golang š¹
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.