This section provides an example of creating a helloworld module based on module template and an adaptation of the hello-world Helm-chart.

Preparing module source code and building

  1. Install the tools you will need:
  2. Fork the module template repository or copy it.

    git clone git@github.com:deckhouse/modules-template.git helloworld \
      && cd helloworld
    
  3. Enter the name of the module in the module.yaml file.

    We will use the helloworld module name in this example, but you can use any name you like. For this, replace ‘helloworld’ in the commands and in your repo’s name with the one you prefer.

    Note that the module name may differ depending on the command. In may be written in kebab-case as well as camelCase. If you use a custom module name, make sure to modify it accordingly.

    Run the following command to add the module name to the module.yaml file or edit it manually:

    sed -i -e 's/^name:.*$/name: helloworld/' module.yaml
    
  4. Clone the hello-world chart source code into a temporary directory.

    git clone https://github.com/giantswarm/hello-world-app .tmp-chart
    
  5. Copy the chart templates to the templates directory of the module (make sure to empty it beforehand).

    rm -rf templates/*
    cp -fR .tmp-chart/helm/hello-world/templates/* templates/
    cp .tmp-chart/helm/hello-world/values.yaml values.yaml
    
  6. Replace the .Values path in the chart templates with .Values.helloworld.

    This is due to the architectural feature of addon-operator. You have to stick to it to be able to access module values.

    sed -i -e 's/.Values/.Values.helloworld/g' $(find templates/ -type f)
    
  7. Add the OpenAPI schema of the module settings.

    The module parameters are specified in the OpenAPI schema in the openapi directory. Execute the following command to convert the JSON schema of the chart parameters to the OpenAPI schema of the module:

    jq 'walk(
       if type == "object" and .type == "object" and (keys | length) == 1
       then . + {additionalProperties: true}
       else .
       end
    )' .tmp-chart/helm/hello-world/values.schema.json > openapi/config-values.yaml
    
  8. Define a rule for building an application container image.

    The rules for building application container images must reside in a subdirectory of the images directory of the module. Run the following commands to create an application image directory and a Dockerfile with the image build rules:

    rm -rf images/*
    mkdir images/helloworld
    echo "FROM quay.io/giantswarm/helloworld:0.2.0" > images/helloworld/Dockerfile
    
  9. Replace the image in the Deployment manifest with the Deckhouse Kubernetes Platform library helper. This will allow you to use the current content-based image tag.

    sed -Ei 's/image\:(.*)/image: {{ include "helm_lib_module_image" (list . "helloworld") }}/g' templates/deployment.yaml
    
  10. Delete module hooks, CRDs, and temporary files.

    In our example, hooks and CustomResourceDefinitions are not used. Run the following commands to clear the hooks and crds directories:

    rm -rf hooks/
    rm -rf crds/
    rm -rf .tmp-chart
    
  11. Set up CI/CD.

    The project template in the .github directory contains pre-built GitHub Actions workflow files that implement a simple scheme for building and publishing a module using the GitHub Packages registry (ghcr.io). Module artifacts will be pushed to ghcr.io/<OWNER>/modules/, which will be the module source. Make changes to the workflow files if the suggested option does not work for you.

    Do the following in the properties of your project on GitHub to make the module workflow run smoothly:

    • Open the Settings -> Actions -> General page.
    • Enable Read and write permissions in the Workflow permissions section.
  12. Commit the changes to the repository (specify the address of the module’s Git repository).

    git add .
    git commit -m "Initial Commit"
    git push --set-upstream origin <GIT_REPO_URL>
    
  13. Confirm that the module was built successfully.

    Go to the Actions section of the module repository and select Build from the workflow list on the left. The workflow that starts after you have executed the git push command at the previous step is expected to run successfully.

    An example:

    An example of module assembly workflow

Publishing the module to the release channel

Here’s how you can publish version v0.0.1 of the module to the Alpha release channel:

  1. Create a new release v0.0.1 of the module in the GitHub repository or add the v0.0.1 tag.

  2. Go to the Actions section of the module repository and select Deploy in the workflow list on the left.

  3. Click on the Run workflow drop-down list on the right of the page and select alpha. Enter the v0.0.1 tag in the tag input field. Click the Run workflow button.

    An example of starting the workflow to publish a module

  4. Confirm that the module publishing workflow has completed successfully.

You can now access your module in a cluster managed by Deckhouse Kubernetes Platform.

Enabling a module in a cluster

The following is the sequence of steps to enable the helloworld in a cluster managed by Deckhouse Kubernetes Platform.

  1. Create an access token in the GitHub repository with permissions to handle GitHub Packages.
  2. Generate an authentication string to access the GitHub Packages container registry in dockerconfigjson format; insert your GitHub username (or organization) and access token in the angle brackets below:

    base64 -w0 <<EOF
    {
      "auths": {
        "ghcr.io": {
          "auth": "$(echo -n '<OWNER>:<TOKEN>' | base64 -w0)"
        }
      }
    }
    EOF
    
  3. Create a ModuleSource resource in the cluster (specify the container registry address and authentication string).

    kubectl apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleSource
    metadata:
      name: ghcr
    spec:
      registry:
        # Insert your GitHub username (or organization), e.g., ghcr.io/octocat/modules.
        repo: ghcr.io/<!OWNER>/modules
        # Paste the authentication string for accessing GitHub Packages that you got in the previous step
        dockerCfg: <!REGISTRY_CREDENTIALS>
    EOF
    

    Note that it may take a few seconds to synchronize data after a resource has been created.

  4. Check the list of available modules

    kubectl  get ms ghcr -o jsonpath='{.status.modules[*].name}'
    

    The list should only contain the helloworld module.

  5. Create a ModuleUpdatePolicy resource that defines the module update policy.

    Run the following command to create an update policy for the helloworld-policy module with the Alpha release channel and Auto update mode:

    kubectl apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha1
    kind: ModuleUpdatePolicy
    metadata:
      name: helloworld-policy
    spec:
      moduleReleaseSelector:
        labelSelector:
          matchLabels:
            source: ghcr
      releaseChannel: Alpha
      update:
        mode: Auto
    EOF
    
  6. Check the ModuleSource resource (the status should have no errors and list the available modules):

    kubectl get ms ghcr -o yaml
    
  7. Confirm that new ModuleRelease resources have been created for the module:

    kubectl get mr
    

    An example of output:

    $ kubectl get mr
    NAME                                PHASE        UPDATE POLICY        TRANSITIONTIME   MESSAGE
    helloworld-v0.0.1                   Deployed     helloworld-policy    22m            
    
  8. If the release has been successfully installed, wait for the Deckhouse Kubernetes Platform pod to restart.

    kubectl -n d8-system get pod -l app=deckhouse
    
  9. Enable the module by running the following command:

    kubectl -ti -n d8-system exec svc/deckhouse-leader -c deckhouse -- deckhouse-controller module enable helloworld
    

    After a while, the module objects will be available in the cluster.

    If you run into errors while starting the module, check the DKP log:

    kubectl -n d8-system logs deploy/deckhouse -f | jq -rc '.msg'
    

or check the status of the DKP queue:

   kubectl -n d8-system exec svc/deckhouse-leader -c deckhouse -- deckhouse-controller queue list