Setup Aggregator Template Variables

July 2, 2026 · View on GitHub

This document describes the template variables consumed by the controller setup aggregator template at pkg/pipeline/templates/setup.go.tmpl. These variables are populated by SetupGenerator.generate and are used to render the aggregated zz_setup.go (or the per-group zz_<group>_setup.go) file. The aggregated setup code invokes the per-resource Setup/SetupGated/SetupWebhookWithManager functions emitted by the controller template, so the two templates are coupled: a custom aggregator MUST call the functions that the (default or custom) controller template exposes.

The setup aggregator template can be overridden via config.Provider (see WithSetupAggregatorTemplate in pkg/config/provider.go). Any custom template MUST honor the contract described below.

Warning

Overriding the setup aggregator template is an advanced feature.

  • Use this capability with great care, and only when the default template genuinely cannot accommodate your provider's requirements. If at all possible, prefer to stay on the default template and contribute upstream changes that benefit all providers.
  • The set of template variables and their semantics are not covered by the same compatibility guarantees as the rest of the public Go API. Upjet may add, remove, rename, or change the meaning of template variables without a deprecation cycle. Such changes will land in a new minor release and be called out in the corresponding release notes.
  • Custom templates that diverge from the default may break on any minor upgrade. Plan for the maintenance cost of keeping a fork of this template in sync.

Template Variables

The following keys are available inside the template via {{ .<Name> }}.

VariableTypeDescription
HeaderstringLicense header rendered from hack/boilerplate.go.txt.
GenStatementstring"Code generated by upjet. DO NOT EDIT." style comment block.
ImportsstringThe resolved import block for the generated file. Contains the imports for every per-resource controller package referenced through Aliases.
PackageNamestringGo package name for the generated setup file, derived from the base name of the API module path. The default template does not use it (it hard-codes package controller), but it is available to custom templates.
Aliases[]stringSorted import aliases for the per-resource controller packages whose setup functions must be aggregated. The default template ranges over these and emits {{ $alias }}Setup, {{ $alias }}SetupGated, and {{ $alias }}SetupWebhookWithManager calls, so each alias MUST refer to a controller package that exposes those functions.
GroupstringSuffix appended to the generated aggregator function names. Empty ("") for the monolithic setup file, or "_<group>" (with a leading underscore, e.g. _ec2) when generating a per-group setup file. This is what makes the monolithic and per-group aggregators (Setup vs. Setup_ec2) coexist without name clashes.

Generated Entry Points

For every rendered setup file the default template exposes three aggregator functions, each of which iterates over Aliases and invokes the matching per-resource function:

  • Setup{{ .Group }}(mgr ctrl.Manager, o controller.Options) error — eagerly registers the reconcilers for all resources in scope.
  • SetupGated{{ .Group }}(mgr ctrl.Manager, o controller.Options) error — registers the reconcilers gated behind their CRDs' GVK observation.
  • SetupWebhookWithManager{{ .Group }}(mgr ctrl.Manager) error — registers the conversion webhooks for all resource kinds in scope.

Generated Output

The rendered file is written under the controllers directory the pipeline is generating into:

<controllers-dir>/zz_setup.go            # monolithic build
<controllers-dir>/zz_<group>_setup.go    # per-group (subpackage) build

The monolithic zz_setup.go is generated when the provider does not configure a per-subpackage main template; otherwise one aggregator file is generated per API group (<group> being the short group name, e.g. ec2). Both variants are produced from the same setup aggregator template, distinguished only by the Group variable.

<controllers-dir> is the controllers directory the pipeline runner (pipeline.Run) selects. When the provider generates both cluster-scoped and namespaced managed resources (Upjet v2 namespaced resources), the pipeline runs once per scope and writes into internal/controller/cluster/... and internal/controller/namespaced/... respectively; a provider that generates only cluster-scoped resources writes directly under internal/controller/.

Overriding the Template

To supply a custom setup aggregator template, pass config.WithSetupAggregatorTemplate through config.Provider. The custom template must accept all variables documented above; otherwise the rendered file will not compile against the upjet runtime contracts. In particular, the generated aggregator functions must keep calling the Setup/SetupGated/ SetupWebhookWithManager functions that the controller template emits for each resource.

When Template Errors Surface

Errors in a custom setup aggregator template are reported at two distinct stages:

  • Provider generation time. Static template errors — such as a template string that fails to parse (text/template.Parse() failures), malformed actions, or references to undefined fields evaluated during execution — are raised by the code generation pipeline and cause provider generation to fail.
  • Provider build / lint time. Syntactically valid templates that produce invalid Go (for example, an empty template that emits no package clause, or output that omits imports required by the upjet runtime contracts) parse cleanly but fail later when the generated zz_setup.go files are compiled or linted as part of the provider build.