--- tags: schema --- # Object References ## Problem Statement `ytt` templates that cover YAML dialects with inter-document references (like the KRM) rely on the author to understand and account for those references, manually. Today, the Configuration Author that wants to apply a modification for object names extracts such a value as a Data Value and uses that reference in both the document containing the entity and _all_ of the paths in documents that refer to it. That strategy becomes unduly burdensome in the case where the author wishes to apply a sweeping change like prefixing all object names with a string. For example, the Kubernetes Resource Model (KRM) contains a web of object references. - `Deployment`s load configuration from `ConfigMap`s and `Secret`s; - `RoleBinding`s mate-up to `Role`s with `ServiceAccount`s; - CRDs can extend the KRM with their own custom relationships. - ... Any intent to modify the name (or namespace) of the referent must also explicitly update all references. Same is true for other identifiers (e.g. labels). ## Ideas ### Idea: Explicit Object Reference In lieu of an explicit value for a given node, the author can make an object reference. ```yaml= #! role.yaml --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: some-role ``` ```yaml= #@ load("@ytt:ref", "ref") --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: a-role-binding roleRef: #@ ref.to(by=overlay.subset({"kind": "Role", "metadata": {"name": "some-role"}}), paths={"apiGroup": "apiVersion", "kind": "kind", "name": "metadata.name"}) ``` ... and when the referent is modified ... ```yaml= #! name_prefix_patch.yaml #@ load("@ytt:overlay", "overlay") #@overlay/match by=overlay.all, expects="1+" --- metadata: #@overlay/replace via=lambda left, right: right+left name: PREFIX- ``` ... the reference is updated ... ```yaml= apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: PREFIX-a-role-binding roleRef: apiGroup: rbac.authorization.k8s.io/v1 kind: Role name: PREFIX-some-role ``` ### Idea: Reference Type in Schema The author can declare a node of type "reference" ```yaml= #@ load("@ytt:ref", "ref") # #@schema/definition name="rbac.authorization.k8s.io/v1/RoleBinding" --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: "" #@schema/type "reference" roleRef: ... ``` ...