Skip to main content

Using Template Functions

Replicated app manager applications have access to a rich set of template functions that can be used to render the Kubernetes manifests in the customer's environment.

The app manager uses Go's text/template libraries as the basis for the templating. All functionality of Go's templating language can be used in conjunction with the app manager custom functions.

All template functions are documented in the template function reference section.

Example: Use a Template Function for a Custom License Field

To use a template function, include it as a string in the application. A simple example is using a boolean custom license field to deliver a value for Max Concurrent Users. This value should be available as an environment variable in a pod.

Given the custom license field named max_concurrent_users, this value can be supplied to the pod environment variable like this:

apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
selector:
matchLabels:
app: api
template:
spec:
containers:
- image: myapp/api:v1.0.1
name: api
env:
- name: MAX_CONCURRENT_USERS
value: 'repl{{ LicenseFieldValue "max_concurrent_users" }}'

Template Function Syntax

The template function syntax supports delimiters of either {{repl ...}} or repl{{ ... }}. These are functionally equivalent and both are supported by the app manager runtime.

However, {{ is not a valid string beginning in YAML, so to use {{repl as the only part of a value, it's required that the YAML attribute be surrounded by quotes. For example:

env:
- name: MAX_CONCURRENT_USERS
value: '{{repl LicenseFieldValue "max_concurrent_users"}}'

This solution is readable and works well for string values. The surrounding ' characters allow this to be parsed and will render as:

env:
- name: MAX_CONCURRENT_USERS
value: '100'

But some Kubernetes API fields require integer values, not strings. For example, replica count. The following YAML is not valid:

replicas: '{{repl ConfigOption "replicas"}}'

This is invalid because it will render as:

replicas: '5'

And the Kubernetes API will reject a string value in this position.

To solve this, reverse the delimiter in the template function and remove the surrounding quotes:

replicas: repl{{ ConfigOption "replicas" }}

Because this doesn't have surrounding quotes and is valid YAML, this will render as:

replicas: 5

And Kubernetes will be able to handle this.

Use Variables in Templates

A result returned from a template function can be assigned to a variable, and the variable can be used in another template function as long as the templates are evaluated at the same time.

All manifest files for the application are templated in a single pass. The Config custom resource manifest file is an exception. Each config item is templated separately and has no access to variables created in other config items. As a workaround, a hidden config item can be used to evaluate complex templates and render the results. The result can be accessed using the ConfigOption function.

For more information about the Config custom resource, see Config in the Custom resources section.

Example: Generating TLS Certificates and Keys

This example demonstrates how to generate a CA, a cert, and a key using Sprig functions. tls_json is the hidden config item that contains all of the generated values in JSON format.

Prerequisites

  • This requires the app manager 1.26.0 or later.
  • Warning: Default values are treated as ephemeral. The following certificate chain is recalculated each time the application configuration is modified. Be sure that your application can handle updating these parameters dynamically.
apiVersion: kots.io/v1beta1
kind: Config
metadata:
name: config-sample
spec:
groups:
- name: example_settings
title: My Example Config
items:
- name: ingress_hostname
title: Ingress Hostname
help_text: Enter a DNS hostname to use as the cert's CN.
type: text
- name: tls_json
title: TLS JSON
type: textarea
hidden: true
default: |-
repl{{ $ca := genCA (ConfigOption "ingress_hostname") 365 }}
repl{{ $tls := dict "ca" $ca }}
repl{{ $cert := genSignedCert (ConfigOption "ingress_hostname") (list ) (list (ConfigOption "ingress_hostname")) 365 $ca }}
repl{{ $_ := set $tls "cert" $cert }}
repl{{ toJson $tls }}
- name: tls_ca
title: Signing Authority
type: textarea
default: repl{{ fromJson (ConfigOption "tls_json") | dig "ca" "Cert" "" }}
- name: tls_cert
title: TLS Cert
type: textarea
default: repl{{ fromJson (ConfigOption "tls_json") | dig "cert" "Cert" "" }}
- name: tls_key
title: TLS Key
type: textarea
default: repl{{ fromJson (ConfigOption "tls_json") | dig "cert" "Key" "" }}