Argo CD / Generated systems and controlled recovery / Lesson 13
ApplicationSet generation and child ownership
Review generator inputs, template authority, and child lifecycle before expanding applications.
On this page
Lesson goals
- Distinguish an ApplicationSet from the Applications and resources it generates.
- Identify source-of-truth and deletion boundaries across both reconciliation layers.
Generation adds another control loop
An ApplicationSet controller generates Application objects from configured generators and templates. Each generated Application then participates in Argo CDโs application reconciliation. Parcel can use a controlled list of lab targets rather than duplicate many definitions by hand. This adds an ownership layer: editing a child Application may be overwritten or ignored according to the generatorโs effective policy. Record which controller owns each field and where the durable desired change belongs. A generated child is not an independent handwritten configuration merely because it appears separately in the interface.
Generator writers can influence destination authority
List, cluster, Git, and other supported generators obtain parameters from different trust sources. A parameter controlling project, repository, destination, or namespace can redirect authority beyond a cosmetic name. Protect the generator source and template together with AppProject and target permissions. Do not let untrusted pull-request metadata freely select a high-authority project or cluster. Review generator output size and collisions before expansion. A typo or unexpectedly broad selection can affect many Applications even when the template itself remains unchanged.
Read a non-runnable template fragment
The fragment below enables Go templating with missing-key errors and shows a synthetic list element and a child name. It intentionally omits the Application spec, so it cannot create a usable child. Release-3.1 Go templating has documented field and type limitations; it is not arbitrary whole-object templating. Missing-key handling improves feedback but is not authorization or a complete domain validator. Validate allowed target identifiers and generated names separately before relying on a template for rollout control.
spec:
goTemplate: true
goTemplateOptions: ["missingkey=error"]
generators:
- list:
elements:
- target: lab-east
namespace: parcel-east
template:
metadata:
name: "parcel-{{.target}}"
The enclosing resource and child spec are absent and nothing is applied. lab-east is a teaching label, not a configured cluster, and the example does not test the Go template engine.
Detect duplicate generated identities locally
The complete local model derives child names from declared targets and rejects duplicate names. It is not an ApplicationSet generator, Go template parser, Kubernetes name validator, or controller test. It demonstrates one review invariant: two parameter records should not accidentally claim the same child identity. A real generator also needs full name and namespace rules, target scope, source trust, and stable ownership. Keep validation outcomes separate from the authority to create or remove Applications.
targets = ["lab-east", "lab-west", "lab-east"]
names = ["parcel-" + target for target in targets]
print(names)
print(len(names) == len(set(names)))
['parcel-lab-east', 'parcel-lab-west', 'parcel-lab-east']
False
The program computes strings only. It does not discover clusters, read Git, run Go templates, or create an ApplicationSet or Application.
Application deletion and resource pruning differ
A generator no longer selecting a target can affect the lifecycle of its child Application according to ApplicationSet policy, owner references, and supported settings. Deleting an Application can separately affect managed resources through finalizer and cascade behavior. Automated prune inside an Application is another decision. Review all layers before retirement or temporarily pausing automation. A child-only edit may not be durable; use the documented parent policy and supported override mechanism. Retain a plan for source errors, empty generator output, partial expansion, and unexpected removal before authorizing broad generation.
Common errors and fixes
A child automation field is edited as if the parent cannot reconcile it.
- Why it happens
- Generated ownership was omitted from the change model.
- How to fix it
- Review the ApplicationSet template and supported modification policy.
- Prevent it next time
- Record the authoritative owner for each child field.
An untrusted generator parameter selects an unrestricted project.
- Why it happens
- Template data is allowed to redirect deployment authority.
- How to fix it
- Constrain and review high-authority fields and generator sources.
- Prevent it next time
- Treat template and parameter writers as part of the trust boundary.
Removing a target is treated as harmless list cleanup.
- Why it happens
- Child deletion and workload lifecycle effects were ignored.
- How to fix it
- Review ApplicationSet modification policy and Application cascade behavior.
- Prevent it next time
- Rehearse retirement and empty-output cases before expansion.
Check your understanding
1. Two target records generate the same child name. What does the local model establish?
Show worked solution
It detects duplicate strings in the declared set and rejects uniqueness. It does not prove which controller behavior would occur or validate all Kubernetes naming rules. Fix the source contract and inspect the intended full child identities before any authorized generation.
2. Why can disabling automation directly on one generated Application be ineffective?
Show worked solution
The parent template and modification policy can remain authoritative and reconcile the child. Review the documented ApplicationSet control path and supported exceptions. A visible child edit is not necessarily a durable desired-state change.
Key takeaways
- ApplicationSet adds ownership and authority layers.
- Review generation, child deletion, and workload pruning separately.