Chapter 4. Template processing in policies


Configuration policies and operator policies support the inclusion of Golang text templates. These templates are resolved at runtime either on the hub cluster or the target managed cluster using configurations related to that cluster. This gives you the ability to define policies with dynamic content, and inform or enforce Kubernetes resources that are customized to the target cluster.

A policy definition can contain both hub cluster and managed cluster templates. Hub cluster templates are processed first on the hub cluster, then the policy definition with resolved hub cluster templates is propagated to the target clusters. A controller on the managed cluster processes any managed cluster templates in the policy definition and then enforces or verifies the fully resolved object definition.

The template must conform to the Golang template language specification, and the resource definition generated from the resolved template must be a valid YAML. See the Golang documentation about Package templates for more information. Any errors in template validation are recognized as policy violations. When you use a custom template function, the values are replaced at runtime.

Important:

  • If you use hub cluster templates to propagate secrets or other sensitive data, the sensitive data exists in the managed cluster namespace on the hub cluster and on the managed clusters where that policy is distributed. The template content is expanded in the policy, and policies are not encrypted by the OpenShift Container Platform ETCD encryption support. To address this, use fromSecret or copySecretData, which automatically encrypts the values from the secret, or protect to encrypt other values.
  • When you add multiline string values such as, certificates, always add | toRawJson | toLiteral syntax at the end of the template pipeline to handle line breaks. For example, if you are copying a certificate from a Secret resource and including it in a ConfigMap resource, your template pipeline might be similar to the following syntax:

    ca.crt: '{{ fromSecret "openshift-config" "ca-config-map-secret" "ca.crt"  | base64dec | toRawJson | toLiteral }}'

    The toRawJson template function converts the input value to a JSON string with new lines escaped to not affect the YAML structure. The toLiteral template function removes the outer single quotes from the output. For example, when templates are processed for the key: '{{ 'hello\nworld' | toRawJson }}' template pipeline, the output is key: '"hello\nworld"'. The output of the key: '{{ 'hello\nworld' | toRawJson | toLiteral }}' template pipeline is key: "hello\nworld".

See the following table for a comparison of hub cluster and managed cluster templates:

  • Comparison of hub cluster and managed cluster templates

    Table 4.1. Comparison table
    TemplatesHub clusterManaged cluster

    Syntax

    Golang text template specification

    Golang text template specification

    Delimiter

    {{hub … hub}}

    {{ … }}

    Context

    Context variables .ManagedClusterName, .ManagedClusterLabels, and .PolicyMetadata are available. .ManagedClusterName resolves to the name of the target cluster where the policy is propagated. .ManagedClusterLabels resolves to a map of keys and values of the labels on the managed cluster where the policy is propagated. .PolicyMetadata resolves to a map with the name, namespace, labels, and annotations keys with values from the root policy.

    For ConfigurationPolicy resources, context variables .ObjectName, .ObjectNamespace, and .Object are available inside objectDefinition. If the object is not cluster-scoped, ObjectNamespace resolves to the name of the selected namespace from the spec.namespaceSelector or metadata.namespace that you specified. The .ObjectName resolves to the name of the object from the objectSelector or metadata.name that you specified. The .Object is the full target object that is currently on the cluster.

    Access control

    By default, you can only reference namespaced Kubernetes resources that are in the same namespace as the Policy object and the ManagedCluster object of the cluster that the policy propagates to.

    Alternatively, you can specify the spec.hubTemplateOptions.serviceAccountName field in the Policy object to a service account in the same namespace as the Policy resource. When you specify the field, the service account is used for all hub cluster template lookups.

    Note: The service account must have list and watch permissions on any resource that is looked up in a hub cluster template.

    You can reference any resource on the cluster.

    Functions

    A set of template functions that support dynamic access to Kubernetes resources and string manipulation. See Template functions for more information. See the Access control row for lookup restrictions.

    The fromSecret template function on the hub cluster stores the resulting value as an encrypted string on the replicated policy, in the managed cluster namespace.

    The equivalent call might use the following syntax: {{hub "(lookup "v1" "Secret" "default" "my-hub-secret").data.message | protect hub}}

    A set of template functions support dynamic access to Kubernetes resources and string manipulation. See Template functions for more information.

    Function output storage

    The output of template functions are stored in Policy resource objects in each applicable managed cluster namespace on the hub cluster, before it is synced to the managed cluster. This means that any sensitive results from template functions are readable by anyone with read access to the Policy resource objects on the hub cluster, and anyone with read access to the ConfigurationPolicy or OperatorPolicy resource objects on the managed clusters. Additionally, if etcd encryption is enabled, the policy resource objects are not encrypted. It is best to carefully consider this when using template functions that return sensitive output (e.g. from a secret).

    The output of template functions are not stored in policy related resource objects.

    Processing

    Processing occurs at runtime on the hub cluster during propagation of replicated policies to clusters. Policies and the hub cluster templates within the policies are processed on the hub cluster only when templates are created or updated.

    Processing occurs on the managed cluster. Configuration policies are processed periodically, which automatically updates the resolved object definition with data in the referenced resources. Operator policies automatically update whenever a referenced resource changes.

    Processing errors

    Errors from the hub cluster templates are displayed as violations on the managed clusters the policy applies to.

    Errors from the managed cluster templates are displayed as violations on the specific target cluster where the violation occurred.

4.1. Template functions

Reference Kubernetes resources such as resource-specific and generic template functions on your hub cluster by using the {{hub …​ hub}} delimiters, or on your managed cluster by using the {{ …​ }} delimiters. You can use resource-specific functions for convenience and to make the content of your resources more accessible.

If you use the generic function, lookup, which is more advanced, familiarize yourself with the YAML structure of the resource that is being looked up. In addition to these functions, utility functions such as base64enc, base64dec, indent, autoindent, toInt, toBool, and more are available.

Policy templates are expressed as strings in the YAML manifest, using quotes or a block scalar (| or >). After processing, the resolved value is also a string. The toInt and toBool functions convert template output to integer or boolean types when the enforced resource expects those data types.

4.2. fromSecret

The fromSecret function returns the value of the given data key in the secret.

View the following syntax for the function:

func fromSecret (ns string, secretName string, datakey string) (dataValue string, err error)

When you use this function, enter the namespace, name, and data key of a Kubernetes Secret resource. You must use the same namespace that is used for the policy when using the function in a hub cluster template. See Template processing for more details.

View the following configuration policy that enforces a Secret resource on the target cluster:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
  name: demo-fromsecret
spec:
  object-templates:
  - objectDefinition:
      apiVersion: v1
      kind: Secret
      metadata:
        name: demosecret
        namespace: test
      type: Opaque
      data:
        USER_NAME: YWRtaW4=
        PASSWORD: '{{ fromSecret "default" "localsecret" "PASSWORD" }}'

+ * You receive a policy violation if the Kubernetes Secret resource does not exist on the target cluster. If the data key does not exist on the target cluster, the value becomes an empty string. * When you use the fromSecret function with hub cluster templates, the output is automatically encrypted using the protect function to protect the value in flight to the managed cluster. * The value for the PASSWORD data key is a template that references the secret on the target cluster.

Important: When you add multiline string values such as, certificates, always add | toRawJson | toLiteral syntax at the end of the template pipeline to handle line breaks. For example, if you are copying a certificate from a Secret resource and including it in a ConfigMap resource, your template pipeline might be similar to the following syntax:

ca.crt: '{{ fromSecret "openshift-config" "ca-config-map-secret" "ca.crt"  | base64dec | toRawJson | toLiteral }}'
  • The toRawJson template function converts the input value to a JSON string with new lines escaped to not affect the YAML structure.
  • The toLiteral template function removes the outer single quotes from the output. For example, when templates are processed for the key: '{{ 'hello\nworld' | toRawJson }}' template pipeline, the output is key: '"hello\nworld"'. The output of the key: '{{ 'hello\nworld' | toRawJson | toLiteral }}' template pipeline is key: "hello\nworld".

Additional resources

4.3. fromConfigMap

The fromConfigMap function returns the value of the given data key in the config map. When you use this function, enter the namespace, name, and data key of a Kubernetes ConfigMap resource. You must use the same namespace that is used for the policy using the function in a hub cluster template. See Template processing for more details.

View the following syntax for the function:

func fromConfigMap (ns string, configmapName string, datakey string) (dataValue string, err Error)

View the following configuration policy that enforces a Kubernetes resource on the target managed cluster:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
  name: demo-fromcm-lookup
spec:
  object-templates:
  - objectDefinition:
      ...
      data:
        app-name: sampleApp
        app-description: "this is a sample app"
        log-file: '{{ fromConfigMap "default" "logs-config" "log-file" }}'
        log-level: '{{ fromConfigMap "default" "logs-config" "log-level" }}'

+ * If the data key does not exist on the target cluster, the value becomes an empty string. * The log-file template value retrieves the value of the log-file data key from the logs-config ConfigMap in the default namespace. * The log-level template value retrieves the value of the log-level data key from the logs-config ConfigMap in the default namespace.

Additional resources

4.4. fromClusterClaim

The fromClusterClaim function returns the value of the Spec.Value in the ClusterClaim resource.

View the following syntax for the function:

func fromClusterClaim (clusterclaimName string) (dataValue string, err Error)

View the following example of the configuration policy that enforces a Kubernetes resource on the target managed cluster:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
  name: demo-clusterclaims
spec:
  object-templates:
  - objectDefinition:
      ...
      data:
        platform: '{{ fromClusterClaim "platform.open-cluster-management.io" }}'
        product: '{{ fromClusterClaim "product.open-cluster-management.io" }}'
        version: '{{ fromClusterClaim "version.openshift.io" }}'

+ * When you use this function, enter the name of a Kubernetes ClusterClaim resource. You receive a policy violation if the ClusterClaim resource does not exist. * Configuration values can be set as key-value properties. * The value for the platform data key is a template that retrieves the value of the platform.open-cluster-management.io cluster claim. Similarly, it retrieves values for product and version from the ClusterClaim resource.

4.5. lookupClusterClaim

The lookupClusterClaim function is similar to the fromClusterClaim function. The only difference is that when the lookupClusterClaim function cannot find the ClusterClaim resource, lookupClusterClaim gives you an empty string. You can use your preferred templating function to detect when the response is an empty string, and then adjust the output. For example, when the ClusterClaim does not exist, you can define a default value or skip the object.

View the following example of the configuration policy that enforces a Kubernetes resource on the target managed cluster:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
  name: demo-clusterclaims
spec:
  object-templates:
  - objectDefinition:
      ...
      kind: ConfigMap
      data:
        something: '{{ default "empty" (lookupClusterClaim "possibly.nonexistent") }}'

+ * When the possibly.nonexistent ClusterClaim is found, its value gets used in the ConfigMap. If the ClusterClaim does not exist, empty gets used instead through the default function that is provided by Sprig.

4.6. lookup

The lookup function returns the Kubernetes resource as a JSON compatible map. When you use this function, enter the API version, kind, namespace, name, and optional label selectors of the Kubernetes resource. You must use the same namespace that is used for the policy within the hub cluster template. See Template processing for more details.

If the requested resource does not exist, an empty map is returned. If the resource does not exist and the value is provided to another template function, you might get the following error: invalid value; expected string.

Note: Use the default template function, so the correct type is provided to later template functions. See Sprig open source for supported functions.

View the following syntax for the function:

func lookup (apiversion string, kind string, namespace string, name string, labelselector ...string) (value string, err Error)

For label selector examples, see Kubernetes labels and selectors. View the following example of the configuration policy that enforces a Kubernetes resource on the target managed cluster:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
  name: demo-lookup
spec:
  object-templates:
  - objectDefinition:
      ...
      data:
        app-name: sampleApp
        app-description: "this is a sample app"
        metrics-url: >-
          http://{{ (lookup "v1" "Service" "default" "metrics").spec.clusterIP }}:8080

+ * Configuration values can be set as key-value properties. * The value for the metrics-url data key is a template that retrieves the v1/Service Kubernetes resource metrics from the default namespace, and is set to the value of the spec.clusterIP in the queried resource.

4.7. base64enc

The base64enc function returns a base64 encoded value of the input data string. When you use this function, enter a string value.

View the following syntax for the function:

func base64enc (data string) (enc-data string)

View the following example of the configuration policy that uses the base64enc function:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
  name: demo-fromsecret
spec:
  object-templates:
  - objectDefinition:
      ...
      data:
        USER_NAME: >-
          {{ fromConfigMap "default" "myconfigmap" "admin-user" | base64enc }}

4.8. base64dec

The base64dec function returns a base64 decoded value of the input enc-data string. When you use this function, enter a string value.

View the following syntax for the function:

func base64dec (enc-data string) (data string)

View the following example of the configuration policy that uses the base64dec function:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
  name: demo-fromsecret
spec:
  object-templates:
  - objectDefinition:
      ...
      data:
        app-name: >-
          {{ ( lookup "v1"  "Secret" "testns" "mytestsecret") .data.appname ) | base64dec }}

4.9. indent

The indent function returns the padded data string. When you use this function, enter a data string with the specific number of spaces.

View the following syntax for the function:

func indent (spaces  int,  data string) (padded-data string)

View the following example of the configuration policy that uses the indent function:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
spec:
  object-templates:
  - objectDefinition:
      ...
      data:
        Ca-cert: >-
          {{ ( index ( lookup "v1" "Secret" "default" "mycert-tls"  ).data  "ca.pem"  ) |  base64dec | indent 4  }}

4.10. autoindent

The autoindent function acts like the indent function that automatically determines the number of leading spaces based on the number of spaces before the template.

View the following example of the configuration policy that uses the autoindent function:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
  name: demo-fromsecret
spec:
  object-templates:
  - objectDefinition:
      ...
      data:
        Ca-cert: >-
          {{ ( index ( lookup "v1" "Secret" "default" "mycert-tls"  ).data  "ca.pem"  ) |  base64dec | autoindent }}

Additional resources

4.11. toInt

The toInt function casts and returns the integer value of the input value. When this is the last function in the template, there is further processing of the source content. This is to ensure that the value is interpreted as an integer by the YAML. When you use this function, enter the data that needs to be cast as an integer.

View the following syntax for the function:

func toInt (input interface{}) (output int)

View the following example of the configuration policy that uses the toInt function:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
  name: demo-template-function
spec:
  object-templates:
  - objectDefinition:
      ...
      spec:
        vlanid: >-
          {{ (fromConfigMap "site-config" "site1" "vlan")  | toInt }}

4.12. toBool

The toBool function converts the input string into a boolean, and returns the boolean. When this is the last function in the template, there is further processing of the source content. This is to ensure that the value is interpreted as a boolean by the YAML. When you use this function, enter the string data that needs to be converted to a boolean.

View the following syntax for the function:

func toBool (input string) (output bool)

View the following example of the configuration policy that uses the toBool function:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
  name: demo-template-function
spec:
  object-templates:
  - objectDefinition:
      ...
      spec:
        enabled: >-
          {{ (fromConfigMap "site-config" "site1" "enabled")  | toBool }}

4.13. fromYaml

The fromYaml, or fromYAML, function parses a YAML string into a Golang object. You can use this function with a ConfigMap resource that has a YAML string value.

View the following example of the configuration policy that uses the fromYaml function:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
  name: demo-template-function
spec:
  object-templates:
  - objectDefinition:
      ...
      spec:
        replicas: >-
          {{ (fromConfigMap "default" "app-config" "config.yaml") | fromYaml | index "replicas" }}

4.14. toYaml

The toYaml, or toYAML, function parses a Golang object into a YAML string. For a multiline result to be properly indented, you must pass the output to either the autoindent or indent function.

View the following example of the configuration policy that uses the toYaml function:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
  name: demo-template-function
spec:
  object-templates:
  - objectDefinition:
      ...
      data:
        config.yaml: |
          {{ dict "key1" "value1" "key2" "value2" | toYaml | autoindent }}

Additional resources

4.15. protect

The protect function enables you to encrypt a string in a hub cluster policy template. It is automatically decrypted on the managed cluster when the policy is evaluated. Use this function to encrypt sensitive hub cluster template values in transit to managed clusters.

View the following example of the configuration policy that uses the protect function:

apiVersion: policy.open-cluster-management.io/v1
kind: ConfigurationPolicy
metadata:
  name: demo-template-function
spec:
  object-templates:
  - objectDefinition:
    ...
    spec:
      enabled: >-
        {{hub (lookup "v1" "Secret" "default" "my-hub-secret").data.message | protect hub}}

+ * In this example, a lookup hub cluster template encrypts the secret value. On the replicated policy, the value resembles $ocm_encrypted:okrrBqt72oI+3WT/0vxeI3vGa+wpLD7Z0ZxFMLvL204=. * Encryption uses AES-CBC with 256-bit keys. * Each managed cluster has a unique key, rotated every 30 days. * The decrypted value is never stored in the policy on the managed cluster. * To force immediate key rotation, delete the policy.open-cluster-management.io/last-rotated annotation on the policy-encryption-key Secret in the managed cluster namespace on the hub cluster. Policies are then reprocessed to use the new encryption key.

4.16. toLiteral

The toLiteral function removes any quotation marks around the template string after it is processed. You can use this function to convert a JSON string from a config map field to a JSON value in the manifest.

Run the following function to remove quotation marks from the key parameter value:

key: '{{ "[\"10.10.10.10\", \"1.1.1.1\"]" | toLiteral }}'

After using the toLiteral function, the following update is displayed:

key: ["10.10.10.10", "1.1.1.1"]

4.17. copySecretData

The copySecretData function copies all of the data contents of the specified secret.

View the following sample of the function:

...
objectDefinition:
  apiVersion: v1
  kind: Secret
  metadata:
    name: my-secret-copy
  data: '{{ copySecretData "default" "my-secret" }}'

+ * When you use this function with hub cluster templates, the output is automatically encrypted using the protect function.

Additional resources

4.18. copyConfigMapData

The copyConfigMapData function copies all of the data content of the specified config map.

View the following sample of the function:

...
objectDefinition:
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: my-secret-copy
  data: '{{ copyConfigMapData "default" "my-configmap" }}'

4.19. getNodesWithExactRoles

The getNodesWithExactRoles function returns a list of nodes with only the roles that you specify, and ignores nodes that have any additional roles except the node-role.kubernetes.io/worker role.

View the following sample function where you are selecting "infra" nodes and ignoring the storage nodes:

...
objectDefinition:
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: my-configmap
    data:
      infraNode: |
        {{- range $i,$nd := (getNodesWithExactRoles "infra").items }}
        node{{ $i }}: {{ $nd.metadata.name }}
        {{- end }}
      replicas: {{ len ((getNodesWithExactRoles "infra").items) | toInt }}

Additional resources

4.20. hasNodesWithExactRoles

The hasNodesWithExactRoles function returns the true value if the cluster contains nodes with only the roles that you specify, and ignores nodes that have any additional roles except the node-role.kubernetes.io/worker role.

View the following sample of the function:

...
objectDefinition:
  apiVersion: v1
  kind: ConfigMap
  metadata:
    name: my-configmap
  data:
    key: '{{ hasNodesWithExactRoles "infra" }}'

4.21. skipObject

The skipObject function is only available in managed cluster templates in a ConfigurationPolicy resource. Calling {{ skipObject }} at any time inside a Go template signals to skip that particular object for the policy. When you use the skipObject with the objectSelector, you can further filter objects selected by name. You can call skipObject by itself inside a conditional or with an optional boolean argument.

View the following example that selects objects that have the label foo: bar, but skips objects that have a name with the suffix -prod:

...
object-templates:
  - objectSelector:
      matchExpressions:
      - key: foo
        operator: In
        values:
        - bar
    objectDefinition:
      apiVersion: v1
      kind: ConfigMap
      data:
        key: '{{ skipObject (hasSuffix "-prod" .ObjectName) }}{{ hasNodesWithExactRoles "infra" }}'

Additional resources

4.22. Sprig open source

Red Hat Advanced Cluster Management supports most of the template functions from the sprig open source project, except for env and expandenv.

View the following table:

Table 4.2. Table of supported, community Sprig functions
Sprig libraryFunctions

Cryptographic and security

htpasswd

Date

date, mustToDate, now, toDate

Default

default, empty, fromJson, mustFromJson, ternary, toJson, toRawJson, mustToRawJson

The Json functions listed are also aliased to an equivalent uppercase JSON function.

Dictionaries and dict

dict, dig, get, hasKey, keys, merge, mustMerge, set, unset, values

Encoding

b64dec, b64enc

Flow control

fail

Integer math

add, mul, div, round, sub

Integer slice

until, untilStep,

Lists

append, has, list, mustAppend, mustHas, mustPrepend, mustSlice, prepend, slice

String lists

concat, join, sortAlpha, split, splitn, splitList

Strings

cat, contains, hasPrefix, hasSuffix, lower, mustRegexFind, mustRegexFindAll, mustRegexMatch, quote, regexFind, regexFindAll, regexMatch, regexQuoteMeta, replace, substr, trim, trimAll, trunc, upper

Version comparison

semver, semverCompare

Additional resources

4.23. Advanced template processing

Managed cluster and hub cluster templates reduce the need to create separate policies for each target cluster or hard code configuration values in policy definitions. For security, resource-specific and generic lookup functions in hub cluster templates are restricted to the policy namespace on the hub cluster.

Important: Using hub cluster templates to propagate secrets or other sensitive data exposes the data in the managed cluster namespace on the hub cluster, and on the managed clusters where that policy is distributed. Template content expands within the policy, and policies are not encrypted by the OpenShift Container Platform etcd encryption support. To address this, use fromSecret or copySecretData to automatically encrypt values from the secret, or use protect to encrypt other values.

Special annotation for reprocessing

Hub cluster templates are resolved to the data in the referenced resources during policy creation, or when the referenced resources are updated.

If you need to manually initiate an update, use the policy.open-cluster-management.io/trigger-update annotation to indicate changes for the data referenced by the templates. Any change to the special annotation value automatically initiates template processing. Additionally, the latest contents of the referenced resource are read and updated in the policy definition that is propagated for processing on managed clusters. A way to use this annotation is to increment the value by one each time.

Template processing bypass methods

By default, Red Hat Advanced Cluster Management processes all Go templates. To bypass template processing for a specific template, change {{ template content }} to {{ `{{ template content }}` }}. Then, the template returns a raw string to be processed by a subsequent templating engine.

To completely bypass the template resolution for a configuration policy, add the policy.open-cluster-management.io/disable-templates: "true" annotation to the relevant ConfigurationPolicy resource within the Policy resource.

4.24. Enable standalone hub cluster templating

Enable the governance-standalone-hub-templating add-on to resolve hub cluster templates on a managed cluster when you deploy configuration policies directly to managed clusters, for example, by using GitOps.

Required access: Cluster administrator

Procedure

  1. Go to the managed cluster namespace on your hub cluster.
  2. Create a ManagedClusterAddOn resource named governance-standalone-hub-templating by applying the following YAML configuration:

    apiVersion: addon.open-cluster-management.io/v1alpha1
    kind: ManagedClusterAddOn
    metadata:
      name: governance-standalone-hub-templating
      namespace: <cluster_name>
      labels:
        cluster.open-cluster-management.io/backup: ''
    spec:
      installNamespace: open-cluster-management-agent-addon

    Notes:

    • The spec.installNamespace field is deprecated.
    • The agent on the managed cluster accesses the ManagedCluster resources on the hub cluster. You can use the .ManagedClusterLabels template variable in the hub cluster templates inside the ConfigurationPolicies that you deploy directly to the managed cluster.
  3. Grant specific permissions to the add-on group to allow the hub template to access other resources through functions like lookup or fromConfigMap.

Grant permissions to the add-on group using roles and role bindings to allow the standalone hub cluster templating add-on to access resources through functions like lookup or fromConfigMap.

The add-on group uses the naming format system:open-cluster-management:cluster:<cluster_name>:addon:governance-standalone-hub-templating, where <cluster_name> represents your managed cluster name.

The add-on resolves hub cluster templates and saves the policy state in a secret on the managed clusters, preventing operational interruptions if the hub cluster becomes temporarily unavailable.

Prerequisites

  • Enable the governance-standalone-hub-templating add-on on the managed cluster.
  • Install the Red Hat OpenShift Container Platform command line interface and authenticate to the hub cluster.

Procedure

  1. Create a Role resource to allow reading configuration maps in your managed cluster namespace on the hub cluster. Run the following command:

    oc create role -n <cluster name> cm-reader --verb=get,list,watch --resource=configmaps
  2. Create a Rolebinding resource to assign the role to the add-on group. Run the following command:

    oc create rolebinding -n <cluster name> cm-reader-binding --role=cm-reader --group=system:open-cluster-management:cluster:<cluster name>:addon:governance-standalone-hub-templating
  3. Add the cluster.open-cluster-management.io/backup label to each created resource.
Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat Documentation

Legal Notice

Theme

© 2026 Red Hat
Back to top