Services

TL;DR:

  • Platform service modules provision Kubernetes resources on clusters provisioned using cluster modules.
  • Consider platform service modules for anything that's required before deploying application workloads.
  • Kubernetes resources managed by platform service modules are fully integrated into the Terraform lifecycle.
  • Platform services can be from the catalog or your own custom manifests.

Adding or Removing Services

Services can be added or removed by adding or removing service modules. The kbst CLI provides scaffolding to make writing the module boilerplate more convenient.

The kbst CLI does not make any changes to cloud or Kubernetes resources. It only changes local files, and you can see the changes with git status. To have the changes take effect, you have to commit, push, merge and promote them following the GitOps flow.

Adding a Service

Adding a services adds one file to your repository, because services are added for every cluster. You can add services by writing the Terraform yourself. Or you can use the kbst CLI to scaffold it. The CLI will configure the provider and environments of the new service to match the cluster it is added to automatically.

# kbst add service <name>
kbst add services nginx
# to only add the services to a specific cluster
# kbst add service <name> --cluster-name <cluster-name>
kbst add service nginx --cluster-name eks_gc0_eu-west-1

Removing a Service

The kbst CLI can also remove a service for you.

# list all platform components
kbst list
aks_gc0_westeurope
aks_gc0_westeurope_service_nginx
eks_gc0_eu-west-1
eks_gc0_eu-west-1_service_nginx
gke_gc0_europe-west1
gke_gc0_europe-west1_service_nginx
# then remove the desired services by <name>
kbst remove gke_gc0_europe-west1_service_nginx

Configuration

Platform service module configuration is the same for all catalog modules and the custom-manifest module. The modules provide the same attributes available in a kustomization.yaml. See the commenteded examples below for more details and how to use them inside Terraform syntax.

module "eks_gc0_eu-west-1_service_example" {
providers = {
kustomization = kustomization.example_cluster_alias
}
# fictitious example module source and version
source = "kbst.xyz/catalog/example/kustomization"
version = "0.0.0-kbst.0"
configuration = {
apps = {
# list of paths to YAML files or Kustomizations to append to the module's default list of resources
# (optional), defaults to null
additional_resources = [
"${path.root}/manifests/resource.yaml"
]
# set annotations on all Kubernetes resources
# (optional), defaults to null
common_annotations = {
"example-annotation" = var.example_annotation
}
# set labels on all Kubernetes resources
# (optional), defaults to null
common_labels = {
"example-label" = var.example_label
}
# generate Kubernetes configMaps
# (optional), defaults to null
config_map_generator = [{
# name (required)
# Sets 'metadata.name' of the configMap resource
name = "example"
# namespace (required)
# Sets 'metadata.namespace' of the configMap resource
namespace = "example"
# behavior (optional)
# Valid values: 'create', 'replace' or 'merge'. Defaults to 'create'.
behavior = "create"
# literals (optional)
# List of 'KEY=VALUE' strings. Sets 'data[KEY] = VALUE' in the configMap.
literals = [
"KEY=VALUE"
]
# envs (optional)
# List of paths (strings) to env files (one KEY=VALUE pair per line).
# Sets 'data[KEY] = VALUE' in the configMap per line in the env file.
envs = [
"${path.root}/manifests/env"
]
# files (optional)
# List of paths (strings) to files.
# Sets 'data[KEY] = file_content'. KEY defaults to the file's name.
# Overwrite by prefixing 'customkey='.
files = [
"${path.root}/manifests/cfg.ini" # data["cfg.ini"] = file_content
"prod.ini=${path.root}/manifests/cfg.ini" # data["prod.ini"] = file_content
]
# options (optional)
# Same as top level 'generator_options' but specific to this configMap.
options = {
# see generator_options
}
}]
# generate Kubernetes secrets
# (optional), defaults to null
secret_generator = [{
# name (required)
# Sets 'metadata.name' of the secret resource
name = "example"
# namespace (required)
# Sets 'metadata.namespace' of the secret resource
namespace = "example"
# behavior (optional)
# Valid values: 'create', 'replace' or 'merge'. Defaults to 'create'.
behavior = "create"
# type (optional)
# 'type' attribute of the secret to generate.
type = "generic"
# literals (optional)
# List of 'KEY=VALUE' strings. Sets 'data[KEY] = VALUE' in the secret.
literals = [
"KEY=VALUE"
]
# envs (optional)
# List of paths (strings) to env files (one KEY=VALUE pair per line).
# Sets 'data[KEY] = VALUE' in the secret per line in the env file.
envs = [
"${path.root}/manifests/env"
]
# files (optional)
# List of paths (strings) to files.
# Sets 'data[KEY] = file_content'. KEY defaults to the file's name.
# Overwrite by prefixing 'customkey='.
files = [
"${path.root}/manifests/cfg.ini" # data["cfg.ini"] = file_content
"prod.ini=${path.root}/manifests/cfg.ini" # data["prod.ini"] = file_content
]
# options (optional)
# Same as top level 'generator_options' but specific to this secret.
options = {
# see generator_options
}
}]
# set options for all configMap and secret generators
# (optional), defaults to null
generator_options = {
# annotations (optional)
# Sets 'metadata.annotations' on the generated resources. Defaults to '{}'.
annotations = {
example-annotation = "example"
}
# labels (optional)
# Sets 'metadata.labels' on the generated resources. Defaults to '{}'.
labels = {
example-label = "example"
}
# disable_name_suffix_hash (optional)
# Disables hash suffix of generated resource's 'metadata.name'.
# Defaults to 'false'.
disable_name_suffix_hash = true
}
# patch image names, tags or digests
# (optional), defaults to null
images = [{
# Refers to the 'pod.spec.container.name' to modify the 'image' attribute of.
name = "busybox"
# Customize the 'registry/name' part of the image. The part before the ':'
new_name = "new_name"
# Customize the 'tag' part of the image. The part after the ':'.
new_tag = "new_tag"
# Replace the 'tag' part of an image with a 'digest'.
digest = "sha256:..."
}]
# prefix or suffix to add to resource names
# (optional), default to null
name_prefix = "prefix-"
name_suffix = "-suffix"
# namespace to set for all resources
# (optional), default to null
namespace = "example"
# patches to apply to resources
# (optional), default to null
patches = [{
# path (optional)
# Path to a file that defines a strategic merge or JSON patch.
path = "${path.root}/manifests/patch.yaml"
# patch (optional)
# Inline string that defines a strategic merge or JSON patch.
patch = <<-EOF
- op: replace
path: /metadata/name
value: newname
EOF
# target (optional)
# Target one or multiple resources to be patched.
target = {
group = ""
version = "v1"
kind = "ConfigMap"
name = "example"
namespace = "example"
label_selector = "key=value"
annotation_selector = "key=value"
}
}]
# set replicas attribute of deployments and similar resources
# (optional), default to null
replicas = [{
# Refers to the 'metadata.name' of the resource to scale
name = "example"
# Sets the desired number of replicas.
count = 5
}]
# select upstream variant to deploy
# available variants are documented on the respective catalog page
# (optional), module specific default
variant = "example"
}
ops = {}
}
}

Low-level arguments

In addition to the convenience kustomization attributes documented above, platform service modules also pass the following low-level attributes through to the kustomization provider. These Kustomization attributes are less useful in the Terraform context and as such are not documented here.

  • components (optional) List of paths to Kustomize components.
  • crds (optional) List of paths to Kustomize CRDs.
  • generators (optional) List of paths to Kustomize generators.
  • transformers (optional) List of paths to Kustomize transformers.
  • vars (optional) List of objects to define Kustomize vars.