WORK IN PROGRESS

1. Overview

Helm is an excellent package management tool for deploying to Kubernetes, but it falls short when it comes to templating Kubernetes manifests. Creating templates in Helm can be difficult to learn and master, and it has no support for Kubernetes resources or configuration management.

For the remainder of this document and unless otherwise explicitly noted, "templates" will refer only to el-CICD Chart templates, and NOT Helm templates.

1.1. Issues With Helm Templates

Verbose

Helm/Go templates and associated values files are verbose, and a good understanding of the Kubernetes resources is required when creating templates. Multiple copies of the same resource type with varying structural content can require multiple copies of the same, verbose template boilerplate, because reuse of YAML is not directly supported, too.

Obtuse

Go Template syntax (everything between the double-brackets) and the supporting Sprig library is not very user friendly, but it’s required knowledge to understand and modify Helm templates.

Values used to render the chart are defined in files separate from Helm templates, and structured far differently, which can make understanding what will rendered difficult.

No configuration management

Configuration management is not supported by Helm. Defining charts that can adapts across even a narrowly defined set of different deployments can be challenging.

It’s code

Helm templates are code; it constitutes a separate application. This means Helm charts need to be tested in isolation from the application they are meant to deploy. Helm charts acknowledge this by supporting a built-in testing framework.

1.2. A Better Way To Create Templates In Helm

el-CICD Chart is a 100% compatible Helm chart that does away with the need for Go templates and replaces it with a much simpler and — in some cases — more flexible alternative for defining Kubernetes deployment manifests. No other tool is required other than Helm, and el-CICD Chart only uses strict YAML for defining it’s deployment definitions. The goal is to make sure there is no need to ever define a Helm/Go template again, and make creating Helm compatible templates easier much easier.

With el-CICD Chart values.yaml files have the following features:

Variables

Define el-CICD Chart variables, which can hold any valid YAML type.

YAML templates

Create templates for any arbitrary YAML.

Leverage built-in Kubernetes templates

Use pre-defined templates for many Kubernetes resources to further reduce the amount of boilerplate needed.

Deployment profiles

Define deployment profiles, which makes defining multiple definitions of the same resource in the same values.yaml file.

Adding these easy to use features to Helm’s values.yaml files significantly reduces the amount of boilerplate necessary to define Kubernetes deployment manifests, as well as significantly reducing the learning curve needed to write them.

2. Helm Repository Contents And Usage

el-CICD Chart as a project is made up of two charts, a Helm library chart and an application chart:

Provided elcicd-charts with usage example
  • elcicd-lib: library chart

    1
    2
    3
    4
    5
    
    # Chart.yaml
    dependencies:
    - name: elcicd-lib
      version: 0.1.0
      repository: https://elcicd.github.io/el-CICD-deploy/charts/
    
  • elcicd-chart: application chart

    1
    2
    
    $ helm repo add elcicd-charts https://elcicd.github.io/el-CICD-deploy/charts/
    $ helm repo update
    

Because library charts cannot render anything by definition, the application chart is provided as a convenience chart that references the library chart as a dependency so that end users aren’t required to create their own charts.

GitHub pages is the current hosting platform for the charts. The charts is also provided from GitHub’s OCI registry, but Helm must be authenticated with GitHub before attempting to use this method:

helm registry login --username ${USERNAME} oci://ghcr.io/elcicd

3. Deployment Definitions

In el-CICD Chart, a collection of one or more Helm values.yaml files defining a deployment will be referred to as a deployment definition. These are the only files required to be written by the end user for deploying to Kubernetes when used in conjunction with Helm and el-CICD Chart. It was a fundamental requirement when designing el-CICD Chart that it remain 100% compatible with Helm, and only requiring values.yaml files for use was how the requirement was met.

A deployment definition consists of el-CICD Chart templates for defining what is rendered through Helm, el-CICD variables for defining any reusable data the templates need, and el-CICD deployment profiles to support different configurations among the same templates. el-CICD Chart adds built-in Kubernetes resource definitions with reasonable default values in order to further reduce boilerplate.

3.1. Basic Structure

The basic structure of an el-CICD Chart deployment definition in a values.yaml file is as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
elCicdDefs:  (1)
  ...

elCicdDefs-<profile or object name>: (1)
  ...

elCicdDefs-<object name>-<profile>: (1)
  ...

elCicdDefs-<profile>-<object name>: (1)
  ...

elCicdTemplates: (2)
  ...

elCicdTemplates-<unique identifier>__: (2)
  ...
1 elCicdDefs(-*) maps define el-CICD Chart variables.
2 elCicdTemplates(-*) lists define el-CICD Chart templates.

3.2. Deployment Profiles

Deployment profiles are the primary mechanism by which el-CICD Chart supports configuration management within a deployment definition.

Deployment profiles are typically defined dynamically on the command line in a list using the elCicdProfiles identifier:

helm upgrade --install --set elCicdProfiles='{<PROFILE_1>,…​,<PROFILE_N>}' …​

Profiles must start and end with an upper case alphanumeric character, and may contain any number of upper case alphanumeric characters delimited by either a single _ or .. The regular expression for a profile is:

(?:[._][A-Z0-9])*

Profile naming standards were defined to disambiguate them from objNames.

A profile is said to be an active profile during the rendering of a deployment definition if included in the elCicdProfiles list.

Within a deployment definition, profiles are defined as either a discriminator for a map of variables or as condition for filtering templates. Which deployment profiles are active at rendering will determine which values are ultimately assigned to variables and whether a template is rendered or not. This is how a single deployment definition can easily hold multiple different configurations.

The default deployment profile is an empty list; i.e. no active profiles. If more than one profile is active at a time, precedence is defined as least to greatest in the order of the list per Helm convention.

3.3. Templates

el-CICD Chart templates are defined in one or more lists starting with the prefix elCicdTemplates:

1
2
3
4
5
6
elCicdTemplates-<unique identifier>: (1)
- templateName: <built-in-template-name>  (2)
  ...
- template: (3)
    <full-YAML-definition>
  ...
1 List of el-CICD Chart templates. The unique identifier suffix is optional.
2 el-CICD Chart template using a built-in template.
3 el-CICD Chart template defined by its full YAML definition.

In order to support multiple values.yaml files for flexibility and modularity when rendering deployment definitions with Helm, multiple elCicdTemplates lists may be defined using the optional unique identifier suffixes. The order the lists and templates is irrelevant. All elCicdTemplates lists will be concatenated before processing. Each list name should be unique per deployment definitions, or the Helm rules for merging values.yaml will overwrite lists with matching names. The text after elCicdTemplates- can be any valid YAML string.

Example deployment definition with three elCicdTemplates lists
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
elCicdTemplates:
- templateName: <built-in-template-name>
  ...

elCicdTemplates-my-secondList:
- templateName: <built-in-template-name>
  ...

elCicdTemplates-WITH_YA%ML:
- template:
    <full-YAML-definition>
  ...

3.3.1. Types Of Templates

el-CICD Chart supports two types of templates:

  • Built-in templates: Predefined templates within el-CICD Chart.

    • Includes many predefined defaults and helper attributes to make rendering resources simpler and less verbose.

    • Defined using the templateName key to use a single built-in or templateNames for compound definitions.

  • free-form templates: Templates of plain YAML that define all or most of resource to be rendered.

    • Defined using the template key.

3.3.2. Helper Attributes

All el-CICD templates, whether free-form or built-in, have a number of helper attributes.

  • kubeObject: Default value is true. Set to false to disable generating the Kubernetes object fields such as apiVersion or the metadata map.

    • Only applies to free-form templates.

  • objName: Directly corresponds to metadata.name.

  • apiVersion: Directly corresponds to apiVersion.

    • Only define this value for a built-in template if a different version than the default is required.

  • namespace: Directly corresponds to metadata.namespace.

  • labels: Directly corresponds to metadata.labels.

  • annotations: Directly corresponds to metadata.annotations.

free-form templates will use the helper attributes as alternative convenience fields. They will be ignored if defined directly in the template map.

3.3.2.1. Discriminator Lists

Discriminator profile lists are helper attributes that define whether a template is rendered or not based on what deployment profiles are active during rendering. The available discriminator lists are:

  • mustHaveAnyProfile: if any profile in this list is active, render the template.

  • mustHaveEveryProfile: if every profile in this list is active at the same time, render the template.

  • mustNotHaveAnyProfile: if any profile in this list is active, do NOT render the template.

  • mustNotHaveEveryProfile: if every profile in this list is active at the same time, do NOT render the template.

Each of the above may be used in combination with each other, and their order of precedence is undefined.

Example of template filtering
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
elCicdTemplates:
- templateName: <built-in-template-name>
  objName: obj-1
  mustHaveAnyProfile: [PROFILE_1, PROFILE_2] (1)
- objName: obj-2
  mustHaveEveryProfile: [PROFILE_1, PROFILE_2] (2)
  template:
    <full-YAML-definition>
- templateNames: [<built-in-template-name1, built-in-template-name2>]
  objName: obj-3
  mustNotHaveAnyProfile: [PROFILE_1, PROFILE_2] (3)
- objName: obj-4
  mustNotHaveEveryProfile: [PROFILE_1, PROFILE_2, PROFILE_3] (4)
  template:
    <full-YAML-definition>
  ...

Given elCicdProfiles='{PROFILE_1,PROFILE_3}'; i.e. PROFILE_1 and PROFILE_3 are active:

1 mustHaveAnyProfile requires either PROFILE_1 or PROFILE_3 to be active, so obj-1 IS rendered.
2 mustHaveEveryProfile requires both PROFILE_1 and PROFILE_2 to be active, so obj-2 is NOT rendered.
3 mustNotHaveAnyProfile requires neither PROFILE_1 or PROFILE_2 to be active, , so obj-3 is NOT rendered.
4 mustNotHaveEveryProfile requires PROFILE_1, PROFILE_2, and PROFILE_3 to not all be active at the same time, so obj-4 IS rendered.
3.3.2.2. Matrices

Matrices are a special kind of helper attribute. Matrices are lists of strings, and el-CICD Chart before final rendering it will be replaced by a copy of the template for each element in the matrix.

el-CICD Chart currently only supports two matrix keys:

  • objNames: Sets the objName helper attribute to match the element for each copy.

  • namespaces: Set the namespace helper attribute to match the element for each copy.

When using matrices, the objName and namespace attributes can used to define how the final value will be rendered with the following patterns:

  • $<>: Inserts the literal value from the matrix.

  • $<#>: Inserts the index of the value in the matrix list.

Example use of objNames and namespaces matrices
1
2
3
4
5
6
elCicdTemplates:
- templateName: <built-in-template-name>
  objNames: [foo, bar]  (1)
  namespaces: [zip, zap] (2)
  objName: $<>-static-name-$<#> (3)
  namespace: $<>-some-namepace-$<#> (3)
1 Will generate two copies of this template for rendering; the original template will then be ignored.
2 Will generate two copies of the template, one for each namespace.
3 Pattern to generate final name and namespace; e.g. <objNames element>-static-text-<index of matrix element>

The above example template results in the following output:

Example of templates generated from objNames and namespaces matrices
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
elCicdTemplates:
- templateName: <built-in-template-name>
  objName: foo-static-name-1
  namespace: zip-some-namespace-1

- templateName: <built-in-template-name>
  objName: bar-static-name-2
  namespace: zip-some-namespace-1

- templateName: <built-in-template-name>
  objName: foo-static-name-1
  namespace: zap-some-namespace-2

- templateName: <built-in-template-name>
  objName: bar-static-name-2
  namespace: zap-some-namespace-2

3.3.3. Built-in Templates

el-CICD Chart defines a number of pre-defined templates in order to further reduce excess boilerplate YAML, and these are referred to as built-in templates. By convention, the names of built-in templates reflect the Kubernetes object they are to render; e.g. deployment for a Deployment and horizontalPodAutoscaler for a HorizontalPodAutoscaler. Built-in templates are requested via the templateName key.

Example using the ConfigMap built-in template
1
2
3
4
5
6
elCicdTemplates:
- templateName: configMap (1)
  objName: my-configmap (2)
  data: (4)
    a-key: a-value
    b-key: b-value
1 Built-in template to render.
2 Eventual name of the rendered object; i.e. metadata.name.
3 Helper attribute rendered to configmap.data.

The above example template results in the following output:

Example ConfigMap rendered from built-in template
1
2
3
4
5
6
7
apiVersion: v1 (1)
kind: ConfigMap (1)
metadata: (1)
  name: my-configmap  (2)
data:  (3)
  a-key: a-value
  b-key: b-value
1 ConfigMap apiVersion, kind, and metadata map for a Kubernetes object from the built-in configMap template.
2 metadata.name generated from objName.
3 data map generated from data helper attribute.

Some built-in templates only include helper attributes that reflect their normal attributes, such as the ConfigMap example above, and are small conveniences for reducing unnecessary boilerplate. Some built-ins have a few extra helper attributes that significantly reduce the amount a boilerplate needed to define a complete object. See the Built-in Templates section for a complete list of all built-ins and their helper attributes.

The current set of built-in templates focus almost exclusively on application deployments and supporting Kubernetes resources. It is hoped that el-CICD Chart will be able to fully support all Kubernetes resources in the future, as well as some of the more widely used Custom Resource Definitions.
3.3.3.1. Compound Built-in Templates

In order to further reduce excess boilerplate YAML, el-CICD Chart allows defining compound built-in templates. Compound built-in templates combine more than one built-in template definitions into a single definition with each individual built-in re-using any shared helper attributes. Compound built-in templates are defined as a list of one more strings under the templateNames key.

Example Deployment, Service, and Ingress as individual built-in templates
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
elCicdTemplates:
- templateName: deployment (1)
  objName: my-app
  image: <some-image>
  port: 8080 (2)

- templateName: service (1)
  objName: my-app
  port: 8081 (2)
  targetPort: 8080 (3)

- templateName: ingress (1)
  objName: my-app
  host: example.com
  port: 8081 (2)
1 templateName of the deployment, service, and ingress built-in templates individually defined.
2 port is defined differently on the separate templates for illustrative purposes.
3 targetPort needs to match the deployment port.
Example Deployment, Service, and Ingress as a single compound templates
1
2
3
4
5
6
7
elCicdTemplates:
- templateNames: [deployment, service, ingress] (1)
  objName: my-app (2)
  image: <some-image>
  host: example.com
  port: 8081 (3)
  targetPort: 8080 (4)
1 templateNames defines this template as combining a deployment, service, and ingress.
For more concise compound templates, take advantage of the fact that YAML is a superset of JSON and use JSON-like list notation.
2 objName is shared among all three resources.
3 port is shared between the service and the ingress. If the service’s outward and inward facing port’s were the same, only the port attribute would need to be defined.
4 targetPort is also a helper attribute of deployment that has precedence over a port definition, making this compound template equivalent to individually defined templates in the previous example.
3.3.3.2. Default Values

Many built-in templates have reasonable default values defined in order to further reduce boilerplate; e.g. if the port and targetPort are the same and the default value (8080) is sufficient, and the release name is sufficient as a metadata.name:

Deployment and Service as compound built-in templates
1
2
3
elCicdTemplates:
- templateNames: [deployment, service]
  image: <some-image>

The above is the minimal amount that’s needed in a deployment definition for a simple deployment of an application to a Kubernetes cluster using el-CICD Chart. Add the ingress built-in to the list and define the host helper attribute if the application is meant to be accessed from outside the cluster.

3.3.4. Free-Form Templates

If more complex template definitions are required, or a built-in template doesn’t exist for a resource, a free-form template can be defined. free-form templates are just fully defined YAML definitions of resources. While more verbose than using the simpler, built-in templates, Kubernetes is infinitely extensible with Custom Resource Definitions (CRD’s), and having free-form templates means that no matter what CRD’s are introduced now or in the future, el-CICD Chart deployment definitions can adapt without requiring the user to resort to creating new Helm/Go templates.

For example, ArgoCD is a popular GitOps solution for managing deployments to Kubernetes clusters, and el-CICD Chart currently has no built-in templates to support an ArgoCD Application, but with free-form templates this isn’t an issue:

Defining an ArgoCD Application for my-app
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
elCicdTemplates:
- template:
    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
      name: my-application-name
      namespace: argocd
    spec:
      project: default
      source:
        repoURL: https://my-git-server.com/my-org/my-app.git
        targetRevision: HEAD
        path: my-app
      destination:
        server: https://kubernetes.default.svc
        namespace: my-app-namespace

Built-in templates are a convenience, and not a necessity. The advantage of free-form templates are that they can still use all other features of el-CICD Chart (e.g. matrices), which means easier templating and configuration management. Anywhere a built-in template is used a free-form template can be substituted, and vice versa if a built-in template exists for the object being rendered; however, if a templateName or templateNames helper attribute are defined, template will be ignored.

3.4. Variables

In traditional Helm, Helm values.yaml files are static YAML files that are fed to a chart consisting of Helm/Go templates and processed to produce resource definitions for deployment to Kubernetes. In order to simplify defining templates and move away from Helm/Go templates, defining variables in deployment definitions was implemented.

3.4.1. Defining

Variables are defined in YAML maps named starting with elCicdDefs either at the root of a document or within an el-CICD Chart template definition. Variables may contain any any valid YAML syntax and type.

Example el-CICD variable definitions by type
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
elCicdDefs: (1)
  STRING: string  (2)

  MULTILINE_STRING: |- (3)
    long
    multiline
    text

  BOOLEAN: true (4)

  NUMBER: 10 (5)

  MAP: (6)
    foo: bar

  LIST: (7)
  - foo
  - bar
1 The elCicdDefs map defines the default set of variables for a deployment definition.
2 A variable representing a string.
3 A variable representing a multiline string.
4 A variable representing a boolean.
5 A variable representing a number.
6 A variable representing a map.
7 A variable representing a list.

Variable names must are defined by strings of alphanumeric characters or _ and optionally delimited by single dashes, -. The regular expression for a variable name is

?(?:[-][\w]?)*

By convention, variables are defined with UPPER_SNAKE_CASE, similar to scripting in shell, but this is not a requirement.

Example valid and invalid variables
1
2
3
4
5
6
7
8
elCicdDefs:
  VALID_VAR: is-valid
  valid-VAR: is-valid
  1-valid-var: is-valid

  -invalid-var: dash-at-the-beginning
  INVALID_VAR-: dash-at-the-end
  INVALID--VAR: double-dashes-middle-of-definition
Invalid variable definitions that are valid YAML are simply ignored. It is not el-CICD Chart’s place to flag valid YAML, and it should be pretty easy to debug any issues by looking at the eventual output.

3.4.2. Referencing

Variables are referenced with the following syntax:

$<VARIABLE_NAME>

Escaping a variable performed with a backslash:

\$<VARIABLE_NAME>

This notation was chosen for two reasons:

  • No scripting languages use it, making the templating of scripts in other languages within a deployment definition straightforward.

  • Variables and their references are valid YAML both as keys in maps and as values in strings, maps, and lists. Helm requires that values.yaml files (and therefore el-CICD Chart deployment definitions) be valid YAML.

Because of the way Helm works, elCicdDefs variable maps are read in completely with the rest of the deployment definition, and each final variable reference value is only determined during processing; therefore, variables do NOT have to be defined before being referenced.

Example of variables referencing other variables
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
elCicdDefs:
  OTHER_VARIABLE: $<VARIABLE> (1)

  VARIABLE: some-name (2)

  $<OTHER_VARIABLE>: final-value (3)

  ESCAPED_VARIABLE: \$<LITERAL_VALUE> (4)

  $<$<FOO>$<BAR>>: dynamic-$<FOO>$<BAR>-value (5)
  FOO: foo
  BAR: bar
1 OTHER_VARIABLE references VARIABLE (defined immediately afterwards), and therefore has the value some-name.
2 VARIABLE has the value of some-name.
3 OTHER_VARIABLE is referenced as the key to a variable; therefore, a variable is defined as some-name with the value final-value.
4 ESCAPED_VARIABLE has the string value “$<LITERAL_VALUE>”, which is NOT a variable reference, because of the \ in front of the $ escaping it. Note that the final value of ESCAPED_VARIABLE does NOT contain the backslash. Backslashes are removed during processing.
5 FOO and BAR are dynamically used to define the variable foobar, with a value of dynamic-foobar-value.

3.4.3. Importing Variable Values from Files

Variable values may be imported from one or more files. There following three prefixes tell el-CICD Chart to import data from external files:

  • $<FILE|path> will import text from a file at the given path.

  • $<CONFIG|path> will import and convert a conf/properties/ini file in to YAML at the given path.

  • $<GLOB|path> will import a map of filenames to each file’s text content at the given path.

The rules defining which files may be accessed are:

  • Files in templates/ cannot be accessed.

  • Files excluded using .helmignore cannot be accessed.

  • Files outside of a Helm application subchart, including those of the parent, cannot be accessed

3.4.3.1. FILE Value Import Prefix

Reads in the contents of a single file at the named path and assigns the text as a string to the variable.

Example of variables whose values come from files
1
2
elCicdDefs:
  VALUE_FROM_FILE_TEXT: $<FILE|path/to/file.py>
file.py
1
2
3
x=5
y=2
print(f'{x} + {y} = {x + y}')
Resulting value of variable
1
2
3
4
5
elCicdDefs:
  VALUE_FROM_FILE_TEXT: |-
    x=5
    y=2
    print(f'{x} + {y} = {x + y}')
3.4.3.2. CONFIG Value Import Prefix

Reads in the contents of a single file where each line has the form key=value at the named path and assigns the text as a string to the variable. Section headers are ignored.

Example of variables whose values come from files
1
2
elCicdDefs:
  VALUE_FROM_CONFIG_FILE: $<CONFIG|path/to/config/file.ini>
file.ini
1
2
a=b
foo = bar
Resulting value of variable
1
2
3
4
elCicdDefs:
  VALUE_FROM_CONFIG_FILE:
    a: b
    foo: bar
3.4.3.3. GLOB Value Import Prefix

Reads each file in a directory, and if match the given glob pattern the files contents will be added to a map with the filename as the key.

Example of variables whose values come from files
1
2
elCicdDefs:
  VALUE_FROM_GLOB: $<GLOB|path/to/files/*>
file.py
1
2
3
x=5
y=2
print(f'{x} + {y} = {x + y}')
file.ini
1
2
a=b
foo = bar
Resulting value of variable
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
elCicdDefs:
  VALUE_FROM_GLOB:
    file.py: |-
      x=5
      y=2
      print(f'{x} + {y} = {x + y}')

    file.ini: |-
      a=b
      foo = bar

3.4.4. Built-in Variables

el-CICD Chart defines a number of built-in variables for use in templates, Helm and template.

3.4.4.1. Helm Built-In Variables

el-CICD Chart has a few built-in variables derived from Helm’s built-in objects.

el-CICD Chart Helm built-in variable examples
1
2
3
elCicdDefs:
  MY_RELEASE_NAME: $<HELM_RELEASE_NAME> (1)
  MY_RELEASE_NAMESPACE: $<HELM_RELEASE_NAMESPACE> (2)
1 HELM_RELEASE_NAME is equivalent to .Release.Name, the release name when deployed.
2 HELM_RELEASE_NAMESPACE is equivalent to .Release.Namespace, the release namespace when deployed.
3.4.4.2. Template Built-In Variables

Each template has it’s own set of built-in variables set when being processed for use in deployment definitions:

el-CICD Chart template built-in variable examples
1
2
3
4
5
elCicdDefs:
  MY_OBJ_NAME: $<OBJ_NAME> (1)
  MY_BASE_OBJ_NAME: $<BASE_OBJ_NAME> (2)
  MY_NAME_SPACE: $<NAME_SPACE> (3)
  MY_BASE_NAME_SPACE: $<BASE_NAME_SPACE> (4)
1 OBJ_NAME: value of the objName helper attribute.
2 BASE_OBJ_NAME: value of an element from the objNames matrix that objName was derived from. Will default to the value of OBJ_NAME if objNames is undefined.
3 NAME_SPACE: namespace the resource will be deployed to. Defaults to HELM_RELEASE_NAMESPACE.
4 BASE_NAME_SPACE: value of an element from the namespaces matrix. Will default to the value of NAME_SPACE if namespaces is undefined.

3.4.5. Scoping

elCicdDefs variables have two different scopes:

  • Deployment

    All elCicdDefs variables defined outside of any el-CICD Chart templates; i.e. defined under elCicdDefs maps at the root of the deployment definition. Every el-CICD template in the deployment definition may reference these variables.

  • Template

    All elCicdDefs variables defined under a specific el-CICD Chart template. Only the specific el-CICD template may use these variables.

Example of deployment and template elCicdDefs map definitions
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
elCicdDefs: (1)
  VAR: outer

elCicdTemplates:
- templateName: <template name>
  objName: $<VAR>$<INNER_VAR>
  elCicdDefs: (2)
    INNER_VAR: inner
- templateName: <template name>
  objName: $<VAR>$<INNER_VAR>
1 elCicdDefs defined at the root of the deployment definition are said to have deployment scope. VAR can be used by first-template and second-template.
2 INNER_VAR is only available to the first-template, because its elCicdDefs map is defined directly under it; therefore, the first template will be named outerinner, and the second outer.

3.4.6. Overriding

Variables may be defined or overridden in el-CICD Chart by defining more specific elCicdDefs maps. The types of elCicdDefs maps are:

  • Profile

    elCicdDefs-<PROFILE_NAME> maps defined for a specific deployment profile. Only one profile may be named.

  • objName

    elCicdDefs-<OBJ_NAME> maps defined for a specific objName or BASE_OBJ_NAME. Only one objName may be named.

  • Profile and objName

    elCicdDefs-<PROFILE_NAME>-<OBJ_NAME> or elCicdDefs-<OBJ_NAME>-<PROFILE_NAME> maps defined for a specific deployment profile and objName. Only one objName and/or profile may be used.

Example of different elCicdDefs map definitions
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
elCicdDefs: (1)
  VAR: a-var

elCicdDefs-PROFILE: (2)
  VAR: a-var

elCicdDefs-obj-name: (3)
  VAR: a-var

elCicdDefs-PROFILE-obj-name: (4)
  VAR: a-var

elCicdDefs-obj-name-PROFILE: (4)
  VAR: a-var
1 Default elCidDefs map.
2 Profile specific elCidDefs map. Only applies if PROFILE is active.
3 objName specific elCidDefs map. Only applies to resources where the objName or BASE_OBJ_NAME match.
4 Profile and objName specific elCidDefs maps. Only applies when PROFILE is active and to resources where the objName or BASE_OBJ_NAME match.

Each of these types of elCicdDefs maps may be defined at deployment or template scope.

3.4.6.1. Order Of Precedence

Order of precedence determines as which elCicdDefs map determines the ultimate value of a variable if it is defined in multiple variable maps.

From least to greatest:

  1. elCicdDefs: default.

  2. elCicdDefs-<PROFILE>

    1. PROFILE is an active profile.

    2. Deployment profiles' precedence is from least to greatest in the elCicdProfiles list.

  3. **elCicdDefs-<BASE_OBJ_NAME>

    An element from an objNames list.

  4. elCicdDefs-<objName>

    The objName value of a template.

  5. elCicdDefs-<PROFILE>-<BASE_OBJ_NAME>

  6. elCicdDefs-<BASE_OBJ_NAME>-<PROFILE>

  7. elCicdDefs-<PROFILE>-<objName>

  8. elCicdDefs-<objName>-<PROFILE>

All template specific elCicdDefs will have precedence over deployment elCicdDefs.

Example of precedence with elCicdDefs maps and active deployment profile PROFILE
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
elCicdProfiles: [PROFILE]

elCicdDefs:
  VAR: a-value

elCicdDefs-PROFILE:
  VAR: a-profile-value

elCicdDefs-obj-name:
  VAR: an-obj-name-value

elCicdTemplates:
- templateName: <template name>
  objName: obj-name  (1)
  elCicdDefs:
    VAR: final-value

- templateName: <template name>
  objName: an-obj-name-value  (2)

- templateName: <template name>
  objName: obj-name-3  (3)
1 VAR == final-value, because the template elCicdDefs overrides all deployment elCicdDefs maps.
2 VAR == an-obj-name-value, because elCicdDefs-<objName> has precedence over elCicdDefs-<profile>.
3 VAR == a-profile-value, because elCicdDefs-<profile> has precedence over elCicdDefs, and there’s no matching elCicdDefs-<objName> map.
To null a variable out, define it as an empty value in the appropriate map.

4. Rendering Process Overview

A high level overview of how el-CICD Chart processes and renders deployment definitions. How and when variables are realized is also explained.

  1. Realize Dynamic elCicdDefs-* Names

    elCicdDefs map names may be defined with variables; e.g. elCicdDefs-$<FOO>. All of the deployment elCicdDefs map names are processed first.

    ONLY values defined in the default deployment elCicdDefs can be used to define deployment elCicdDefs-* maps.
  2. Create Profile-based elCicdDefs

    Collect final values elCicdDefs based on deployment profiles only; i.e. consider only elCicdDefs-<PROFILE> maps.

  3. Collect and Filter All Templates

    elCicdTemplate-* lists are collected and concatenated to create an intermediate elCicdTemplates list. Templates are then removed if their discriminators fail.

  4. Expand Matrixes:

    Matrix values and lists can be parameterized with variables; e.g. namespaces: $<NAMESPACE_LIST> or objNames: [$<FOO>,$<BAR>]. Using the profiles-based elCicdDefs map, process the matrix variable references, and then generate copies for any templates with matrices defined to create a final elCicdTemplates list. The original template with the matrix defined is discarded.

    Only values derived from profile-based deployment elCicdDefs map can be used as variables in matrices.
  5. Process Templates

    For each template in the final template list:

    1. Use the active profiles and the objName to derive the final deployment elCicdDefs for the template.

    2. Using the final deployment elCicdDefs map as the starting point, process all template elCicdDefs to derive the final elCicdDefs map for the template.

    3. Using the final elCicdDefs map for the template, replace ALL remaining variable references in the template.

    4. If any escaped el-CICD Chart variable references exist, remove the backslash; e.g. \$<FOO> becomes $<FOO>.

  6. Render the Templates to YAML

    1. If templateName or templateNames are defined, process the named templates using the named built-in template(s) in the order they are defined.

    2. If templateName or templateNames are NOT defined, render the value of template.

  7. Output Final Metadata

    As YAML comments, output:

    • The list of active profiles

    • A list of each template skipped due to filtering.

    • A list of each template rendered.

This concludes the el-CICD Chart rendering process.

5. Specialized Utilities

el-CICD Chart has a some extra functionality built in to make creating deployment definitions easier, as well as enabling new means of defining deployment definitions for more dynamic deployments.

5.1. projectedVolumes By Labels

While Kubernetes Pods support mounting ConfigMaps and Secrets as volumes, there are some limitations. To address these limitations, Kubernetes added the concept of projected volumes. The advantage of Projected volumes is that several different resources — and not just ConfigMaps and Secrets — could be mounted to a single directory in a container.

Unfortunately, like most tools associated with deploying to Kubernetes, the manifests for mounting Secrets and ConfigMaps, whether individually or in projected volumes, had to be statically declared; i.e. the deployment manifests had to know all the resources to be mounted as volumes beforehand.

In order to enable more dynamic behavior, el-CICD Chart implemented functionality that would mount a collection of ConfigMaps and/or Secrets into a projected volume by their labels. Lists of labels can be provided, and the namespace of the Pod will be scanned for matching resources, all of which will be mounted into the container. The values of the labels are not relevant to this functionality. Only whether the label exists on the resource.

Example Using projectedVolumes.configMapsByLabels For Job

ConfigMaps are deployed first:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
elCicdTemplates:
- templateName: configMap
  objName: cm-1
  labels:
    foo: "doesn't matter"
  data:
    cm-1.txt: some text

- templateName: configMap
  objName: cm-2
  labels:
    foo: "doesn't matter"
  data:
    cm-2.txt: some text
The ConfigMaps must be deployed before using projectedVolumes.configMapsByLabels. Helm will only find resources already deployed in the sane namespace.
Deploy Job that is using projectedVolumes.configMapsByLabels:
1
2
3
4
5
6
7
8
9
elCicdTemplates:
- templateName: job
  objName: cm-by-labels-example
  image: <some-image>:latest
  projectedVolumes:
  - name: foo-label-volume
    mountPath: /mnt/testing
    configMapsByLabels:
      foo: {}
Partial pseudo-manifest generated by el-CICD Chart from deployment definition above:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
apiVersion: batch/v1
kind: Job
metadata:
  name: cm-by-labels-example
spec:
  template:
    metadata:
      labels:
      name: cm-by-labels-example
      namespace: elcicd-chart-demo
    spec:
      containers:
      - name: cm-by-labels-example
        image: <some-image>:latest
        ...
        volumeMounts:
        - mountPath: /mnt/testing
          name: foo-label-volume
          readOnly: false
        ...
      volumes:
      - name: foo-label-volume
        projected:
          sources:
          - configMap:
              name: cm-1
          - configMap:
              name: cm-2

5.2. copyResources

Sometimes it makes sense to copy resources from one namespace to another. From a design perspective, this is analogous to the prototype design pattern.

Example use cases:

  • A pull secret used by many or all applications on the cluster can be deployed in a master namespace. It’s easier to copy the Secret from the master namespace to the application namespaces than have every application manage its own copy directly.

  • Similarly, a common set of configuration values is defined in a ConfigMap and deployed in a master namespace, and they are used by many or all applications on the cluster. It’s easier to copy the ConfigMap from the master namespace to the application namespaces as needed than have every application manage its own copy directly.

el-CICD Chart has implemented a utility built-in template that will copy a resource from one namespace to any other.

copyResource built-in template structure
1
2
3
4
5
- templateName: copyResource
  objName: copy-example
  kind: <some resource kind>
  fromNamespace: <source namespace>
  toNamespace: <target namespace>

In conjunction with the objNames namespace, a single template declaration can copy a resource as many times as it needs.

6. Debugging Utilities

el-CICD Chart supports two utilities to help with debugging deployment definitions.

renderPreprocessedValues

If true, output all merged values.yaml files as YAML and exit. No el-CICD Chart processing takes place. Templates will NOT be rendered to YAML. Useful for inspecting how Helm merges multiple deployment definition files, or creating a single el-CICD Chart values.yaml file from many values.yaml files.

helm template --set renderPreprocessedValues=true …​

renderProcessedValues

If true, output all values of a processed el-CICD Chart deployment definition as YAML and exit. Includes all values belonging elCicdTemplates and elCicdDefs maps and the elCicdProfiles list. Templates will NOT be rendered to YAML. Useful for inspecting the results of a processed deployment definition before the templates are rendered.

helm template --set renderProcessedValues=true …​

7. Unconventional Use-Cases

Below are a just a few unconventional use cases where el-CICD Chart can be used.

7.1. Third-party Helm Charts

There are many applications that already have Helm charts created for them, and rewriting them to use el-CICD Chart directly is not an effective use of time and resources. So how can el-CICD Chart still be leveraged for configuration management? The answer is to define a deployment definition that results in a values.yaml file compatible with the third-party chart, and pipe it or post-render it with a second Helm call using the target chart.

Example deployment definition for third-party Helm chart, third-party-chart-values.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
elCicdDefs:
  SOME_3RD_PARTY_VALUES_YAML_VAR: a-value

elCicdDefs-SOME_PROFILE:
  SOME_3RD_PARTY_VALUES_YAML_VAR: b-value

elCicdTemplates:
- kubeObject: false (1)
  template:
    third-party-value: $<SOME_3RD_PARTY_VALUES_YAML_VAR>  (2)
    ...
1 Set kubeObject to false so el-CICD does not automatically generate apiVersion, kind, and metadata fields.
2 Create a YAML template for the values.yaml files of the third-party chart under the template key, and parameterize values as necessary
Example deploying 3rd party chart
#!/bin/bash

helm template -f third-party-chart-values.yaml third-party-values-yaml elcicd-charts/elcicd-chart > final-values.yaml

helm upgrade --install -f final-values.yaml 3rd-party-deployment 3rd-party-charts/3rd-party-chart

7.2. Kustomize

Helm is not good at some things that el-CICD Chart cannot fix on its own; e.g. labeling and/or annotating an arbitrary collection of Kubernetes resources, oOr arbitrarily patching resources. Kustomize fills the gap in functionality that Helm in general or el-CICD Chart in particular can’t address.

kustomization.yaml files, though, are notoriously static in nature by design. Using el-CICD Chart to create a template of a Kustomization in order to make the files dynamic (e.g. for a CICD system) is trivial.

Example deployment definition kustomization-values.yaml for a dynamic kustomization.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
elCicdDefs: {}  (1)

elCicdTemplates:
- templateName: kustomization (2)
  fields:  (3)
    resources:
    - $<RESOURCES_FILE>

    commonLabels:
      elcicd.io/teamid: $<TEAM_ID>
      elcicd.io/projectid: $<PROJECT_ID>
1 elCicdDefs is only defined here to note that all variables in this example are expected to be passed in via the command line.
2 el-CICD Chart has a kustomization built-in template so that the boilerplate headers don’t need to be defined.
3 Create the Kustomization definition, and parameterize it as necessary.
Example --post-renderer kustomize.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/bash
cat <&0 > manifests.yaml

helm template -f kustomization-values.yaml \
  --set-string elCicdDefs.RESOURCES_FILE=manifests.yaml \
  --set-string elCicdDefs.TEAM_ID=my-team \
  --set-string elCicdDefs.PROJECT_ID=my-team-project \
  kustomization-release \
  elcicd-charts/elcicd-chart > kustomization.yaml

kustomize build .
Example using el-CICD Chart with a Helm --post-renderer to deploy third-party chart
helm upgrade --install -f deployment-def.yaml --post-renderer kustomize.sh my-app elcicd-charts/elcicd-chart

More information on using a Helm --post-renderer can be found here.

8. Extending el-CICD Chart

9. el-CICD Chart Reference

9.1. Glossary

Terms used to help define certain concepts in el-CICD Chart.

Active profile

Any values defined in the elCicdProfiles list during rendering of an el-CICD Chart.

Built-in template

Pre-defined el-CICD Chart Templates to help make creating deployment definitions. Referenced using the templateName helper attribute on an el-CICD template definition.

Compound built-in template

An el-CICD Chart template that uses multiple built in el-CICD Chart built-in templates. Referenced using the templateNames helper attribute on an el-CICD template definition. All values in the el-CICD Chart template are shared among the listed built-templates when rendering.

Deployment definition

A collection of Helm values.yaml files for use specifically with an el-CICD Chart.

Deployment profiles

List of strings values matching (?:_[A-Z]) assigned to elCicdProfiles the for use in a deployment definition. Profiles can be used as a rendering discriminator for el-CICD templates, or as an alternative set of variable definitions in an elCicdDefs- map.

Deployment scope

Where an el-CICD Chart variable defined. Can be either deployment scope, in which the variable is accessible to all templates, or template, in which the variable is accessible only to the specific el-CICD Chart template where it was defined. Template scope variables always take precedence over deployment scope variables.

Discriminator

Any deployment profile listed in under one of the following elCICD Chart Template properties:

  • mustHaveAnyProfile

  • mustHaveEveryProfile

  • mustNotHaveAnyProfile

  • mustNotHaveEveryProfile

Matches of active profiles with the above lists determine whether or not an el-CICD Chart Template is rendered or not.

el-CICD Chart Variables

Keys defined under elCicdDefs maps in a deployment definition holding arbitrary YAML values. Can be used to defined and/or reuse values in el-CICD templates.

el-CICD Chart Templates

Member of a list under elCicdTemplates in a deployment definition. Must contain either a templateName referencing a built-in template or a template attribute defining arbitrary YAML.

free-form template

An el-CICD Chart template that does not use an el-CICD Chart template, but rather defined itself under the template helper attribute as arbitrary YAML.

Helper attribute

Any attributes defined at the root of an el-CICD Chart template, which may or may not directly correlate to an attribute on the rendered resource.

Matrices

Optional list of valid Kubernetes namespace (namespaces) or object resource (objNames) values defined per el-CICD Chart Template. Each member of either list will result in a copy of the original template created and rendered for the particular namespace and/or name, and the original template ignored.

9.2. Keywords

Helm Chart Values settings defined for use in el-CICD Chart to help define deployment definitions.

elCicdDefaults

Used for overriding el-CICD Chart pre-defined defaults.

elCicdDefs

Identifier of map for defining el-CICD Chart variables.

elCicdProfiles

Identifier of list of strings for defining el-CICD Chart active profiles.

elCicdTemplates

Identifier of map for defining el-CICD Chart templates.

renderPreprocessedValues

Render the combined values.yaml files before el-CICD Chart processing.

renderProcessedValues

Render the combined values.yaml files after el-CICD Chart processing; i.e the values.yaml file after all variables and other el-CICD Chart settings in the deployment definition have been processed, but before the chart has been rendered.

usePrometheus

Render Prometheus annotations by default. This value can be set at either the deployment or template scope (Container or Service definition). Ignored if not rendering the Service or Container with built-in templates.

use3Scale

Render 3Scale annotations by default. This value can be set at either the deployment or template scope (Service definition). Ignored if not rendering the Service with the built-in template.

9.3. Built-In Deployment Definition Variables

Built-in el-CICD Chart variables that can be used in defining other el-CICD Chart variables or within el-CICD Chart templates.

  • EL_CICD_DEPLOYMENT_TIME_NUM: numerical only time of deployment

  • EL_CICD_DEPLOYMENT_TIME: human readable string time of deployment

  • BASE_OBJ_NAME: Kubernetes object name as listed in objNames matrix, or objName if objNames is empty.

  • OBJ_NAME: Kubernetes object name after value in objNames matrix is processed, or literal string value if directly set.

  • BASE_NAME_SPACE: Kubernetes namespace name as listed in namespaces matrix, or namespace if namespaces is empty.

  • NAME_SPACE: Kubernetes object name after value in namespaces matrix is processed, or literal string value if directly set.

  • HELM_RELEASE_NAME: Helm release name. Corresponds to .Release.Name in a Helm template.

  • HELM_RELEASE_NAMESPACE: Namespace Helm chart is deployed to. Corresponds to .Release.Namespace in a Helm template.

9.4. Built-In Defaults

Default values used by built in el-CICD Chart built-in templates if not otherwise defined.

General Kubernetes objects defaults
  • annotations: empty dictionary

  • labels: empty dictionary

Deployment/Service/Ingress specific defaults
  • deploymentRevisionHistoryLimit: 0

  • imagePullPolicy: "Always"

  • port: 8080

  • protocol: "TCP"

  • ingressRulePath: "/"

  • ingressRulePathType: "Prefix"

Prometheus specific annotation defaults
  • prometheusPort: "9090"

  • prometheusPath: "/metrics"

  • prometheusScheme: "https"

  • prometheusScrape: "false"

  • prometheusProtocol: "TCP"

3Scale specific annotation defaults
  • 3ScaleScheme: "https"

9.5. Standard Helper Attributes

Default helper attributes all el-CICD templates, built-in or free-form, share.

annotations

Kubernetes object annotations. Maps directly to metadata.annotations.

elCicdDefs-*

el-CICD variable maps. Defines maps specific to an el-CICD template, and optional to a profile or objName.

kubeObject

Unless otherwise defined for a particular el-CICD template, default value is true. If false, the Kubernetes apiVersion and kind attributes, and the Kubernetes metadata section, el-CICD Chart will not attempt to render the metadata section. In a free-form template, any of the above is defined, el-CICD will render it as-is without modification. In practice, this also means the annotations and labels helper attributes are ignored.

labels

Kubernetes object labels. Maps directly to metadata.labels.

objName

Fundamental identifier for an el-CICD template. Can be used in the following way:

  • If the template represents a Kubernetes object, will map directly to metadata.name, otherwise, it is just a unique identifier.

  • If objNames is defined, it represents a pattern that each matrix value should be evaluated to for each copied template objName.

objName is mapped to the el-CICD variable OBJ_NAME during rendering for each template. It is also mapped to the el-CICD variable BASE_OBJ_NAME if objNames is not defined.

objNames

List of string that represents a matrix value for el-CICD template objName identifier. Each member of the list will result in a to a copy of the template, and that member is assigned to the objName helper attribute.

namespace

Namespace a rendered el-CICD template should be deployed to. Can be used in the following way:

  • If the template represents a Kubernetes object, will map directly to metadata.namespace, otherwise, it means nothing.

  • If namespaces is defined, it represents a pattern that each matrix value should be evaluated to for each copied template namespace.

namespace is mapped to the el-CICD variable NAMESPACE during rendering for each template. It is also mapped to the el-CICD variable BASE_NAMESPACE if namespaces is not defined.

namespaces

List of string that represents a matrix value for el-CICD template namespace. Each member of the list will result in a to a copy of the template, and that member is assigned to the namespace helper attribute.

template

Arbitrary YAML to render defining the template. Ignored if templateName is defined.

templateName

Name of el-CICD template to apply values to.

templateNames

List of name of el-CICD templates to apply values to. Each member of the list will result in a separate rendering based on the template values.

9.5.1. must*

Every helper attribute below must evaluate to true for the template to render; i.e. they all have equal precedence when determining whether a template should be rendered or not.

mustHaveAnyProfile

An array of strings representing profiles. If any profile in this list is active, the template will be rendered.

mustHaveEveryProfile

An array of strings representing profiles. Every profile in this list must be active for the template to render.

mustNotHaveAnyProfile

An array of strings representing profiles. If any profile in this list is active, the template will not be rendered.

mustNotHaveEveryProfile

An array of strings representing profiles. Every profile in this list must not be active for the template to render.

9.6. Built-in Templates

The following is a comprehensive list of all el-CICD Chart built-in templates and their helper attributes. While the full name of the template is given (e.g. elcicd-kubernetes.cronJob), only the latter part of the name is needed for rendering built-in templates (i.e. cronjob).

Helper attributes specific to the built-in template will be listed under each heading, along with a JSON path-like dot notation of where the value will be rendered; i.e. how the value is used in a rendered Kubernetes resource, if applicable. If a default value is defined internally for the helper attribute, it will noted.

Unless otherwise described here, the content under each helper attribute mirrors the rendered resource definition as described in their reference documentation. Follow the link under each template to its reference documentation for more information.

9.6.1. Kubernetes Authentication Resources

9.6.1.1. elcicd-kubernetes.serviceAccount

RENDERS: ServiceAccount

Helper Rendered to NOTES

automountServiceAccountToken

automountServiceAccountToken

imagePullSecrets

imagePullSecrets

secrets

secrets

9.6.2. Kubernetes Authorization Resources

9.6.2.1. elcicd-kubernetes.clusterRole

RENDERS: ClusterRole

Helper Rendered to NOTES

aggregationRule

aggregationRule

rules

rules

9.6.2.2. elcicd-kubernetes.clusterRoleBinding
Helper Rendered to NOTES

roleRef

roleRef

subjects

subjects

9.6.2.3. elcicd-kubernetes.role

RENDERS: Role

Helper Rendered to NOTES

aggregationRule

aggregationRule

rules

rules

9.6.2.4. elcicd-kubernetes.roleBinding

RENDERS: RoleBinding

Helper Rendered to NOTES

roleRef

roleRef

subjects

subjects

9.6.3. Kubernetes Cluster Resources

9.6.3.1. elcicd-kubernetes.namespace

RENDERS: Namespace

Helper Rendered to NOTES

N/A

No attributes to render

9.6.4. Kubernetes Config and Storage Resources

9.6.4.1. elcicd-kubernetes.configMap

RENDERS: ConfigMap

Helper Rendered to NOTES

binaryData

binaryData

data

data

immutable

immutable

9.6.4.2. elcicd-kubernetes.persistentVolume

RENDERS: PersistentVolume

Helper Rendered to NOTES

accessModes

spec.accessModes

awsElasticBlockStore

spec.awsElasticBlockStore

azureDisk

spec.azureDisk

azureFile

spec.azureFile

cephfs

spec.cephfs

cinder

spec.cinder

claimRef

spec.claimRef

csi

spec.csi

fc

spec.fc

flexVolume

spec.flexVolume

csi

spec.csi

flocker

spec.flocker

gcePersistentDisk

spec.gcePersistentDisk

glusterfs

spec.glusterfs

hostPath

spec.hostPath

iscsi

spec.iscsi

local

spec.local

mountOptions

spec.mountOptions

nfs

spec.nfs

nodeAffinity

spec.nodeAffinity

persistentVolumeReclaimPolicy

spec.persistentVolumeReclaimPolicy

portworxVolume

spec.portworxVolume

quobyte

spec.quobyte

rbd

spec.rbd

scaleIO

spec.scaleIO

storageCapacity*

spec.capacity.storage

storageClassName

spec.storageClassName

storageos

spec.storageos

csi

spec.csi

vsphereVolume

spec.vsphereVolume

volumeMode

spec.volumeMode

9.6.4.3. elcicd-kubernetes.persistentVolumeClaim
Helper Rendered to NOTES

accessModes

spec.accessModes

dataSource

spec.dataSource

dataSourceRef

spec.dataSourceRef

resources

spec.resources

Will override storageRequest and storageLimit

selector

spec.selector

storageClassName

spec.storageClassName

storageRequest

spec.resources.requests.storage

Ignored if resources is defined

storageLimit

spec.resources.limits.storage

Ignored if resources is defined

volumeMode

spec.volumeMode

volumeName

spec.volumeName

9.6.4.4. elcicd-kubernetes.secret

RENDERS: Secret

Helper Rendered to NOTES

data

data

immutable

immutable

stringData

stringData

type

9.6.5. el-CICD Chart Resources

9.6.5.1. elcicd-renderer.copyResource

copyResource is a special el-CICD Chart helper template for copying resources already deployed to a Kubernetes cluster from one namespace to another. The objName should reflect the name of the resource to be copied in the fromNamespace.

Helper Rendered to NOTES

apiVersion

apiVersion

apiVersion of source object; DEFAULT: "v1"

fromNamespace

fromNamespace

Namespace of source object

ignoreAnnotations

ignoreAnnotations

Do not copy annotations from source if "true"

ignoreLabels

ignoreLabels

Do not copy labels from source if "true"

kind

kind

kind of source object

optional

optional

If "true", only output WARNING if not found; otherwise,fail

srcMetadataName

srcMetadataName

DEFAULT: objName

toNamespace

toNamespace

Namespace to copy object to

9.6.6. Kubernetes Policy Resources

9.6.6.1. elcicd-kubernetes.limitRange

RENDERS: LimitRange

Helper Rendered to NOTES

limits

spec.limits

9.6.6.2. elcicd-kubernetes.resourceQuota

RENDERS: ResourceQuota

Helper Rendered to NOTES

hard

spec.hard

scopes

spec.scopes

scopeSelector

spec.scopeSelector

9.6.7. Kubernetes Service Resources

9.6.7.1. elcicd-kubernetes.ingress

RENDERS: Ingress

Helper Rendered to NOTES

defaultBackend

spec.defaultBackend

host

spec.rules[0].host

Ignored if rules is defined
DEFAULT: N/A
elCicdDefaults.ingressHostDomain

ingressClassName

spec.rules.ingressClassName

path

spec.rules[0].http.paths[0].path

Ignored if rules is defined

pathType

spec.rules[0].http.paths[0].pathType

Ignored if rules is defined
DEFAULT: Prefix
elCicdDefaults.ingressRulePathType

port

spec.rules[0].http.paths[0].backend.service.port.number

Ignored if rules is defined
DEFAULT: 8080
elCicdDefaults.port

rules

spec.rules

Will override host, path, pathType, and port

secretName

spec.tls.secretName

Ignored if tls is defined

tls

spec.tls

Will override secretName

9.6.7.2. elcicd-kubernetes.service

RENDERS: Service

Helper Rendered to NOTES

containerPort

spec.containerPort

Helper atribute to define targetPort if used as part of compound template with a container definition
Ignored if targetPort is defined

port

spec.ports[0].name: ${objName}-port
spec.ports[0].port

Rendering will fail if ports is also defined
DEFAULT: 8080
elCicdDefaults.port

ports

spec.ports

Rendering will fail if port is also defined
Overrides containerPort, port, prometheus, protocol, targetPort, and usePrometheus

prometheus.port

spec.ports[1].name: ${objName}-port
spec.ports[1].port

name is hard-coded
DEFAULT: 9090
elCicdDefaults.prometheusPort

prometheus.protocol

spec.ports[1].name: ${objName}-port
spec.ports[1].protocol

name is hard-coded
DEFAULT: TCP
elCicdDefaults.prometheusProtocol

protocol

spec.ports[0].protocol

Ignored if ports is also defined
DEFAULT: TCP
elCicdDefaults.protocol

selector

spec.selector

elcicd.io/selector will be defined in addition to any optional values here

targetPort

spec.targetPort

CAUTION: Overrides containerPort

usePrometheus

spec.ports[1].name: prometheus-port
spec.ports[1].port
spec.ports[1].protocol

Will generate a Prometheus integration port definition from defaults if "true"
DEFAULT port: 9090
elCicdDefaults.prometheusPort
DEFAULT protocol: TCP
elCicdDefaults.prometheusProtocol

9.6.8. General Tool Resources

These resources YAML documents for common Kubernetes associated tools, Kustomize and Helm, are not used for rendering to Kubernetes directly.

9.6.8.1. elcicd-kubernetes.chart-yaml

RENDERS: Helm Chart.yaml

Helper Rendered to NOTES

appVersion

appVersion

deprecated

deprecated

description

description

dependencies

dependencies

home

home

icon

icon

keywords

keywords

kubeVersion

kubeVersion

maintainers

maintainers

sources

sources

type

type

version

version

9.6.8.2. elcicd-kubernetes.kustomization
Helper Rendered to NOTES

generators

generators

resources

resources

transformers

transformers

validators

validators

9.6.9. Kubernetes Workload Helper Resources

The following templates are documented for brevity in the Kubernetes Workload Resources reference documentation, and shouldn’t be used directly in deployment definitions; i.e. never referenced either in templateName or templateNames.

If a Kubernetes resource contains a PodTemplate, the associated el-CICD template may use all podTemplate and container helper attributes in the root of the template definition.
9.6.9.1. elcicd-kubernetes.container

RENDERS: Container
RENDERED TO: [PodTemplate].containers[0]

Containers are rendered in various lists contained in a PodTemplate. If a workload resource contains a PodTemplate, then these helper attributes may be expressed under the root el-CICD template for the first, main container. Other containers in either the main Pod list or other container lists must can otherwise use these helper attributes to define themselves, but should not use the default values.

Helper Rendered to [PodTemplate].containers[0] NOTES

args

args

command

command

containerPort

ports[0].containerPort

DEFAULT: 8080
elCicdDefaults.port
Primary value for containers[0].containerPort

env

env

envFrom

envFrom

envFrom

envFrom

image

image

DEFAULT: elCicdDefaults.image

imagePullPolicy

imagePullPolicy

DEFAULT: Always
elCicdDefaults.imagePullPolicy

lifecycle

lifecycle

limitsCpu

resources.limits.cpu

limitsMemory

resources.limits.memory

livenessProbe

livenessProbe

name

name

DEFAULT: objName
Default is defined for first Container in list only.

port

ports[0].containerPort

Only used if containerPort and targetPort are undefined.

ports

ports

Overrides containerPort, port, prometheus, protocol, targetPort, and usePrometheus

projectedVolumes

SEE: projectedVolumes By Labels

resources.limits

resources.limits

Overrides limitsCpu and limitsMemory

resources.requests

resources.requests

Overrides requestsCpu and requestsMemory

readinessProbe

readinessProbe

requestsCpu

resources.requests.cpu

requestsMemory

resources.requests.memory

startupProbe

startupProbe

securityContext

securityContext

DEFAULT:

allowPrivilegeEscalation: false
capabilities:
  drop:
  - ALL

stdin

stdin

stdinOnce

stdinOnce

targetPort

ports[0].containerPort

Only used if containerPort is undefined.

terminationMessagePolicy

terminationMessagePolicy

tty

tty

usePrometheus

usePrometheus

If true, will generate the following under ports:

- name: prometheus-port
  containerPort: <prometheus.port>
  protocol: <prometheus.protocol>

DEFAULTS:

containerPort: 9090
protocol: TCP

elCicdDefaults.prometheusPort elCicdDefaults.prometheusProtocol

volumeDevices

volumeDevices

volumeMounts

volumeMounts

workingDir

workingDir

9.6.9.2. elcicd-kubernetes.podTemplate

RENDERS: PodTemplate

Kubernetes workload resources that generate Pods all include a PodTemplate. The following helper attributes may all be defined under any of those el-CICD templates.

Helper Rendered to *.template.spec NOTES

activeDeadlineSeconds

activeDeadlineSeconds

affinity

affinity

automountServiceAccountToken

automountServiceAccountToken

containers

containers

containers[0] may be defined at the root of template; otherwise, see elcicd-kubernetes.container for helper attributes for each container in the list.

dnsConfig

dnsConfig

dnsPolicy

dnsPolicy

enableServiceLinks

enableServiceLinks

ephemeralContainers

ephemeralContainers

See elcicd-kubernetes.container for helper attributes for each container in the list

hostAliases

hostAliases

hostIPC

hostIPC

hostNetwork

hostNetwork

hostPID

hostPID

hostname

hostname

imagePullSecret

imagePullSecrets

DEFAULT: elCicdDefaults.imagePullSecrets
Overridden by imagePullSecrets
Helper for easily defining a single secret

imagePullSecrets

imagePullSecrets

DEFAULT: elCicdDefaults.imagePullSecrets

initContainers

initContainers

See elcicd-kubernetes.container for helper attributes for each container in the list

nodeName

nodeName

nodeSelector

nodeSelector

os

os

overhead

overhead

preemptionPolicy

preemptionPolicy

priorityClassName

priorityClassName

priority

priority

DEFAULT: TCP elCicdDefaults.imagePullSecrets

readinessGates

readinessGates

restartPolicy

restartPolicy

runtimeClassName

runtimeClassName

schedulerName

schedulerName

securityContext

securityContext

DEFAULT:

runAsNonRoot: true
seccompProfile:
  type: RuntimeDefault

serviceAccount

serviceAccount

serviceAccountName

serviceAccountName

setHostnameAsFQDN

setHostnameAsFQDN

shareProcessNamespace

shareProcessNamespace

subdomain

subdomain

terminationGracePeriodSeconds

terminationGracePeriodSeconds

tolerations

tolerations

topologySpreadConstraints

topologySpreadConstraints

volumes

volumes

9.6.9.3. elcicd-kubernetes.jobSpec

RENDERS: JobSpec

Job related workload resources, elcicd-kubernetes.cronJob and elcicd-kubernetes.job, contain JobSpecs. JobSpecs wrap PodTemplates, and the following helper attributes may be used on the root of the el-CICD templates.

Helper Rendered to *.spec NOTES

activeDeadlineSeconds

activeDeadlineSeconds

backoffLimit

backoffLimit

completionMode

completionMode

completions

completions

manualSelector

manualSelector

parallelism

parallelism

podFailurePolicy

podFailurePolicy

<podTemplate>

template.spec

See elcicd-kubernetes.podTemplate for further helper attributes

restartPolicy

restartPolicy

DEFAULT: Never

suspend

suspend

ttlSecondsAfterFinished

ttlSecondsAfterFinished

9.6.10. Kubernetes Workload Resources

Except for the horizontalPodAutoscaler, the following el-CICD templates all contains a PodTemplate, and therefore[cols="1,2,4"] may make use of the helper attributes defined up in both elcicd-kubernetes.podTemplate and elcicd-kubernetes.container.

Templates with PodTemplates were designed to integrate easily with both the elcicd-kubernetes.service and elcicd-kubernetes.ingress el-CICD templates to create compound templates.
9.6.10.1. elcicd-kubernetes.cronJob

RENDERS: CronJob

Helper Rendered to NOTES

concurrencyPolicy

concurrencyPolicy

failedJobsHistoryLimit

failedJobsHistoryLimit

<jobSpec>

template.spec

See elcicd-kubernetes.jobSpec for further helper attributes

parallelism

parallelism

schedule

schedule

startingDeadlineSeconds

startingDeadlineSeconds

successfulJobsHistoryLimit

successfulJobsHistoryLimit

ttlSecondsAfterFinished

ttlSecondsAfterFinished

9.6.10.2. elcicd-kubernetes.daemonSet

RENDERS: DaemonSet

Helper Rendered to NOTES

minReadySeconds

spec.minReadySeconds

<podTemplate>

spec.template.spec

See elcicd-kubernetes.podTemplate for further helper attributes

revisionHistoryLimit

spec.revisionHistoryLimit

updateStrategy

spec.updateStrategy

9.6.10.3. elcicd-kubernetes.deployment

RENDERS: Deployment

Helper Rendered to NOTES

minReadySeconds

spec.minReadySeconds

<podTemplate>

spec.template.spec

See elcicd-kubernetes.podTemplate for further helper attributes

progressDeadlineSeconds

spec.progressDeadlineSeconds

revisionHistoryLimit

spec.revisionHistoryLimit

DEFAULT: 0
elCicdDefaults.deploymentRevisionHistoryLimit

rollingUpdateMaxSurge

spec.strategy.rollupdate.maxSurge

NOTE: strategyType must be RollingUpdate
DEFAULT: elCicdDefaults.rollingUpdateMaxSurge

rollingUpdateMaxUnavailable

spec.strategy.rollupdate.maxUnavailable

NOTE: strategyType must be RollingUpdate
DEFAULT: elCicdDefaults.rollingUpdateMaxUnavailable

strategyType

spec.strategy.type

9.6.10.4. elcicd-kubernetes.horizontalPodAutoscaler
Helper Rendered to NOTES

behavior

spec.behavior

maxReplicas

spec.maxReplicas

metrics

spec.metrics

minReplicas

spec.minReplicas

scaleTargetRef

spec.scaleTargetRef

DEFAULTS:

apiVersion: apps/v1
kind: Deployment
apiVersion: $<OBJ_NAME>

Defaults are rendered for any missing key of the scaleTargetRef

9.6.10.5. elcicd-kubernetes.job

RENDERS: Job

Helper Rendered to NOTES

<jobSpec>

spec.template.spec

See elcicd-kubernetes.jobSpec for further helper attributes

9.6.10.6. elcicd-kubernetes.pod

RENDERS: Pod

Helper Rendered to NOTES

<podTemplate>

spec.template.spec

See elcicd-kubernetes.podTemplate for further helper attributes

9.6.10.7. elcicd-kubernetes.statefulSet

RENDERS: StatefulSet

Helper Rendered to NOTES

minReadySeconds

spec.minReadySeconds

ordinals

spec.ordinals

persistentVolumeClaimRetentionPolicy

spec.persistentVolumeClaimRetentionPolicy

podManagementPolicy

spec.podManagementPolicy

<podTemplate>

spec.template.spec

See elcicd-kubernetes.podTemplate for further helper attributes

replicas

spec.replicas

revisionHistoryLimit

spec.revisionHistoryLimit

updateStrategy

spec.updateStrategy

volumeClaimTemplates

spec.volumeClaimTemplates