This blog post is one example “how to setup an app-of-apps pattern in ArgoCD” and is in the context of the blog post How to use a declarative setup for Argo CD to deploy an application using a Helm repository?
The app of apps pattern enables you to use Argo CD to deploy Argo CD application configurations to deploy new applications to a cluster. We will use Argo CD to configure Argo CD.
The blog post is organized in the following sections:
- Simplified architecture overview
- Understand the
"app-of-apps"
Argo CD configuration for the example - Detailed steps to deploy the example app-of-apps with Helm
- Verify the example app-of-apps in Argo CD
- Summary
Note: You can access the source code related to the current blog post in the
GitHub project
I created. The project is under Apache-2.0 license.
1. Simplified architecture overview
That is a simplified architecture overview

As a starting point we are using the blog post called “Use Software Everywhere and IasCable to setup GitOps on a Red Hat OpenShift Cluster in a Virtual Private Cloud on IBM Cloud” to configure and setup the needed following resources.
- IBM Cloud
- Red Hat OpenShift in a VPC
- Argo CD is setup and with an initial gitops bootstap
And we are going to use …
- … two existing GitHub repositories
- … Helm to deploy the
app-of-apps
vend example
application to our cluster - … the folder
"root-applications"
in gitops-app-of-apps repository contains the ArgoCD configuration yaml for theexample vend app
lication.
Note: In current example we won’t use the pre-configured bootstap resoures for Argo CD resources, created by the Software Everywhere module called terraform-tools-gitops.
2. Understand the "app-of-apps"
Argo CD configuration for the example
To understand the "app-of-apps"
Argo CD configuration we take a look into the Argo CD configurations we are going to use. In the diagram you see an extract for Argo CD only configuration of the simplified architecture overview diagram.

a) Repository
apiVersion: v1
kind: Secret
metadata:
name: {{ .Values.repository_metadata_name }}
namespace: {{ .Values.repository_metadata_namespace }}
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: {{ .Values.repository_stringData_url }}
Relevant values for the repository in the Helm values.yaml
file.
repository_metadata_name: "github.com-thomassuedbroecker-gitops-app-of-apps"
repository_metadata_namespace: "openshift-gitops"
repository_stringData_url: "https://github.com/thomassuedbroecker/gitops-app-of-apps"
b) Project
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: {{ .Values.project_metadata_name }}
namespace: {{ .Values.project_metadata_namespace }}
spec:
clusterResourceWhitelist:
- group: '*'
kind: '*'
description: This is just an root-project example.
destinations:
- name: {{ .Values.project_destination_name }}
namespace: '*'
server: {{ .Values.project_destination_server }}
namespaceResourceWhitelist:
- group: '*'
kind: '*'
sourceRepos:
- '*'
status: {}
Relevant values for the repository in the Helm
file.values.yaml
Let us have a short look at some of the values:
project_metadata_namespace
: Here we reuse the exising"openshift-gitops"
namespace.project_destination_namespace
: We allow all namespases"*"
as destination namespaces.project_destination_name
: We configure only"in-custer"
as a valid cluster, that means using the cluster where Argo CD is installed.project_source_repo_url
: We configure our repository, where we are going to search for new applications to deploy.
project_metadata_name: "root-application"
project_metadata_namespace: "openshift-gitops"
project_destination_namespace: "*"
project_destination_name: "in-cluster"
project_destination_server: "https://kubernetes.default.svc"
project_source_repo_url: "https://github.com/thomassuedbroecker/gitops-app-of-apps"
c) app-of-apps
Application
This is the app-of-apps
application configuration. We call the configuration in our situation the application root-application
.
The image below shows a later stage, when we sync all resources.

The ArgoCD root-application is not defined as a specific type deployment types like Helm for example.
Based on that we don’t define restrictions for the new Argo CD application configuration entries in that folder. The relevant entry in the values.yaml is application_source_path: “root-applications”. The root-applications directory is where we can insert new apps. In our case the root-applications folder contains the Argo CD application configuration for the vend application example.
It just contains the information:
- Related Argo CD project
- Destination information
- Source information
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: {{ .Values.application_metadata_name }}
namespace: {{ .Values.application_metadata_namespace }}
spec:
destination:
name: {{ .Values.application_destination_name }}
namespace: {{ .Values.application_destination_namespace }}
project: {{ .Values.application_project }}
source:
path: {{ .Values.application_source_path }}
repoURL: {{ .Values.application_source_repo_url }}
targetRevision: HEAD
syncPolicy:
retry:
backoff:
duration: 5s
factor: 2
maxDuration: 3m0s
limit: 2
application_metadata_name: "root-application"
application_metadata_namespace: "openshift-gitops"
application_destination_namespace: "openshift-gitops"
application_destination_name: "in-cluster"
application_project: "root-application"
application_source_repo_url: "https://github.com/thomassuedbroecker/gitops-app-of-apps"
application_source_path: "root-applications"
d) example vend
Application
The following configuration of the application contains the link to GitHub repo for with the Helm chart to deploy the example vend app
lication.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: vend
namespace: openshift-gitops
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
destination:
name: in-cluster
namespace: openshift-gitops
project: root-application
source:
helm:
valueFiles:
- values.yaml
path: "charts/vend-helm"
repoURL: "https://github.com/thomassuedbroecker/vend-helm"
targetRevision: HEAD
syncPolicy:
retry:
backoff:
duration: 5s
factor: 2
maxDuration: 3m0s
limit: 2
3. Detailed steps to deploy the example app-of-apps with Helm
Step 1: Clone the project
git clone https://github.com/thomassuedbroecker/gitops-app-of-apps.git
Step 2: Navigate to the “charts” folder
cd charts
Step 3: Ensure you are connect to your OpenShift cluster with admin rights
oc login --token=YOUR_TOKEN --server=https://YOUR_SERVER_URL
Step 4: Update Helm dependencies
helm dependency update ./root-application
Step 5: Verify Helm configuration
- Verify with lint
helm lint ./root-application
- Example output:
==> Linting ./root-application
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed
- Do a dry-run
helm install --dry-run --debug root-application ./root-application/
- Example output:
install.go:178: [debug] Original chart version: ""
install.go:195: [debug] CHART PATH: /Users/thomassuedbroecker/Downloads/dev/gitops-app-of-apps/charts/root-application
NAME: root-application
LAST DEPLOYED: Mon Aug 22 19:26:23 2022
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
application_destination_name: in-cluster
application_destination_namespace: openshift-gitops
application_metadata_name: root-application
application_metadata_namespace: openshift-gitops
application_project: root-application
application_source_path: root-applications
application_source_repo_url: https://github.com/thomassuedbroecker/gitops-app-of-apps
project_destination_name: in-cluster
project_destination_namespace: '*'
project_destination_server: https://kubernetes.default.svc
project_metadata_name: root-application
project_metadata_namespace: openshift-gitops
project_source_repo_url: https://github.com/thomassuedbroecker/gitops-app-of-apps
repository_metadata_name: github.com-thomassuedbroecker-gitops-app-of-apps
repository_metadata_namespace: openshift-gitops
repository_stringData_url: https://github.com/thomassuedbroecker/gitops-app-of-apps
HOOKS:
MANIFEST:
---
# Source: root-application/templates/repository.yaml
apiVersion: v1
kind: Secret
metadata:
name: github.com-thomassuedbroecker-gitops-app-of-apps
namespace: openshift-gitops
labels:
argocd.argoproj.io/secret-type: repository
stringData:
type: git
url: https://github.com/thomassuedbroecker/gitops-app-of-apps
---
# Source: root-application/templates/project.yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: root-application
namespace: openshift-gitops
spec:
clusterResourceWhitelist:
- group: '*'
kind: '*'
description: This is just a root-project example.
destinations:
- name: in-cluster
namespace: '*'
server: https://kubernetes.default.svc
namespaceResourceWhitelist:
- group: '*'
kind: '*'
sourceRepos:
- '*'
status: {}
---
# Source: root-application/templates/application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-application
namespace: openshift-gitops
spec:
destination:
name: in-cluster
namespace: openshift-gitops
project: root-application
source:
path: root-applications
repoURL: https://github.com/thomassuedbroecker/gitops-app-of-apps
targetRevision: HEAD
syncPolicy:
retry:
backoff:
duration: 5s
factor: 2
maxDura
Step 6: Install Argo CD configuration using Helm
helm install root-application ./root-application/
- Example output:
NAME: root-application
LAST DEPLOYED: Mon Aug 22 19:28:34 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
Step 7 (optional): Uninstall Argo CD configuration using Helm
helm uninstall root-application
Note: When we create the repository with Helm we don’t have the access rights to connect to the github repository we are using as our repository. That why we need to recreate it later from the ui, because we in that example we want to use a public github project and we don’t save credentials in a public github project.
4. Verify the example app-of-apps in Argo CD
Step 1: Login to Argo CD as admin
Step 2: Verfiy the connected repositories
In Settings/Repositories
that the https://github.com/thomassuedbroecker/gitops-app-of-apps
repository is connected.

Step 3: Verfiy the root
project exists
In Settings/Projects
the project called root-application
should be created.

Step 4: Verfiy the application called root-application
exists
Open Applications
and the you will notice the root-application
it is out of sync and click on the application.

Step 5: Ensure you see the resource defined for the root-applications
in folder of the https://github.com/thomassuedbroecker/gitops-app-of-apps
repository

Step 6: Press sync for the application

Step 7: Then you will notice what needs to be synchronized

Step 8: Go back to Applications and press sync
Here you see we need to sync the vend application.

Step 9: Now click on vend and verify the created application resources

5. Summary
Now we followed one option to configure app-of-apps
in Argo CD. The app of apps pattern enables you to use ArgoCD to deploy ArgoCD application configurations to deploy new applications to a cluster. We used use ArgoCD to configure ArgoCD. The module GitOps repo for the Software Everywhere modules catalog uses the app of apps pattern to provide an effective organization for you application you are going to manage in ArgoCD.
Note: This is a good blog post you can Continuous Delivery with Helm and Argo CD dig in.
I hope this was useful to you and let’s see what’s next?
Greetings,
Thomas
#ibmcloud, #softwareeverywhere, #iascable, #argocd, #openshift, #helm
Leave a Reply