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 module
    NAME       WEIGHT   SOURCE   PHASE       ENABLED   READY
    ...
    helloworld                   Available   False     False     
    ...
    
  5. Create a ModuleUpdatePolicy resource that defines the module update policy.

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

    kubectl apply -f - <<EOF
    apiVersion: deckhouse.io/v1alpha2
    kind: ModuleUpdatePolicy
    metadata:
      name: helloworld-policy
    spec:
      releaseChannel: Alpha
      update:
        mode: Auto
    EOF
    
  6. Create a ModuleConfig where you specify the module source (the source parameter), the update policy (the updatePolicy parameter), and set the enabled parameter to true:

    kubectl apply -f - <<EOF
       apiVersion: deckhouse.io/v1alpha1
       kind: ModuleConfig
       metadata:
         name: helloworld
       spec:
          enabled: true
          source: ghcr
          updatePolicy: helloworld-policy
    
  7. Check the ModuleSource (the status should have no errors and list the available modules):

    kubectl get ms ghcr -o yaml
    
  8. Confirm that the new ModuleRelease objects 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            
    
  9. 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
    

    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

Migration of ModuleUpdatePolicy to version v1alpha2

If there is a ModuleUpdatePolicy of version v1alpha1 in the cluster, the following migration steps to version v1alpha2 must be performed:

If any ModuleUpdatePolicy of version v1alpha1 in the cluster defines moduleReleaseSelector, alerts ModuleHasDeprecatedUpdatePolicy will be triggered in the monitoring system for all modules that match this selector. In this case, follow these steps to migrate to version v1alpha2 of ModuleUpdatePolicy:

  • Specify the update policy for the corresponding modules in the moduleConfig properties.updatePolicy parameter.
  • Execute the following command, specifying the required ModuleUpdatePolicy:

    kubectl patch moduleupdatepolicies.v1alpha1.deckhouse.io <MUP_NAME> --type='json' \
      -p='[{"op": "replace", "path": "/spec/moduleReleaseSelector/labelSelector/matchLabels", "value": {"": ""}}]'