The source code of the module and its assembly rules must be located in a directory with a certain structure. The best analog is a Helm chart.
Not all module folders and files are required. In short, you can use the following guidelines:
- Create a module.yaml file to describe the module metadata.
- In the templates folder, place the Helm templates that will be used in the cluster.
If you want the objects created by the module to change their behavior depending on any module parameters, define the necessary parameters in the specification and use them in the templates.
- In the images folder, place instructions for building container images used by the module.
If the templates only use addresses of external images, you don`t need to create a folder.
- If the module should respond to events or interact with the Kubernetes API, you need to create hooks that should be placed in the hooks folder.
- Place the module documentation in the docs folder. If the module documentation is missing, the module will not appear in the list of modules in the documentation web interface in the cluster.
- If the module has auxiliary Helm charts, place them in the charts folder.
- If the module needs to create custom resources (CRD), place their specifications in the crds folder.
There is a repository containing the sample module template. We recommend you start your module development with it.
Further down this page you will find a more detailed description of the module directory and file structure.
Example module folder structure...
Example module folder structure containing build and publish rules using GitHub Actions:
📁 my-module/
├─ 📁 .github/
│ ├─ 📁 workflows/
│ │ ├─ 📝 build_dev.yaml
│ │ ├─ 📝 build_prod.yaml
│ │ ├─ 📝 checks.yaml
│ │ ├─ 📝 deploy_dev.yaml
│ │ └─ 📝 deploy_prod.yaml
├─ 📁 .werf/
│ ├─ 📁 workflows/
│ │ ├─ 📝 bundle.yaml
│ │ ├─ 📝 images.yaml
│ │ ├─ 📝 images-digest.yaml
│ │ ├─ 📝 python-deps.yaml
│ │ └─ 📝 release.yaml
├─ 📁 charts/
│ └─ 📁 helm_lib/
├─ 📁 crds/
│ ├─ 📝 crd1.yaml
│ ├─ 📝 doc-ru-crd1.yaml
│ ├─ 📝 crd2.yaml
│ └─ 📝 doc-ru-crd2.yaml
├─ 📁 docs/
│ ├─ 📝 README.md
│ ├─ 📝 README.ru.md
│ ├─ 📝 EXAMPLES.md
│ ├─ 📝 EXAMPLES.ru.md
│ ├─ 📝 CONFIGURATION.md
│ ├─ 📝 CONFIGURATION.ru.md
│ ├─ 📝 CR.md
│ ├─ 📝 CR.ru.md
│ ├─ 📝 FAQ.md
│ ├─ 📝 FAQ.ru.md
│ ├─ 📝 ADVANCED_USAGE.md
│ └─ 📝 ADVANCED_USAGE.ru.md
├─ 📁 hooks/
│ ├─ 📝 hook1.py
│ └─ 📝 hook2.py
├─ 📁 images/
│ ├─ 📁 nginx
│ │ └─ 📝 Dockerfile
│ └─ 📁 backend
│ └─ 📝 werf.inc.yaml
├─ 📁 lib/
│ └─ 📁 python/
│ └─ 📝 requirements.txt
├─ 📁 openapi/
│ ├─ 📁 conversions
│ │ ├─ 📁 testdata
│ │ │ ├─ 📝 v1-1.yaml
│ │ │ └─ 📝 v2-1.yaml
│ │ ├─ 📝 conversions_test.go
│ │ └─ 📝 v2.yaml
│ ├─ 📝 config-values.yaml
│ ├─ 📝 doc-ru-config-values.yaml
│ └─ 📝 values.yaml
├─ 📁 templates/
│ ├─ 📝 a.yaml
│ └─ 📝 b.yaml
├─ 📝 .helmignore
├─ 📝 Chart.yaml
├─ 📝 module.yaml
├─ 📝 werf.yaml
└─ 📝 werf-giterminism.yaml
charts
The /charts
directory contains Helm helper charts used when rendering templates.
Deckhouse Kubernetes Platform (DKP) has its own library for working with templates called lib-helm. You can read about the library’s features in the lib-helm repository. To add the library to the module, download the tgz-archive with the appropriate release and move it to the /charts
directory of the module.
crds
This directory contains CustomResourceDefinitions (CRDs) used by the module components. CRDs are updated every time the module is started, if there are updates.
To render CRDs from the /crds
directory in the site documentation or documentation module in the cluster, follow these steps:
- create a translation file with a structure identical to the original resource file:
- in it, keep only the
description
parameters containing the translation text; - use the
doc-ru-
prefix in the name: e.g.,/crds/doc-ru-crd.yaml
for/crds/crd.yaml
.
- in it, keep only the
- create
/docs/CR.md
and/docs/CR.ru.md
files.
docs
The /docs
directory contains the module documentation:
-
README.md
— this file describes what the module is for, what problem it solves and outlines the general architectural principles.The (front matter) file metadata as a YAML structure must present in all language versions of the file. You can use the following parameters in the metadata:
title
— (recommended) The title of the module description page, for example, “Deckhouse web admin console”. It is also used in navigation iflinkTitle
parameter is not specified.menuTitle
— (recommended) The name of the module to show in the menu on the left sidebar of the page, e.g., “Deckhouse Admin”. If not set, the name of the directory or repository is used, e.g.deckhouse-admin
.linkTitle
— (optional) Alternative title for navigation if, for example, thetitle
is very long. If not set, thetitle
parameter is used.description
— (recommended) A short unique description of the page content (up to 150 characters). It should not repeat the `title’. Goes on with the meaning of the title and reveals it in more detail. It is used during generation of preview links and indexing by search engines, e.g., “The module allows you to fully manage your Kubernetes cluster through a web interface with only mouse skills.”d8Edition
— (optional)ce/be/se/ee
. The minimum edition in which the module is available. The default isce
.moduleStatus
— (optional)experimental
. The status of the module. If a module is labeled asexperimental
, a warning that the code is unstable is displayed on its pages. Also, a special bar in the menu is displayed.
Metadata example...
--- title: "Deckhouse administrator web console" menuTitle: "Deckhouse Admin" description: "The module allows you to fully manage your Kubernetes cluster through a web interface with only mouse skills." ---
-
The
EXAMPLES.md
file contains examples of module configuration with description.The (front matter) file metadata as a YAML structure must present in all language versions of the file. You can use the following parameters in the metadata:
title
– (recommended) The title of the page, e.g.,Examples
. It is also used in navigation if there is nolinkTitle
.description
– (recommended) A short unique description of the page content (up to 150 characters). It should not repeat the `title’. Goes on with the meaning of the title and reveals it in more detail. It is used during generation of preview links and indexing by search engines, e.g., “Examples of storing secrets in a neural network and automatically substituting them into thoughts when communicating.”linkTitle
– (optional) Alternative title for navigation if, for example, thetitle
is very long. If not set, thetitle
parameter is used.
Metadata example...
--- title: "Examples" description: "Examples of storing secrets in a neural network with automatic substitution into thoughts when communicating." ---
-
FAQ.md
– the file contains frequently asked questions related to module operation, e.g., “What scenario should I choose: A or B?”.The (front matter) file metadata as a YAML structure must present in all language versions of the file. You can use the following parameters in the metadata:
title
– (recommended) The title of the page.description
– (recommended) A short unique description of the page content (up to 150 characters).linkTitle
– (optional) Alternative title for navigation if, for example, thetitle
is very long. If not set, thetitle
parameter is used.
Metadata example...
--- title: "FAQs" description: "Frequently asked questions." ---
-
ADVANCED_USAGE.md
— this file contains instructions for debugging the module.The (front matter) file metadata as a YAML structure must present in all language versions of the file. You can use the following parameters in the metadata:
title
– (recommended) The title of the page.description
– (recommended) A short unique description of the page content (up to 150 characters).linkTitle
– (optional) Alternative title for navigation if, for example, thetitle
is very long. If not set, thetitle
parameter is used.
Metadata example...
--- title: "Module debugging" description: "This section covers all the steps for debugging the module." ---
-
Manually add
CR.md
andCR.ru.md
, the files for generating resources from the/crds/
directory.Metadata example...
--- title: "Custom resources" ---
-
Manually add
CONFIGURATION.md
, the file to create resources from/openapi/config-values.yaml
and/openapi/doc-<LANG>-config-values.yaml
.Metadata example...
--- title: "Module settings" ---
All images, PDF files and other media files should be stored in the /docs
directory or its subdirectories (e.g, /docs/images/
). All links to files should be relative.
You need a file with the appropriate suffix for each language, e.g. image1.jpg
and image1.ru.jpg
. Here’s how you can include images in your document:
[image1](image1.jpg)
in an English-language document;[image1](image1.ru.jpg)
in a Russian-language document.
hooks
The /hooks
directory contains the module’s hooks. A hook is an executable file executed in response to an event. Hooks are also used by the module for dynamic interaction with Kubernetes API. For example, they can be used to handle events related to the creation or deletion of objects in a cluster.
Get to know the concept of hooks before you start developing your own hook. You can use the Python library by the Deckhouse team to speed up the development of hooks.
Hook requirements:
- The hook must be written in the Python language.
- When run with the
--config
parameter, the hook must output its configuration in YAML format. - When run without parameters, the hook must perform its intended action.
The hook files must be executable. Add the appropriate permissions using the chmod +x <path to the hook file>
command.
You can find Python hook examples in the module template repository. Go hook examples can be found in the SDK.
images
The /images
directory contains instructions for building module container images. The first level contains directories for files used to create the container image, the second level contains the building context.
There are two ways to define a container image:
- Dockerfile — this file contains commands for building images. To build an application from source code, copy it next to the Dockerfile and include it in the image using the
COPY
command. - The
werf.inc.yaml
file, which is the same as the image definition section inwerf.yaml
.
The image name matches the directory name for this module, written in camelCase notation starting with a small letter. For example, the directory /images/echo-server
corresponds to the image name echoServer
.
The built images have content-based tags that can be used when building other images. To use content-based image tags, enable the lib-helm library. You can also use other features of the helm_lib library of Deckhouse Kubernetes Platform.
Below is an example of using a content-based image tag in a Helm chart:
image: {{ include "helm_lib_module_image" (list . "<image name>") }}
openapi
conversions
The /openapi/conversions
directory contains module parameter conversion files and their tests.
Module parameter conversions allow you to convert the OpenAPI specification of module parameters from one version to another. Conversions may be necessary when a parameter is renamed or moved to a different location in a new version of the OpenAPI specification.
Each conversion can only be performed between two consecutive versions (e.g., from the first to the second one). There can be several conversions, and the chain of conversions must cover all versions of the parameter specification with no “gaps”.
The conversion file is an arbitrarily named YAML file of the following format:
version: N # The version number to convert to.
conversions: [] # A set of jq expressions to transform data from the previous version.
Below is an example of a module parameter conversion file where in version 2, the .auth.password
parameter has been removed:
version: 2
conversions:
- del(.auth.password) | if .auth == {} then del(.auth) end
Conversion tests
You can use the conversion.TestConvert
function to write conversion tests. It receives the following parameters:
- path to the source configuration file (i.e., the version before the conversion);
- path to the resulting configuration file (i.e., the version after the conversion).
An example of a conversion test.
config-values.yaml
This file is required to validate the module parameters that the user can configure via ModuleConfig.
To render the schema in the documentation on the site or in the documentation module in the cluster, create:
- the
doc-ru-config-values.yaml
file with a structure similar to that of theconfig-values.yaml
file. Keep only the translated description parameters in thedoc-ru-config-values.yaml
file; - the
/docs/CONFIGURATION.md
and/docs/CONFIGURATION.ru.md
files to enable rendering of data from the/openapi/config-values.yaml
and/openapi/doc-ru-config-values.yaml
files.
An example of a /openapi/config-values.yaml
schema with a single configurable nodeSelector
parameter:
type: object
properties:
nodeSelector:
type: object
additionalProperties:
type: string
description: |
The same as the Pods' `spec.nodeSelector` parameter in Kubernetes.
If the parameter is omitted or `false`, `nodeSelector` will be determined
[automatically](https://deckhouse.io/products/kubernetes-platform/documentation/v1/#advanced-scheduling).</code>
An example of the /openapi/doc-ru-config-values.yaml
file:
properties:
nodeSelector:
description: |
English description. Markdown markup.</code>
values.yaml
This file is required for validating the source data when rendering templates without using extra Helm chart functions. Its closest analogs are Helm’s schema files.
You can automatically add parameter validation from config-values.yaml
to values.yaml
. In this case, the basic values.yaml
looks as follows:
x-extend:
schema: config-values.yaml
type: object
properties:
internal:
type: object
default: {}
templates
The /templates
directory contains Helm templates.
-
Use the path
.Values.<moduleName>
to access module settings in templates, and.Values.global
for global settings. The module name is converted to camelCase notation. -
To facilitate working with templates, use lib-helm, which is a set of extra functions that make it easier to work with global and module values.
-
Accesses to the registry from the ModuleSource resource are available at the
.Values.<moduleName>.registry.dockercfg
path. -
To use these functions to pull image pools in controllers, create a secret and add it to the corresponding parameter:
"imagePullSecrets": [{"name":"registry-creds"}]
.apiVersion: v1 kind: Secret metadata: name: registry-creds type: kubernetes.io/dockerconfigjson data: .dockerconfigjson: {{ .Values.<moduleName>.registry.dockercfg }}
A module can have parameters with which it can alter its behavior. Module parameters and their validation scheme are described in OpenAPI-schemes in /openapi
directory.
The settings are stored in two files: config-values.yaml
and values.yaml
.
You can find an example of an OpenAPI schema in module template.
.helmignore
.helmignore
allows you to exclude files from the Helm release. In case of DKP modules, directories /crds
, /images
, /hooks
, /openapi
must be added to .helmignore
to avoid exceeding 1 Mb limit of Helm release size.
Chart.yaml
This is a file for a chart, similar to Chart.yaml
in Helm. It must contain at least a name
parameter with the module name and a version
parameter with the version.
You don’t need to create this file, Deckhouse will create it automatically.
An example:
name: echoserver
version: 0.0.1
dependencies:
- name: deckhouse_lib_helm
version: 1.38.0
repository: https://deckhouse.github.io/lib-helm
module.yaml
The module.yaml
file in the root of the module folder contains the module’s metadata.
The file might not be present, but it is recommended to fill it in. Most of the metadata will be available in the Module object in the cluster. The Module object will be created automatically after the module source (resource ModuleSource) is configured and synchronization is successful.
Parameters that can be used in module.yaml
:
description
— String. Arbitrary text description of the module’s purpose. Will be displayed in the documentation.disable
— Object. Parameters related to the behavior when disabling a module.confirmation
— Boolean. Require confirmation when disabling a module.message
— String. Message with information about what will happen when disabling a module.
If confirmation is required to disable a module (the confirmation
parameter is set to true
), then disabling the module will only be possible if the modules.deckhouse.io/allow-disabling=true
label is set on the corresponding ModuleConfig object. If such a label is not present, then a warning will be displayed when attempting to disable the module, with the message from the message
parameter added.
name
— String, mandatory parameter. The name of the module in Kebab Case. For example,echo-server
.requirements
— Object. Dependencies of a pod — a set of conditions that must be met for Deckhouse Kubernetes Platform (DKP) to be able to start the pod.bootstrapped
— Boolean. Pod dependency on cluster installation status (for built-in DKP pods only).deckhouse
— String. Pod dependency on Deckhouse Kubernetes Platform version that the pod is compatible with.kubernetes
— String. Pod dependency on Kubernetes version that the pod is compatible with.modules
— Object. Module dependency on the version of other modules.stage
— String. Module lifecycle stage. Possible values:Sandbox
,Incubating
,Graduated
, orDeprecated
.tags
— Array of strings. List of additional module tags. Tags are converted to Module object labels according to the templatemodule.deckhouse.io/<TAG>=""
(where<TAG>
is the tag name).
For example, if you specify tags: ["test", "myTag"]
, then the corresponding Module object in the cluster will be assigned the labels module.deckhouse.io/test=""
and module.deckhouse.io/myTag=""
.
-
weight
— Number. The weight of the module. Used to control the order in which the module is launched compared to other modules. The lower the weight, the earlier the module will be launched. Default: 900.The order in which a module is launched can also be influenced by the list of module dependencies.
Example of metadata description for the hello-world
module:
name: hello-world
tags: ["test", "myTag"]
weight: 960
stage: "Sandbox"
description: "The module to say hello to the world."
requirements:
deckhouse: ">= 1.61"
kubernetes: ">= 1.27"
bootstrapped: true
disable:
confirmation: true
message: "Disabling this module will delete all resources, created by the module."