Grouping Instances#

Sometimes Instances become quite large with many components. If you work on them with multiple team members, you end up having to synchronize the deployment of the Instances.

You can easily rip large Instances apart using the group tag, joining multiple Instances into one group and making sure the NetworkPolicies are opened to pods from other Instances within the Instance Group.

global:
  instance:
    # -- despite the instance name, all components within this group will be prefixed
    # with the group (unless the group name and the environment name are not identical)
    # Also this makes sure the network policies are acting on the group, not on the instance.
    group: "sample-group"

You can query the instance group in your code with .instance.group.

Example: We build multiple Instances in one group:

  • sample-group-backend
    • Database
    • nstl
    • rs
  • sample-group-middleware
    • nappl
    • application(s)
  • sample-group-frontend
    • web
    • cmis

Portainer is showing the group as if it were an single instance:

Portainer

The nplus UI is showing the instances of the group:

nplus Web Monitoring

And the nplus CLI is also showing single instances:

% kubectl get nscale
NAME                                                                 INSTANCE                         COMPONENT       TYPE            VERSION    STATUS
component.nplus.cloud/sample-group-cmis                              sample-group-frontend            cmis            cmis            9.2.1200   healthy
component.nplus.cloud/sample-group-database                          sample-group-backend             database        database        16         healthy
component.nplus.cloud/sample-group-nappl                             sample-group-middleware          nappl           core            9.2.1302   healthy
component.nplus.cloud/sample-group-rs                                sample-group-backend             rs              rs              9.2.1201   healthy
component.nplus.cloud/sample-group-web                               sample-group-frontend            web             web             9.2.1300   healthy

NAME                                                  HANDLER   VERSION    TENANT   STATUS
instance.nplus.cloud/sample-group-backend             manual    9.2.1302            healthy
instance.nplus.cloud/sample-group-frontend            manual    9.2.1302            healthy
instance.nplus.cloud/sample-group-middleware          manual    9.2.1302            healthy

Files#

Download all files of this sample

backend.yaml#

components:
  nappl: false
  nappljobs: false
  web: false
  mon: false
  rs: true
  ilm: false
  cmis: false
  database: true
  nstl: true
  nstla: false
  nstlb: false
  pipeliner: false
  application: false
  administrator: false
  webdav: false
  rms: false
  pam: false
global:
  instance:
    # -- despite the instance name, all components within this group will be prefixed
    # with the group (unless the group name and the environment name are not identical)
    # Also this makes sure the network policies are acting on the group, not on the instance.
    group: "sample-group"

# -- We need to make sure, that only ONE instance is creating the default network policies
# and also the certificate for the group.
# All other group members are using the central one
override:
  ingress:
    # -- this overrides any issuers and makes sure not certificate request is generated for
    # cert-manager
    issuer: null
    # -- since no issuer is set, the default would be to generate a self signed certificate.
    # We need to prevent that
    createSelfSignedCertificate: false
  security:
    cni:
      # -- Even if we globally switched the creation of network policies on, we do not want that
      # for this instance (and the instance chart only: Subcharts might still create the policies.
      # If you want to force that off as well, override in global)
      createNetworkPolicy: false

build.sh#

#!/bin/bash
#
# This sample script builds the example as described. It is also used to build the test environment in our lab,
# so it should be well tested.
#

# Make sure it fails immediately, if anything goes wrong
set -e

# -- ENVironment variables:
# CHARTS: The path to the source code
# DEST: The path to the build destination
# SAMPLE: The directory of the sample
# NAME: The name of the sample, used as the .Release.Name
# KUBE_CONTEXT: The name of the kube context, used to build this sample depending on where you run it against. You might have different Environments such as lab, dev, qa, prod, demo, local, ...

# Check, if we have the source code available
if [ ! -d "$CHARTS" ]; then
    echo "ERROR Building $SAMPLE example: The Charts Sources folder is not set. Please make sure to run this script with the full Source Code available"
    exit 1
fi
if [ ! -d "$DEST" ]; then
    echo "ERROR Building $SAMPLE example: DEST folder not found."
    exit 1
fi
if [ ! -d "$CHARTS/instance" ]; then
    echo "ERROR Building $SAMPLE example: Chart Sources in $CHARTS/instance not found. Are you running this script as a subscriber?"
    exit 1
fi

# Set the Variables
SAMPLE="group"
NAME="sample-$SAMPLE"

# Output what is happening
echo "Building $NAME"

# Create the manifest
mkdir -p $DEST/instance-group
helm template --debug \
     --values $SAMPLES/group/backend.yaml \
     --values $SAMPLES/environment/$KUBE_CONTEXT.yaml \
     --values $SAMPLES/resources/$KUBE_CONTEXT.yaml \
     $NAME-backend $CHARTS/instance > $DEST/instance-group/$SAMPLE-backend.yaml

helm template --debug \
     --values $SAMPLES/group/middleware.yaml \
     --values $SAMPLES/environment/$KUBE_CONTEXT.yaml \
     --values $SAMPLES/resources/$KUBE_CONTEXT.yaml \
     $NAME-middleware $CHARTS/instance > $DEST/instance-group/$SAMPLE-middleware.yaml

helm template --debug \
     --values $SAMPLES/group/frontend.yaml \
     --values $SAMPLES/environment/$KUBE_CONTEXT.yaml \
     --values $SAMPLES/resources/$KUBE_CONTEXT.yaml \
     $NAME-frontend $CHARTS/instance > $DEST/instance-group/$SAMPLE-frontend.yaml

frontend.yaml#

components:
  nappl: false
  nappljobs: false
  web: true
  mon: false
  rs: false
  ilm: false
  cmis: true
  database: false
  nstl: false
  nstla: false
  nstlb: false
  pipeliner: false
  application: false
  administrator: false
  webdav: false
  rms: false
  pam: false
global:
  instance:
    # -- despite the instance name, all components within this group will be prefixed
    # with the group (unless the group name and the environment name are not identical)
    # Also this makes sure the network policies are acting on the group, not on the instance.
    group: "sample-group"

# Notice, that we do NOT override anything here, are we use this instance as the master for the group.

middleware.yaml#

components:
  nappl: true
  nappljobs: false
  web: false
  mon: false
  rs: false
  ilm: false
  cmis: false
  database: false
  nstl: false
  nstla: false
  nstlb: false
  pipeliner: false
  application: true
  administrator: false
  webdav: false
  rms: false
  pam: false

application:
  docAreas:
    - id: "Sample"

global:
  instance:
    # -- despite the instance name, all components within this group will be prefixed
    # with the group (unless the group name and the environment name are not identical)
    # Also this makes sure the network policies are acting on the group, not on the instance.
    group: "sample-group"

# -- We need to make sure, that only ONE instance is creating the default network policies
# and also the certificate for the group.
# All other group members are using the central one
override:
  ingress:
    # -- this overrides any issuers and makes sure not certificate request is generated for
    # cert-manager
    issuer: null
    # -- since no issuer is set, the default would be to generate a self signed certificate.
    # We need to prevent that
    createSelfSignedCertificate: false
  security:
    cni:
      # -- Even if we globally switched the creation of network policies on, we do not want that
      # for this instance (and the instance chart only: Subcharts might still create the policies.
      # If you want to force that off as well, override in global)
      createNetworkPolicy: false