Working example using ArgoCD

There are quite a few good working examples on the Web that you can rely on and build your own solutions. This article is based on an article from the company’s blog Nortaland is intended for small projects and teams, because the main focus is on Application.
Theoretical part
General concept
The ArgoCD documentation suggests using declarative attitude, which allows you to explicitly define the necessary settings. This installation can also include the creation application, through which to implement the approach app of app. The concept is as follows: when ArgoCD is installed, several Application resources are created, which rely on Git repository. In turn, the Git repository contains: a chart generating Application for custom applications, a source chart for custom applications, and a chart for deploying infrastructure applications.

The concept of deploying infrastructure applications
Used here infra chart which will be:
Automatically generate Application from the general template
Substitute values from properties into the template applicationsin which the nested array of objects
The concept of deploying custom applications
Here are used common and apps charts. AT apps chart will be:
Automatic generation Application from the general template
Substitute values from properties into the template applicationsin which the nested array of objects
The main template refers to common chart
AT common the chart will have common templates for resources: Deploymen, Ingress, Service, etc. And there will also be directories with files containing parameters for each application and its separate environment.

Practical part
Setting up argocd-server
To the parameters of the official chart in the section serveryou need to add an application appswhich will be the parent app of app, and will create child Applications for custom applications. For convenience and logical separation, an application with the name infra, from which infrastructure applications will be deployed. Example of required settings:
# -- Deploy ArgoCD Applications within this helm release
# @default -- `[]` (See [values.yaml])
## Ref: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/
additionalApplications:
- name: apps
namespace: argocd
additionalLabels: {}
additionalAnnotations: {}
project: default
source:
repoURL: https://github.com/dmitrii-dmnk/argocd-working-example.git
targetRevision: master
path: apps
helm:
valueFiles:
- values.yaml
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
- name: infra
namespace: argocd
additionalLabels: {}
additionalAnnotations: {}
project: default
source:
repoURL: https://github.com/dmitrii-dmnk/argocd-working-example.git
targetRevision: master
path: infra
helm:
valueFiles:
- values.yaml
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
The above settings are collected in one file argrocd.yamland available on github.
Solutions for deploying custom applications
To deploy custom applications, charts are required apps and common. In the apps chart, Application is being generated from a common template. Separately, it is worth noting that the Nortal company blog offers the option to parameterize the application directly in the apps chart. In the current operating conditions, this approach turned out to be redundant, and it was easier to move all customizable parameters into values files of the same name in common chart.
Sample template from apps chart
The template for custom Application looks like this:
{{ $targetRevision := .Values.targetRevision }}
{{ $repoURL := .Values.repoURL }}
{{ $project_name := .Values.project_name }}
{{- range $application := .Values.applications }}
{{- range $namespace := $application.namespaces }}
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: {{ $application.name }}-{{ $namespace }}
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
destination:
namespace: {{ $namespace }}
server: https://kubernetes.default.svc
project: {{ $project_name }}
source:
path: common
repoURL: {{ $repoURL }}
targetRevision: {{ $targetRevision }}
helm:
valueFiles:
- values.yaml
- values/{{ $application.name }}.yaml
- values/{{ $namespace }}/{{ $application.name }}.yaml
syncPolicy:
automated:
prune: true
selfHeal: true
---
{{- end }}
{{- end }}
AT values.yaml in properties applications there is a nested array of objects that looks like this:
applications:
- name: guestbook
namespaces: [develop,test]
- name: hello-kubernetes
namespaces: [develop,test]
- name: static
namespaces: [develop,test]
Different work cases require different approaches, so in common The demo chart will show the default helm-generated chart almost unchanged. Separately, a parameter was added to set the container port.
Deployment Solutions for Infrastructure Applications
There are several options for parameterizing the deployed application from third-party and official charts, namely:
spec.source.helm.values: |
все необходимые настройки
Disadvantages of this approach: there is no way to template the Application, some parameters may contain double curly braces, which will cause similar errors:
Error: template: infra/templates/argocd.yaml:2304:63: executing "infra/templates/argocd.yaml" at <.app.metadata.name>: nil pointer evaluating interface {}.metadata
spec.source.helm.values: |
{{ $valueFileContent }}
With this approach, there will be no errors in the presence of double curly braces. It will also be easier to edit the application parameters, because the syntax highlighting in the editor will not break, there will be no extra indents, and it will be possible to template.
An example of a template from the infra chart
The template for Infrastructure Application looks like this:
{{- range $application := .Values.applications }}
{{ $valueFilePath := print "values/" $application.name ".yaml" }}
{{ $valueFileContent := $.Files.Get $valueFilePath | nindent 8 }}
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: {{ $application.name }}
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
destination:
server: https://kubernetes.default.svc
namespace: {{ $application.namespace }}
project: {{ $application.project | default "default" }}
syncPolicy:
automated:
prune: true
selfHeal: true
source:
path: ''
repoURL: {{ $application.repoURL }}
targetRevision: {{ $application.targetRevision }}
chart: {{ $application.chart }}
helm:
values: |
{{ $valueFileContent }}
---
{{- end }}
AT values.yaml in properties applications there is a nested array of objects, looks like this:
applications:
- name: argocd
namespace: argocd
chart: argo-cd
targetRevision: 3.33.6
repoURL: https://argoproj.github.io/argo-helm
- name: cert-manager
namespace: infra
chart: cert-manager
targetRevision: v1.8.0
repoURL: https://charts.jetstack.io
- name: tomcat
namespace: infra
chart: tomcat
targetRevision: 10.3.9
repoURL: https://charts.bitnami.com/bitnami
Applying the above settings
For demonstration purposes, you can use the ready-made configuration argocd.yamland deploy ArgoCD to minikube.
We clone the repository with the settings, and run the installation script:
git clone git@github.com:dmitrii-dmnk/argocd-working-example.git;
cd argocd-working-example/helpers;
sh setup.sh
At this point, the necessary settings are completed. All applications will be automatically deployed, because they were described in advance.
Conclusion
Helm’s capabilities fit well with application deployment through the creation of an Application. The flexibility of templating allows you to solve work tasks in a practical way. The recommendations and descriptions of the solutions above were obtained during the practical use of ArgoCD. Welcome: criticism, wishes, suggestions.