Argo CD app of apps pattern for cluster bootstrapping

How to bootstrap a new Kubernetes cluster with one parent Application or a cluster-generator ApplicationSet in Argo CD, and the security and deletion rules to set first.

On this page

When the Argo CD app of apps pattern fits cluster bootstrapping

A new cluster needs its base components, such as ingress, monitoring, policy and Argo CD projects, delivered from Git on the first day. The app of apps pattern answers this with one parent Application that declares the child Applications for those components. The Argo CD cluster bootstrapping guide also offers a cluster-generator ApplicationSet as the recommended alternative, which creates one Application per registered cluster from labels on cluster secrets. The parent Application is the control point: it decides which child Applications exist, which Git paths and revisions they track, and which Argo CD project each child runs in. Changing the parent's manifests changes what every child is allowed to deploy, so a single commit can reach many resources at once.

Because of that reach, app of apps is an admin-only tool. Only administrators should be able to push to the parent repository, and reviewers should check the project field on every child Application, since a child placed in a permissive project can deploy outside the boundaries you intended. Any project that can reach the Argo CD namespace effectively holds admin privileges, so treat that access as an admin grant. Confirm these controls with your own repository permissions and project definitions before the first bootstrap, not after. Licensing is not a factor in this choice: Argo CD is released under the Apache License 2.0 and the project offers no paid edition, so the cost of the pattern lies in the design, review and operating work described in the rest of this page.

Teams that want many clusters to be created from one template, or that register clusters often, usually fit better with the cluster-generator ApplicationSet, because the cluster label drives the output. Teams with a small, fixed set of platform components and a strict review path often find a single parent easier to audit. Ask your Argo CD administrators which of these two shapes your current change control can review, and document the answer before you write the first manifest.

Choosing between one parent Application and a cluster-generator ApplicationSet

When you run a handful of clusters that rarely change, and each one is known by name in advance, a single parent Application that lists its child Applications is easy to read and easy to review. The whole bootstrap sits in one place, and a reviewer can see every child, its project and its source in one diff. The cost is that each new cluster usually means another hand-written parent or child set, so the pattern stays manageable only while the list stays short. Argo CD's cluster bootstrapping guide recommends ApplicationSets with a cluster generator as the first choice, and app of apps is the alternative when a parent that declares children is clearer for your team.

  • Review load: every child Application is visible in one parent file, so reviewers check the project field of each child directly.
  • Drift handling: children are managed by the parent, so ignoring drift on a child is a deliberate, per-Application decision.
  • Cluster secrets: a fixed set still needs each destination registered, and the cluster secret should carry a label such as env or role so you can filter later.
  • Growth cost: each addition edits the parent by hand, which is acceptable at this scale and becomes the main friction later.

Before you choose, confirm with your team how many clusters you expect in the next year and who approves changes to the parent repository.

How a parent Application declares child Applications on a new cluster

The sequence starts before any Application exists. First, the destination cluster is registered with Argo CD so that Argo CD holds credentials it can use to deploy there. Second, the parent Application is created in the Argo CD control plane and points at a Git path that contains only child Application resources. Third, Argo CD syncs the parent, which creates each child Application in the Argo CD namespace. Each child then reconciles its own source path against the destination cluster. Nothing in this chain is automatic from the cluster's point of view, so the reader should be able to name the cluster registration, the parent source path and the first child sync as separate steps when they review a bootstrap. Confirm the registration method your Argo CD version uses for the destination cluster in the cluster bootstrapping guide before you write the parent manifest, because the cluster secret and its labels determine where children can land.

Each child Application carries its own project field, its own source repository and path, and its own destination. The project is the boundary that decides which repositories, destination clusters and namespaces that child may use, so a child that names the wrong project can reach resources the parent author never intended. For that reason, reviews of the parent repository should check every child's project value against the project list, confirm that no child points at a project with broad destination rights, and confirm that the child's path is the one the team meant to deploy. A child that inherits a permissive project from a copy-pasted template is one of the most common ways app of apps setups drift beyond their intended scope. Ask whoever maintains the parent repository to show the review checklist they use for new child files.

Because the parent is the single point that creates children, anyone who can change the parent repository can add, repoint or remove applications across the cluster. This is why the bootstrap model should be treated as admin-only, and why the parent repository needs the same access controls as the Argo CD installation itself. Plan for how a child is removed as well, since deleting a child's Application can delete its managed resources depending on its finalizers, a behavior covered in the deletion section of this page. Before you go live, confirm with your own environment that the parent sync completes, that each child shows the expected project and destination, and that a test change to one child does not affect the others.

Bootstrap options and when each one fits

This table compares the single parent Application, the cluster-generator ApplicationSet, the resources finalizer on child Applications and drift settings on children. Read each row for the situation it suits and the risk it carries, then confirm the exact field names and behavior in the Argo CD version you run.

OptionWhat it doesWhen it fitsMain risk
Single parent Application (app of apps)One parent Application declares the child Applications, which Argo CD then syncs from a repository pathA small, fixed set of clusters or environments that a single admin team manages from one repositoryAnyone who can push to the parent repository can create or change child Applications, so access must stay admin-only
Cluster-generator ApplicationSetGenerates one Application per cluster registered in Argo CD, selected by labels on the cluster secretsMany clusters that share a common baseline, where new clusters should receive the same add-ons without a manual editA label change or a wrongly labeled cluster secret can roll baseline apps onto clusters that should not receive them
Resources finalizer on child ApplicationsAdds resources-finalizer.argocd.argoproj.io so deleting the Application also deletes the resources it managesBootstrapped add-ons that should disappear with their Application, such as a test or preview clusterDeleting a parent or child Application can remove live workloads, so confirm the finalizer on each child before deletion
Ignoring drift on child ApplicationsTells Argo CD to ignore differences on specific managed fields, such as fields that a controller or operator writes at runtimeFields that cluster controllers mutate by design, for example generated defaults or autoscaler-managed countsBroad ignore rules can hide real configuration drift, so keep the list of ignored fields narrow and reviewed
Child project fieldSets which Argo CD project each child Application belongs to, which governs its allowed repositories and destinationsSeparating platform add-ons from team workloads by project boundaryA child that points at a permissive project can reach clusters or namespaces it should not, so review this field in every parent change
Admin access to the Argo CD namespaceGives control over Applications, projects and cluster registrations for the whole instancePlatform teams that own bootstrapping for the instanceAny project that can reach the Argo CD namespace effectively holds admin privileges, so restrict project scope before adding bootstrap automation
Confirming behavior in your versionField names, sync options and finalizer handling can change between minor releasesBefore the first bootstrap run and before each Argo CD upgradeRelying on a remembered default from an older release, so test the parent, a child and a deletion in a non-production cluster first

How to set up a cluster bootstrap in Argo CD

This sequence takes a new Kubernetes cluster from an Argo CD install to a state where a single admin-owned Git source delivers its baseline platform components, with each step checked before the next begins.

  1. Confirm the Argo CD control plane and access model

    Confirm which Argo CD instance will manage the new cluster and that it is installed and reachable by the platform team. Check that the built-in admin user is limited to initial setup and that local users or SSO are configured, with admin.enabled set to false once they are. Confirm the Argo CD version against the project's current release list so you know which patch line you are on. Done when you can log in as a named platform administrator and the Argo CD API responds for that account.

  2. Register the destination cluster with labels on its secret

    Register the new cluster with Argo CD as a cluster secret in the Argo CD namespace, and add labels that describe its role, such as environment, region or platform tier. The labels are what a cluster generator later matches on, so agree the label scheme with the platform team first. Confirm the cluster appears in the Argo CD cluster list with the expected name, server address and labels, and that its connection status is successful. If the labels are missing or wrong, fix the secret before continuing, because generated Applications will not be created for an unlabeled cluster.

  3. Create the admin-owned parent repository and project

    Create a Git repository that only platform administrators can push to, and define an Argo CD AppProject that limits which source repositories, destination clusters and namespaces the bootstrap resources may use. Keep the project's cluster-scoped and namespace permissions narrow, because any project that can reach the Argo CD namespace effectively holds admin rights. Confirm in your Git host that write access is restricted to the admin group and in Argo CD that the project lists only the approved repositories and destinations.

  4. Add the child Applications or the cluster-generator ApplicationSet

    Choose the pattern that fits the number of clusters. For a single cluster or a small fixed set of children, add one parent Application that declares each child Application in the parent repository. For a fleet of clusters that share the same baseline, add an ApplicationSet with a cluster generator that selects clusters by the labels set in step two. Set each child's project field explicitly to the admin-owned project. Verify that the parent Application or ApplicationSet has been created and that it lists the expected children, with no unexpected targets.

  5. Verify sync and health of the bootstrap resources

    Trigger or wait for the first sync of the parent Application or ApplicationSet, then review each child Application's sync status and health. Confirm that every child reaches Synced and Healthy, or that any remaining differences are understood and recorded. Check that the destination namespaces and projects match the design, and that no child points at a project or cluster outside the approved list. Keep a copy of the sync results as change evidence for the bootstrap.

  6. Set finalizer and drift behavior for child Applications

    Decide which children should delete their managed resources when the Application is removed, and add the resources-finalizer.argocd.argoproj.io finalizer only to those. Decide which fields, such as those that controllers or operators mutate at runtime, should be ignored in drift comparison, and document each ignore rule with its owner. Test the behavior on a non-production cluster first: confirm that deleting a child with the finalizer removes its resources, and that a child with ignored fields no longer shows OutOfSync because of those fields alone.

  7. Record the bootstrap and test the removal path

    Record the final state: the cluster secret and labels, the parent repository and its access list, the project definition, the child list and the finalizer and ignore decisions. Confirm the bootstrap can be reproduced from Git by a second administrator, and that a deliberate removal of one test child behaves as the recorded design says. Ask your partner or internal team to confirm the runbook covers what happens when a cluster is unregistered, since removing a cluster secret can affect every generated child.

Security rules for the parent repository and projects

An app of apps parent Application decides what every child Application deploys, so the people who control its repository and the projects they can target effectively control the cluster. The cards below cover the access rules, privilege boundaries and login settings to confirm before the first bootstrap sync.

Restrict pushes to the parent repository

The parent repository declares every child Application, so a commit to it can point a child at any repository, path or destination. Treat it as an admin-only tool: limit write access to the platform admins, require reviews on every change, and check each child's project field during review. A child that names a permissive project can reach namespaces and clusters its team never needed. Confirm who can merge to the parent branch in your Git host, not only who can push.

Treat project access as admin access

Any Argo CD project that can reach the Argo CD namespace effectively has admin privileges, because Applications can deploy resources that change Argo CD's own configuration and secrets. Review each project's destination namespaces and cluster list for the argocd namespace, and keep team projects away from it. When you assign roles, ask who can create Applications in each project, since that permission is the same as deploying into its destinations.

Limit what repo-server can render

The repo-server runs Helm and Kustomize against repository content, so an untrusted repository or a file reference that reaches outside the repository can expose data or run unwanted rendering. Allow only repositories your platform team has approved, and check that Helm and Kustomize inputs do not pull files from outside the app path. Ask your reviewers which repositories the parent Application can reach, because every child inherits that exposure.

Disable the built-in admin user

The built-in admin account exists for first-time setup. Once local users or SSO are configured and tested, set admin.enabled to false in the argocd-cm ConfigMap so that a shared password cannot bypass your identity provider. Before you switch it off, confirm that at least one named administrator can log in through SSO and that the group-to-role mapping grants the required permissions. Keep a documented break-glass path that your team has tested.

Cascading deletion finalizers and ignoring drift on child apps

The resources-finalizer.argocd.argoproj.io finalizer decides what happens to a cluster when a child Application is deleted. Added to a child Application's metadata.finalizers list, it tells Argo CD to delete every resource that Application manages before it removes the Application object itself. Without it, deleting the Application only removes the Argo CD record and leaves the Deployments, Services, Secrets and CRDs running in the cluster. The effect is easy to underestimate in a bootstrap design: if the child Application generates a cluster-scoped resource, such as a CustomResourceDefinition, a ClusterRole or a namespace, the cascade can reach well beyond the workload the team had in mind. Because a parent Application can delete its children when they are pruned from Git, a single removed file in the parent repository can start that chain.

Before you tear down a parent Application, review each child's finalizer and prune settings, and list the cluster-scoped resources each child owns. Confirm in the Argo CD cluster bootstrapping guide how finalizers propagate when the parent is deleted, and test the teardown on a non-production cluster first. Treat the finalizer as a deliberate choice for each child, not a default copied from a template.

Ignoring drift on a child Application tells Argo CD to stop reporting and correcting differences for specified fields, such as replica counts set by a Horizontal Pod Autoscaler or annotations written by a controller. That is useful when another system legitimately owns a field. The risk is that the same setting hides real changes: an operator who edits a field by hand, or a compromised account that alters a security context, may show as Synced. Limit ignored differences to named fields on named resources, document the owner of each field, and make the ignore rule reviewable in the parent repository so it goes through the same change approval as the rest of the bootstrap configuration. Confirm with your team which drift must still be visible to your on-call and audit processes.

Limits to confirm in your environment

A bootstrap design only holds if the platform underneath it matches what the pattern assumes. These four checks cover the Argo CD version line, the cluster labels that drive generation, the RBAC behavior that automation accounts depend on, and whether the control plane can reach each cluster it manages.

Argo CD minor version in use

Confirm which minor line your control plane runs. The project ships a minor release four times a year, and only the three most recent minor versions receive patch releases, so an older line may stop receiving fixes before you plan to upgrade. Check the release page for the current patch numbers and whether your minor is still on the patch list. Record the version in your bootstrap runbook so every child Application and generator behaves the same way across upgrades.

Cluster label matching in generators

Confirm that the labels on your cluster secrets match the selectors your cluster generator uses. A missing or misspelled label means a new cluster is silently skipped and never receives its bootstrap Applications. Test with a non-production cluster first, then check that the generated Application names and destinations match what you expect. Agree on a labeling standard across platform teams so that adding a cluster is one reviewed change, not a set of manual edits.

RBAC changes for automation accounts

Confirm how the upgrade from 2.14 to 3.0 changed RBAC for the service accounts and tokens your pipelines use. Update and delete permissions now apply only to the Application itself, and reading logs requires an explicit logs, get permission. A bootstrap account that worked before may fail to delete or inspect child Applications until its policy is updated. Test each automation role against the cascading delete path before relying on it in production.

Network reach from the control plane

Confirm that the Argo CD control plane can reach the API server of every cluster it bootstraps, and that the path stays open across firewalls, proxies and segmented networks. Bootstrapping fails quietly when a cluster is unreachable, leaving Applications stuck in an unknown or progressing state. Ask your network team to document the allowed routes, the certificate trust chain for each API endpoint, and the behavior when a cluster is in a maintenance window.

Questions teams ask before bootstrapping clusters with Argo CD

What does a cluster bootstrap implementation cost, and what drives the effort?

The cost is set by the written scope, not by a list price. Effort rises with the number of clusters, the number of base components each cluster needs (ingress, certificate management, monitoring, policy engines, secrets operators), the RBAC design across teams, and the state of any existing GitOps repositories. Clusters that share one template cost less to bootstrap than clusters that differ by region, provider or compliance zone. One-time work covers repository layout, the parent or generator configuration, SSO and RBAC wiring, and verification. Recurring costs are operations, upgrades of Argo CD itself and of the components it deploys, and any retainer. Ask any provider for a quote that lists each cluster, each base component, and each identity and RBAC item separately, and that states what is excluded.

How long does a bootstrap take, and what sets the schedule?

Duration depends on how many clusters must be ready, how many base components each one installs, and how quickly the client can make decisions and grant access. The critical path is usually not the Argo CD install itself but the dependencies around it: identity provider configuration, repository ownership and branch protection decisions, network paths from Argo CD to each cluster, and approval for cluster-scoped privileges. Change freezes and the client's own review cycles also add time. Ask for a timeline that shows these dependencies as separate tasks with named owners, so the schedule reflects the client's readiness as well as the implementation work.

What must our team provide before a bootstrap starts?

Most delays come from missing inputs. Plan to provide:

  • Administrative access to each target cluster, or a documented path for the implementation team to get it, plus network routes from the Argo CD control plane to each API server.
  • Ownership of the Git repositories that will hold the parent or generator definitions, with named approvers and branch protection rules.
  • The identity provider, its administrators, and the group names that will map to Argo CD roles.
  • Decisions on the base components, versions and environments each cluster needs.
  • A named technical owner who can approve scope changes during the engagement.

Confirm these inputs with your own security and platform teams before the scope is signed, because each one changes the design.

Can our internal platform team bootstrap clusters with Argo CD on its own?

A team with Kubernetes administration experience and Git workflow discipline can build a bootstrap without outside help, and many do. The harder parts are the security decisions: who can push to the parent repository, how projects bound what each child Application may deploy, how SSO groups map to roles, and how deletion behaves. These decisions need review by people who understand both Argo CD and your audit obligations. Ask yourself whether the team has time to build, test and document these controls in addition to its normal workload, and whether it can run the first upgrade of Argo CD and its components without an outage.

When should we choose ApplicationSets over the app of apps pattern?

App of apps fits a small, stable set of clusters where one parent Application declares every child explicitly and an admin reviews each change. A cluster generator inside an ApplicationSet fits fleets where each cluster is registered with labels and should receive the same base components automatically, because adding a labeled cluster produces its Applications without editing a parent file. The Argo CD cluster bootstrapping guide recommends ApplicationSets with a cluster generator and labels on cluster secrets as the preferred route, with app of apps as the alternative. Choose based on how often clusters are added, how much per-cluster variation exists, and how many people review changes to the parent definitions.

How do we prevent accidental deletion of cluster resources?

Deletion risk comes from two places. First, a child Application with the resources-finalizer.argocd.argoproj.io finalizer deletes its managed resources when the Application is removed, so deleting a parent or an ApplicationSet can cascade into workloads. Second, anyone who can push to the parent repository or create Applications in the Argo CD namespace can remove or redirect large parts of a fleet. Controls include adding the finalizer only to Applications that should be removed with their resources, restricting the parent repository to admins, scoping each child to a project with explicit destinations, reviewing deletions as a separate change, and testing deletion on a non-production cluster. Ask any provider to demonstrate the deletion path before go-live.

How DeployOpen scopes and supports Argo CD cluster bootstrapping

DeployOpen plans and implements the app of apps pattern or a cluster-generator ApplicationSet inside your own infrastructure, so the parent repository, cluster labels, projects and deletion behavior are agreed before the first cluster is bootstrapped. Engagements are fixed-scope, with the scope, deliverables and timeline agreed in writing before work starts.

How we scope

  • Written scope names the clusters to bootstrap, the parent repository and who may push to it
  • We record which pattern fits each cluster group and why, with the reasons documented
  • The scope lists the Argo CD projects, identity groups and destination namespaces each child Application may use
  • Quotes follow from the written scope, and we ask you to confirm cluster access and change approval paths

How we build

  • We build the parent Application or ApplicationSet and the child manifests in a Git repository you control
  • Cluster secrets receive the labels the generator reads, and we test that each new cluster matches only its intended group
  • We set the resources-finalizer on child Applications only where cascading deletion is intended, and test a deletion in staging
  • Child Applications ignore drift only on fields agreed in the scope, with each ignored field recorded and reviewed

How we hand over

  • Handover includes the repository layout, the admin-only push rule for the parent repository and the review checklist for child project fields
  • We document the bootstrap sequence for a new cluster, including the steps a platform engineer repeats for each addition
  • Runbooks cover what to do when a child Application is deleted, when drift is ignored and when a project boundary blocks a sync
  • Your team receives written deliverables and a walkthrough of each test run against staging clusters

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers, and the support scope is agreed in writing
  • Support can cover Argo CD minor upgrades, with patch releases tracked against the release cadence you choose to follow
  • We can review new cluster additions against the documented sequence and the admin-only parent repository rule
  • Confirm with us how support requests, change windows and escalation paths will work before the engagement starts

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.