From ebb72af9752f78fd5dc0fe18f281c609a59de044 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 28 Oct 2024 10:23:12 +0000 Subject: [PATCH] Deployed 5dad00a to main with MkDocs 1.6.1 and mike 2.1.3 --- main/library/core/index.html | 2 +- main/library/extensions/index.html | 2 +- main/library/index.html | 2 +- main/library/labeling/index.html | 2 +- main/library/networking/index.html | 2 +- main/library/route/index.html | 2 +- main/library/util/index.html | 2 +- main/modules/databases/mariadb/index.html | 2 +- main/search/search_index.json | 2 +- main/sitemap.xml.gz | Bin 127 -> 127 bytes 10 files changed, 9 insertions(+), 9 deletions(-) diff --git a/main/library/core/index.html b/main/library/core/index.html index 9161894..22167e6 100644 --- a/main/library/core/index.html +++ b/main/library/core/index.html @@ -1271,7 +1271,7 @@

fn v1.container.new

- 2024-10-25 + 2024-10-28 diff --git a/main/library/extensions/index.html b/main/library/extensions/index.html index 57a4273..a7ee14d 100644 --- a/main/library/extensions/index.html +++ b/main/library/extensions/index.html @@ -1116,7 +1116,7 @@

extensions

- 2024-10-25 + 2024-10-28 diff --git a/main/library/index.html b/main/library/index.html index d5cafa2..398e4b0 100644 --- a/main/library/index.html +++ b/main/library/index.html @@ -1144,7 +1144,7 @@

cloudflight-libsonnet

- 2024-10-25 + 2024-10-28 diff --git a/main/library/labeling/index.html b/main/library/labeling/index.html index 94970c1..44b7564 100644 --- a/main/library/labeling/index.html +++ b/main/library/labeling/index.html @@ -1187,7 +1187,7 @@

Usage

- 2024-10-25 + 2024-10-28 diff --git a/main/library/networking/index.html b/main/library/networking/index.html index 8b33607..93d78e0 100644 --- a/main/library/networking/index.html +++ b/main/library/networking/index.html @@ -1271,7 +1271,7 @@

fn v1.ingress.withCertMixin

- 2024-10-25 + 2024-10-28 diff --git a/main/library/route/index.html b/main/library/route/index.html index 7ffed18..89fc7a4 100644 --- a/main/library/route/index.html +++ b/main/library/route/index.html @@ -1271,7 +1271,7 @@

fn v1.route.new

- 2024-10-25 + 2024-10-28 diff --git a/main/library/util/index.html b/main/library/util/index.html index a93da3e..3f8efd5 100644 --- a/main/library/util/index.html +++ b/main/library/util/index.html @@ -1841,7 +1841,7 @@

fn openshiftOAuth.serviceAccount.new - 2024-10-25 + 2024-10-28 diff --git a/main/modules/databases/mariadb/index.html b/main/modules/databases/mariadb/index.html index ba5fac9..b5aec0a 100644 --- a/main/modules/databases/mariadb/index.html +++ b/main/modules/databases/mariadb/index.html @@ -1185,7 +1185,7 @@

MariaDB Database Module

image: 'registry.redhat.io/rhel9/mariadb-105:1-105', datadirAction: 'upgrade-warn', // use 'upgrade-auto' to enable auto-upgrade when going to newer MariaDB version exporterImage: 'docker.io/prom/mysqld-exporter:v0.15.1', - exporter_password: std.md5(self.password), + exporterPassword: std.md5(self.password), resources:: { limits: { cpu: '500m', diff --git a/main/search/search_index.json b/main/search/search_index.json index 9980863..10d78ee 100644 --- a/main/search/search_index.json +++ b/main/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Home","text":"

Welcome to the documentation of the Cloudflight jsonnet library.

This library contains utilities and premade modules to ease working with Kubernets and OpenShift.

To get started, take a look at the guides or the module documentation.

If you know your way around jsonnet already, why not take a look at our complete library?

If you want support for your editor you should use one of the plugins listed on the tools page. We recommend plugins based on the jsonnet-language server.

Info

cloudflight-libsonnet is inteded to be used with Tanka. Other tools might work, however we do not test for them. If you're using kubecfg, take a look at our migration guide.

"},{"location":"guides/","title":"Index","text":"

This section contains guides for various usecases concerning our jsonnet library.

If you just want to get going, take a look at the quick start.

"},{"location":"guides/#external-resources","title":"External Resources","text":""},{"location":"guides/quickstart/","title":"Quick start","text":""},{"location":"guides/quickstart/#setting-up","title":"Setting up","text":"

To start using this library, first initialize the working directory using tk init.

This will create a directory structure similar to this:

.\n\u251c\u2500\u2500 environments\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 default\n\u251c\u2500\u2500 jsonnetfile.json\n\u251c\u2500\u2500 jsonnetfile.lock.json\n\u251c\u2500\u2500 lib\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 k.libsonnet\n\u2514\u2500\u2500 vendor\n    \u251c\u2500\u2500 1.23 -> github.com/jsonnet-libs/k8s-libsonnet/1.23\n    \u251c\u2500\u2500 github.com\n    \u2514\u2500\u2500 ksonnet-util -> github.com/grafana/jsonnet-libs/ksonnet-util\n

Next, we need to install the cloudflight-libsonnet library using jb:

jb install github.com/cloudflightio/cloudflight-libsonnet@main\n

The last step is to adapt the predefined k.libsonnet. When initializing, Tanka simply imports the k8s-libsonnet library here. Since some of our customizations depend on other libraries which have to be imported at this point (such as openshift-libsonnet or prometheus-libsonnet), you replace the contents of k.libsonnet with the following:

import 'github.com/cloudflightio/cloudflight-libsonnet/k.libsonnet'\n
"},{"location":"guides/quickstart/#using-the-library","title":"Using the library","text":"

To use the components provided by this library (or other Kubernetes components), import our prelude.libsonnet.

Let's use the library to deploy a simple java based application, backed by an MariaDB instance.

"},{"location":"guides/quickstart/#creating-the-application","title":"Creating the application","text":"

Applications should be defined in the lib folder. To configure a java application, we create a file called lib/test-java.libsonnet with the contents below.

local k = (import 'cloudflight-libsonnet/prelude.libsonnet');\n{\n  _config+:: {\n    myApplication: {\n      name: 'my-application',\n      image: error '$._config.myApplication.image must be defined',\n    },\n  },\n  myApplication: {\n    deployment: k.util.java.deployment.new(\n      name=$._config.myApplication.name,\n      image=$._config.myApplication.image,\n      containerMixin=k.core.v1.container.livenessProbe.withInitialDelaySeconds(60),\n    ),\n    service: k.util.serviceFor(self.deployment),\n    route: k.util.routeFor(self.service, 'hello.example.com'),\n  },\n}\n

Now we can import this into our environment file environments/default/main.jsonnet

(import 'test-java.libsonnet')\n+ {\n  _config+: {\n    myApplication+: {\n      image: 'helloworld:latest',\n    },\n  },\n}\n

Provided your .kube/config and environments/default/spec.json are set up correctly, you can deploy this by running tk apply environments/default.

"},{"location":"guides/quickstart/#adding-the-database","title":"Adding the database","text":"

Most applications want to store data somewhere so let's add a database next. First, we import the database of choice in the main.jsonnet file.

(import 'cloudflight-libsonnet/databases/mariadb.libsonnet')\n+ (import 'test-java.libsonnet')\n+ {\n  _config+: {\n    mariadb+: {\n      user: 'application-user',\n      password: 'hunter2',\n      database: 'my-application',\n    },\n    myApplication+: {\n      image: 'helloworld:latest',\n    },\n  },\n}\n

To connect our application to the database, we need to configure the deployment on a lower level. This is because of the fact, that the plain util.java.deployment does not make any assumptions about databases.

As documented in the java module, we build the deployment ourselves, but mix in some environment variables.

local k = (import 'cloudflight-libsonnet/prelude.libsonnet');\n{\n  _config+:: {\n    myApplication: {\n      name: 'my-application',\n      image: error '$._config.myApplication.image must be defined',\n      dbUser: error '$._config.myApplication.dbUser must be defined',\n      dbPasswordRef: error '$._config.myApplication.dbPasswordRef must be a valid secretSecretKeyRef',\n      dbUrl: error '$._config.myApplication.dbUrl must be defined',\n    },\n  },\n  myApplication: {\n    deployment: k.apps.v1.deployment.new(\n      name=$._config.myApplication.name,\n      replicas=1,\n      containers=[\n        k.util.java.container.new($._config.myApplication.name, $._config.myApplication.image)\n        + k.core.v1.container.withEnvMixin([\n          {\n            name: 'SPRING_DATASOURCE_PASSWORD',\n            valueFrom: { secretKeyRef: $._config.myApplication.dbPasswordRef },\n          },\n          {\n            name: 'SPRING_DATASOURCE_USERNAME',\n            value: $._config.myApplication.dbUser,\n          },\n          {\n            name: 'SPRING_DATASOURCE_URL',\n            value: $._config.myApplication.dbUrl,\n          },\n        ]),\n      ]\n    ),\n    service: k.util.serviceFor(self.deployment),\n    route: k.util.routeFor(self.service, 'hello.example.com'),\n  },\n}\n

In the last step, we fill the new config parameters with values.

(import 'cloudflight-libsonnet/databases/mariadb.libsonnet')\n+ (import 'test-java.libsonnet')\n+ {\n  _config+: {\n    mariadb+: {\n      user: 'application-user',\n      password: 'hunter2',\n      database: 'my-application',\n    },\n    myApplication+: {\n      image: 'helloworld:latest',\n      dbUser: $._config.mariadb.user,\n      dbPasswordRef: $.mariadb.passwordSecretKeyRef,\n      dbUrl: 'jdbc:mysql://' + $.mariadb.service.metadata.name + '/' + $._config.mariadb.database,\n    },\n  },\n  mariadb2: (import 'cloudflight-libsonnet/databases/mariadb.libsonnet') + {\n    _config+: {\n      mariadb+: {\n        name: 'foo',\n        user: 'foo-user',\n        password: 'foo-user',\n      },\n    },\n  },\n}\n

And we're done!

To recap: we have configured an application, added a database and connected it to our application. The way we connected the applications is transparent, and we could (as long as the application supports it) change the database entirely in our main.jsonnet. This way, we can use different database setups across environment, while keeping the application configuration the same.

For more information, check out the documentation of the java utilities and the MariaDB module.

"},{"location":"guides/tanka_migration/","title":"Migrating to Tanka","text":"

At Cloudflight we were previously using kubecfg to deploy our applications. As of 2022-02-21, tanka is our recommended tool for Kubernetes configurations. Reasoning for this can be found in ADR-0077.

If you're still using kubecfg you're in Luck! The migration to Tanka is very simple and can be done in under five minutes.

Tip

TL;DR:

"},{"location":"guides/tanka_migration/#verifying-your-current-setup","title":"Verifying your current setup","text":"

Before we can start to migrate to the new setup, we should be confident in the old one to avoid issues further down the line.

As a requirement, you should be able to view your configuration in the yaml format by running

kubecfg show $YOUR_STAGE_FILE\n
"},{"location":"guides/tanka_migration/#restructuring","title":"Restructuring","text":"

The main change required for a smooth workflow in Tanka, is a small restructuring of the directory. Our old layout prescribes a flat structure with everything in the root directory. Tanka on the other hand expects a folder per environment. To perform this step, you need to go from this:

.\n\u251c\u2500\u2500 jsonnetfile.json\n\u251c\u2500\u2500 production.jsonnet\n\u251c\u2500\u2500 resources\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 application.jsonnet\n\u2514\u2500\u2500 staging.jsonnet\n

to

.\n\u251c\u2500\u2500 jsonnetfile.json\n\u251c\u2500\u2500 environments\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 production\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 main.jsonnet # (1)\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 staging\n\u2502\u00a0\u00a0     \u2514\u2500\u2500 main.jsonnet # (2)\n\u2514\u2500\u2500 lib\n    \u2514\u2500\u2500 application.libsonnet\n
  1. The old production.jsonnet
  2. The old staging.jsonnet
"},{"location":"guides/tanka_migration/#configuring","title":"Configuring","text":"

Instead of relying on the current Kubernetes context, Tanka needs explicit information on the API Server as well as the namespace.

This information is saved in the spec.json file, contained in the respective environment. The complete layout can be found in the Tanka documentation

The syntax is as follows:

{\n  \"apiVersion\": \"tanka.dev/v1alpha1\",\n  \"kind\": \"Environment\",\n  \"metadata\": {\n    \"name\": \"environments/staging\"\n  },\n  \"spec\": {\n    \"apiServer\": \"openshift-dev.internal.cloudflight.io:6443\", // (1)\n    \"namespace\": \"762-example-staging\", // (2)\n    \"resourceDefaults\": {},\n    \"expectVersions\": {},\n    \"injectLabels\": true\n  }\n}\n
  1. API server URL. Excluding theh protocol, including the port
  2. Namespace of your project. Will be injected to all resources
"},{"location":"guides/tanka_migration/#fixing-imports","title":"Fixing Imports","text":"

Now that you moved around the files, you will also need to fix the imports contained within them. For convenience, Tanka automatically includes the lib and vendor directory in the jsonnet path. So instead of having to write ../../lib/application.libsonnet you can simply import application.libsonnet.

"},{"location":"guides/tanka_migration/#verifying-the-new-configuration","title":"Verifying the new configuration","text":"

After fixing the imports, you can show the new configuration with the following command:

tk show environments/staging\n
"},{"location":"guides/tanka_migration/#teamcity","title":"TeamCity","text":"

Tanka integration from TeamCity is supported from version 3.0.0 of the cloudflight-teamcity-dsl onwards.

Example:

subCloudflightProject {\n  name = \"Deployment\"\n  tankaApply {\n    openShiftConfig {\n        serviceAccountToken = \"credentialsJSON:...\"\n    }\n    contextDir = \".openshift\" // (1)\n  }\n}\n
  1. Default: deployment as is the case with our new configuration skeleton
"},{"location":"library/","title":"cloudflight-libsonnet","text":"

This library contains various utility modules for use with the jsonnet configuration language To get started, import the provided prelude which will composit the library for you.

local k = import ('cloudflight-libsonnet/prelude.libsonnet');\n

The prelude depends on a file called k.libsonnet being available for import. Either place it in your lib or environment folder. Using the environment folder allows for library level configuration options to be applied on an environment level.

This works, because import paths are ranked as highlighted in the Tanka documentation.

A pre-populated k.libsonnet is available in this library so a minimal k.libsonnet would look like this:

(import 'cloudflight-libsonnet/k.libsonnet')\n

This includes k8s-libsonnet, openshift-libsonnet as well as prometheus-libsonnet

For more information on customization options in k.libsonnet, take a look at the labeling extension.

"},{"location":"library/core/","title":"core","text":"

Contains extensions related to core kubernetes components

"},{"location":"library/core/#index","title":"Index","text":""},{"location":"library/core/#fields","title":"Fields","text":""},{"location":"library/core/#obj-v1","title":"obj v1","text":""},{"location":"library/core/#obj-v1container","title":"obj v1.container","text":""},{"location":"library/core/#fn-v1containernew","title":"fn v1.container.new","text":"
new(name, image, unprivileged='true')\n

new returns a new container of given name and image. By default it injects an openshift 4.11 compatible securityContext

"},{"location":"library/extensions/","title":"extensions","text":"

Extensions available to the standard library

"},{"location":"library/labeling/","title":"labeling","text":"

This extension allows you to label core kubernetes resources with useful labels.

"},{"location":"library/labeling/#usage","title":"Usage","text":"

To use this labeling function, edit your k.libsonnet to look something like this

(import 'cloudflight-libsonnet/k.libsonnet')\n+ {\n  _config+:: {\n    project: 'some-project-name'\n  }\n}\n

Afterwards, all resources created (provided they use cloudflight-libsonnet/prelude.libsonnet), will have the cloudflight.io/project=some-project-name label attached

If you need to set this on a per-environment basis, move the k.libsonnet file to your environment folder as described in the Tanka documentation.

"},{"location":"library/networking/","title":"networking","text":"

Contains extensions related to cert-manager

"},{"location":"library/networking/#index","title":"Index","text":""},{"location":"library/networking/#fields","title":"Fields","text":""},{"location":"library/networking/#obj-v1","title":"obj v1","text":""},{"location":"library/networking/#obj-v1ingress","title":"obj v1.ingress","text":""},{"location":"library/networking/#fn-v1ingresswithcertmixin","title":"fn v1.ingress.withCertMixin","text":"
withCertMixin(issuer, clusterwide)\n

withCertMixin instructs cert-manager to add an certificate to the ingress-resource.

"},{"location":"library/route/","title":"route","text":"

Contains extensions to the default route functions provided by openshift-libsonnet

"},{"location":"library/route/#index","title":"Index","text":""},{"location":"library/route/#fields","title":"Fields","text":""},{"location":"library/route/#obj-v1","title":"obj v1","text":""},{"location":"library/route/#obj-v1route","title":"obj v1.route","text":""},{"location":"library/route/#fn-v1routenew","title":"fn v1.route.new","text":"
new(name, host, path)\n

builds a route with a predefined host and TLS Edge termination

"},{"location":"library/util/","title":"util","text":"

The util package contains ease of use functions to simplify working with kubernetes and jsonnet

"},{"location":"library/util/#index","title":"Index","text":""},{"location":"library/util/#fields","title":"Fields","text":""},{"location":"library/util/#fn-ingressfor","title":"fn ingressFor","text":"
ingressFor(service, host='', path='/', port='service.spec.ports[0].port')\n

ingressFor constructs a ingress object, compatible with the automatic translation to openshift routes. It expects a value for the hostname and defaults to '/' for the path.

"},{"location":"library/util/#fn-routefor","title":"fn routeFor","text":"
routeFor(service, host='', path='/', port='service.spec.ports[0].port')\n

routeFor constructs a openshift route to the specified service. It expects a value for the hostname and defaults to '/' for the path.

"},{"location":"library/util/#fn-servicefor","title":"fn serviceFor","text":"
serviceFor(deployment, ignored_labels, nameFormat='%(port)s')\n

serviceFor constructs a service for the specified deployment.

Selector labels are taken from the pod spec but can be ignored using the ignored_labels parameter.

The ports of the service will have the same name as in the container spec to avoid confusion. This can be changed with the nameFormat parameter.

"},{"location":"library/util/#fn-weightedroutefor","title":"fn weightedRouteFor","text":"
weightedRouteFor(name, host='', port='', services, path='/')\n

weightedRouteFor constructs a openshift route to the specified services. It expects a value for the name, hostname, port, services and defaults to '/' for the path. services expects an array consisting of objects with the keys name (name of the service) and weight.

"},{"location":"library/util/#obj-certmanager","title":"obj certmanager","text":"

certman holds functions related to cert-manager (cert-manager.io)

"},{"location":"library/util/#obj-certmanagerissuer","title":"obj certmanager.issuer","text":""},{"location":"library/util/#fn-certmanagerissuernew","title":"fn certmanager.issuer.new","text":"
new(emain, ingressClassName='nginx', production=true, clusterwide=true, name='letsencrypt-production || letsencrypt-staging')\n

constructs a cert-manager issuer resource for letsencrypt with sensible default.

"},{"location":"library/util/#obj-java","title":"obj java","text":"

java holds my functions related to java based applications

"},{"location":"library/util/#obj-javacontainer","title":"obj java.container","text":""},{"location":"library/util/#fn-javacontainernew","title":"fn java.container.new","text":"
new(name, image, port=8080, actuatorPort='port+8080', env={})\n

constructs a container with reccomended settings for Java/Spring Boot applications. Includes liveness- and readiness probes, activates the kubernetes spring profile and sets sensible resource defaults.

"},{"location":"library/util/#obj-javadeployment","title":"obj java.deployment","text":""},{"location":"library/util/#fn-javadeploymentnew","title":"fn java.deployment.new","text":"
new(name, image, replicas=1, env={}, containerMixin={}, runtime='spring-boot', component='backend')\n

constructs a deployment using the java container. If you need more control, construct this deployment yourself.

containerMixin can be used to modify the application container. For example:

deployment.new(/*...*/,\n  containerMixin=k.core.v1.container.livenessProbe.withInitialDelaySeconds(60))\n
increases the initial delay seconds of the default liveness probe.

The runtime and component parameters are used to prefill recommended labels

"},{"location":"library/util/#obj-javalivenessprobe","title":"obj java.livenessProbe","text":""},{"location":"library/util/#fn-javalivenessprobenew","title":"fn java.livenessProbe.new","text":"
new(port=8080, initialDelaySeconds=30)\n

new constructs a fresh liveness probe, checking if the tcp port 8080 is open

"},{"location":"library/util/#obj-javareadinessprobe","title":"obj java.readinessProbe","text":""},{"location":"library/util/#fn-javareadinessprobenew","title":"fn java.readinessProbe.new","text":"
new(port=18080, path='/actuator/health')\n

new constructs a fresh readiness probe, checking if the application is up. The port and path of the actuator endpoint can be changed using the parameters.

"},{"location":"library/util/#obj-openshiftoauth","title":"obj openshiftOAuth","text":"

openshiftOAuth contains utilities to proxy an application using the OpenShift OAuth Proxy

"},{"location":"library/util/#obj-openshiftoauthcontainer","title":"obj openshiftOAuth.container","text":""},{"location":"library/util/#fn-openshiftoauthcontainernew","title":"fn openshiftOAuth.container.new","text":"
new(upstream, serviceAccount)\n

constructs a container proxying connections to the upstream parameter.

"},{"location":"library/util/#obj-openshiftoauthdeployment","title":"obj openshiftOAuth.deployment","text":""},{"location":"library/util/#fn-openshiftoauthdeploymentwithproxy","title":"fn openshiftOAuth.deployment.withProxy","text":"
withProxy(upstream, serviceAccount)\n

add a proxy sidecar to the container. This also sets the service account used by the pod. The ServiceAccount needs to have the correct redirect reference for the route. See openshiftOAuth.serviceAccount.new for an easy way to create a compliant service account

"},{"location":"library/util/#obj-openshiftoauthserviceaccount","title":"obj openshiftOAuth.serviceAccount","text":""},{"location":"library/util/#fn-openshiftoauthserviceaccountnew","title":"fn openshiftOAuth.serviceAccount.new","text":"
new(name, route)\n

constructs a serviceaccount annotated with a oauth-redirectreference pointing to the route parameter

"},{"location":"modules/","title":"What are modules?","text":"

Modules are ready-to-use setups of existing applications and services. To use them, import them into your main.libsonnet like so:

(import 'cloudflight-libsonnet/databases/mariadb.libsonnet') + {\n  _config+: {\n    mariadb+: {\n      user: 'foo',\n      password: 'bar',\n    }\n  }\n}\n
"},{"location":"modules/java_application/","title":"Java Applications","text":"

Even though not strictly a module, this library contains a lot of utility functions to help you deploy Java applications. This page contains some ways these functions can be used.

"},{"location":"modules/java_application/#all-in-one","title":"All-in-one","text":"

This example contains the deployment of a simple spring boot based application. It should be located somewhere like lib/my-application.libsonnet.

jsonnetyaml
local k = (import 'cloudflight-libsonnet/prelude.libsonnet');\n{\n  _config+:: {\n    myApplication: {\n      name: 'my-application',\n      image: error '$._config.myApplication.image must be defined',\n    },\n  },\n  myApplication: {\n    deployment: k.util.java.deployment.new(\n      name=$._config.myApplication.name,\n      image=$._config.myApplication.image,\n      containerMixin=k.core.v1.container.livenessProbe.withInitialDelaySeconds(60),\n    ),\n    service: k.util.serviceFor(self.deployment),\n    route: k.util.routeFor(self.service, 'hello.example.com'),\n  },\n}\n
apiVersion: v1\nkind: Service\nmetadata:\nlabels:\n    name: my-application\nname: my-application\nnamespace: test-java\nspec:\nports:\n- name: my-application-http\n    port: 8080\n    targetPort: 8080\n- name: my-application-actuator\n    port: 9080\n    targetPort: 9080\nselector:\n    name: my-application\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\nname: my-application\nnamespace: test-java\nspec:\nminReadySeconds: 10\nreplicas: 1\nrevisionHistoryLimit: 10\nselector:\n    matchLabels:\n    name: my-application\ntemplate:\n    metadata:\n    labels:\n        name: my-application\n    spec:\n    containers:\n    - env:\n        - name: SPRING_PROFILES_ACTIVE\n        value: kubernetes\n        image: helloworld:latest\n        imagePullPolicy: IfNotPresent\n        livenessProbe:\n        failureThreshold: 5\n        initialDelaySeconds: 30\n        periodSeconds: 10\n        successThreshold: 1\n        tcpSocket:\n            port: 8080\n        timeoutSeconds: 1\n        name: my-application\n        ports:\n        - containerPort: 8080\n        name: http\n        - containerPort: 9080\n        name: actuator\n        readinessProbe:\n        failureThreshold: 5\n        httpGet:\n            path: /actuator/health\n            port: 18080\n        initialDelaySeconds: 30\n        periodSeconds: 10\n        successThreshold: 1\n        timeoutSeconds: 1\n        resources:\n        limits:\n            cpu: 500m\n            memory: 1Gi\n        requests:\n            cpu: 100m\n            memory: 1Gi\n---\napiVersion: route.openshift.io/v1\nkind: Route\nmetadata:\nname: my-application\nnamespace: test-java\nspec:\nhost: hello.example.com\npath: /\nport:\n    targetPort: 8080\ntls:\n    insecureEdgeTerminationPolicy: Redirect\n    termination: Edge\nto:\n    kind: Service\n    name: my-application\n

Switch between the tabs to see the rendered output

"},{"location":"modules/java_application/#diy","title":"DIY","text":"

If you have the need for further customization, you can pick and choose parts of the library you would like to use.

In this example, we want to modify the container so we use the util.java.container.new() to get a base structure and extend it. This way, we still have the defaults set, but are able to customize them to our hearts content.

jsonnetyaml
local k = (import 'cloudflight-libsonnet/prelude.libsonnet');\n{\n  _config+:: {\n    myApplication: {\n      name: 'my-application',\n      image: error '$._config.myApplication.image must be defined',\n    },\n  },\n  myApplication: {\n    deployment: k.apps.v1.deployment.new(\n                  name=$._config.myApplication.name,\n                  replicas=2,\n                  containers=[\n                    k.util.java.container.new($._config.myApplication.name, $._config.myApplication.image)\n                    + k.core.v1.container.withVolumeMounts([\n                      k.core.v1.volumeMount.new(name='temp', mountPath='/opt/cache'),\n                    ]),\n                  ]\n                )\n                + k.apps.v1.deployment.spec.template.spec.withVolumes([\n                  k.core.v1.volume.fromEmptyDir(name='temp'),\n                ]),\n    service: k.util.serviceFor(self.deployment),\n    route: k.util.routeFor(self.service, 'hello.example.com'),\n  },\n}\n
apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    name: my-application\n  name: my-application\n  namespace: test-java-diy\nspec:\n  ports:\n  - name: my-application-http\n    port: 8080\n    targetPort: 8080\n  - name: my-application-actuator\n    port: 9080\n    targetPort: 9080\n  selector:\n    name: my-application\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: my-application\n  namespace: test-java-diy\nspec:\n  minReadySeconds: 10\n  replicas: 2\n  revisionHistoryLimit: 10\n  selector:\n    matchLabels:\n      name: my-application\n  template:\n    metadata:\n      labels:\n        name: my-application\n    spec:\n      containers:\n      - env:\n        - name: SPRING_PROFILES_ACTIVE\n          value: kubernetes\n        image: helloworld:latest\n        imagePullPolicy: IfNotPresent\n        livenessProbe:\n          failureThreshold: 5\n          initialDelaySeconds: 30\n          periodSeconds: 10\n          successThreshold: 1\n          tcpSocket:\n            port: 8080\n          timeoutSeconds: 1\n        name: my-application\n        ports:\n        - containerPort: 8080\n          name: http\n        - containerPort: 9080\n          name: actuator\n        readinessProbe:\n          failureThreshold: 5\n          httpGet:\n            path: /actuator/health\n            port: 18080\n          initialDelaySeconds: 30\n          periodSeconds: 10\n          successThreshold: 1\n          timeoutSeconds: 1\n        resources:\n          limits:\n            cpu: 500m\n            memory: 1Gi\n          requests:\n            cpu: 100m\n            memory: 1Gi\n        volumeMounts:\n        - mountPath: /opt/cache\n          name: temp\n      volumes:\n      - emptyDir: {}\n        name: temp\n---\napiVersion: route.openshift.io/v1\nkind: Route\nmetadata:\n  name: my-application\n  namespace: test-java-diy\nspec:\n  host: hello.example.com\n  path: /\n  port:\n    targetPort: 8080\n  tls:\n    insecureEdgeTerminationPolicy: Redirect\n    termination: Edge\n  to:\n    kind: Service\n    name: my-application\n
"},{"location":"modules/applications/mailhog/","title":"Mailhog","text":"

This module creates an instance of mailhog. Data is stored in memory only so messages will disappear after a pod restart.

The following snippet lists all available configuration options alongside their default values:

(import 'cloudflight-libsonnet/applications/mailhog.libsonnet')\n+ {\n  _config+: {\n        mailhog: {\n          name: 'mailhog',\n          image: 'docker.io/anatomicjc/mailhog:1.0.1',\n          host: error '$._config.mailhog.host must be defined',\n          resources:: {\n            limits: {\n              cpu: '20m',\n              memory: '64Mi',\n            },\n            requests: {\n              cpu: '10m',\n              memory: '64Mi',\n            },\n          },\n        },\n\n  }\n}\n
"},{"location":"modules/applications/spring-boot-admin/","title":"Spring Boot Admin","text":"

This module creates an instance of spring-boot-admin, preconfigured to discover endpoints via Kubernetes.

The following snippets lists all available configuration options alongside their default values:

(import 'cloudflight-libsonnet/applications/spring-boot-admin.libsonnet')\n+ {\n  _config+: {\n        springBootAdmin: {\n          name: 'spring-boot-admin',\n          image: 'ghcr.io/cloudflightio/spring-boot-admin-docker:2.7.3',\n          host: error '$._config.springBootAdmin.host must be defined',\n          serviceAccountName: 'default',\n          config: {\n            spring: {\n              cloud: {\n                kubernetes: {\n                  discovery: {\n                    enabled: true,\n                    'service-labels': {\n                      '[app.openshift.io/runtime]': 'spring-boot',\n                    },\n                    catalogServiceWatchDelay: 300,\n                    'primary-port-name': 'actuator',\n                  },\n                },\n              },\n            },\n          },\n          resources:: {\n            limits: {\n              cpu: '500m',\n              memory: '512Mi',\n            },\n            requests: {\n              cpu: '10m',\n              memory: '512Mi',\n            },\n          },\n        },\n\n  }\n}\n
"},{"location":"modules/applications/spring-boot-admin/#integration-and-service-discovery","title":"Integration and Service Discovery","text":"

When using our java helpers, spring-boot-admin will automatically discover provided services and their respective actuator endpoints.

To customize the discovery, modify $._config.springBootAdmin.config.spring.cloud.kubernetes.discovery to match your labels.

"},{"location":"modules/databases/mariadb/","title":"MariaDB Database Module","text":"

This module contains a MariaDB instance, located in the mariadb key.

The following snippets lists all available configuration options alongside their default values:

(import 'cloudflight-libsonnet/databases/mariadb.libsonnet')\n+ {\n  _config+: {\n        mariadb: {\n          name: 'mariadb',\n          storage: '5Gi',\n          user: error 'cfg.user must be defined',\n          password: error 'cfg.password must be defined',\n          database: self.user,\n          image: 'registry.redhat.io/rhel9/mariadb-105:1-105',\n          datadirAction: 'upgrade-warn',  // use 'upgrade-auto' to enable auto-upgrade when going to newer MariaDB version\n          exporterImage: 'docker.io/prom/mysqld-exporter:v0.15.1',\n          exporter_password: std.md5(self.password),\n          resources:: {\n            limits: {\n              cpu: '500m',\n              memory: '1Gi',\n            },\n            requests: {\n              cpu: '200m',\n              memory: '1Gi',\n            },\n          },\n        },\n\n  }\n}\n
"},{"location":"modules/databases/mariadb/#exposed-values","title":"Exposed values","text":"

The following values are exposed, but not exported:

Name Contents mariadb.passwordSecretKeyRef A kubernetes secretKeyRef, referencing the user password"},{"location":"modules/databases/mariadb/#starting-multiple-instances","title":"Starting multiple instances","text":"

Another way to use this module, is by calling the newMariaDB function. This allows you to create multiple instances without polluting the global scope.

{\n  _config+:: {\n    dbOne: {\n      name: 'dbOne',\n      user: 'foo',\n      password: 'bar',\n    },\n    dbTwo: {\n      name: 'dbTwo',\n      user: 'foo',\n      password: 'bar',\n    }\n  }\n  dbOne: (import 'cloudflight-libsonnet/databases/mariadb.libsonnet').newMariaDB($._config.dbOne),\n  dbTwo: (import 'cloudflight-libsonnet/databases/mariadb.libsonnet').newMariaDB($._config.dbTwo),\n}\n
"},{"location":"modules/databases/mssql/","title":"MSSQL Database Module","text":"

This module contains a simple MSSQL instance, located in the mssql key.

The following snippets lists all available configuration options alongside their default values:

Info

You need to set acceptEula to true to accept the MSSQL EULA

(import 'cloudflight-libsonnet/databases/mssql.libsonnet')\n+ {\n  _config+: {\n        mssql: {\n          name: 'mssql',\n          storage: '5Gi',\n          // The password must be at least 8 characters long and contain characters from three of the following four sets: Uppercase letters, Lowercase letters, Base 10 digits, and Symbols\n          rootPassword: error 'cfg.rootPassword must be defined',\n          productId: 'Developer',\n          image: 'mcr.microsoft.com/mssql/rhel/server:2022-latest',\n          acceptEula: false,\n          resources:: {\n            limits: {\n              cpu: '500m',\n              memory: '2Gi',\n            },\n            requests: {\n              cpu: '200m',\n              memory: '2Gi',\n            },\n          },\n        },\n\n  }\n}\n
"},{"location":"modules/databases/mssql/#exposed-values","title":"Exposed values","text":"

The following values are exposed, but not exported:

Name Contents mssql.passwordSecretKeyRef A kubernetes secretKeyRef, referencing the SA password"},{"location":"modules/databases/redis/","title":"Redis Cache Module","text":"

This module contains a Redis Cache, located in the redis key.

The following snippets lists all available configuration options alongside their default values:

(import 'cloudflight-libsonnet/databases/redis.libsonnet')\n+ {\n  _config+: {\n        redis: {\n          name: 'redis',\n          image: 'registry.redhat.io/rhel8/redis-6:1-62',\n          exporterImage: 'docker.io/oliver006/redis_exporter:v1.43.0',\n          password: error 'cfg.password must either be defined or set to null',\n          storage: null,\n          resources:: {\n            limits: {\n              cpu: '100m',\n              memory: '1Gi',\n            },\n            requests: {\n              cpu: '50m',\n              memory: '1Gi',\n            },\n          },\n        },\n\n  }\n}\n
"},{"location":"modules/databases/redis/#starting-multiple-instances","title":"Starting multiple instances","text":"

Another way to use this module, is by calling the newRedis function. This allows you to create multiple instances without polluting the global scope.

{\n  _config+:: {\n    cacheOne: {\n      name: 'cacheOne',\n      password: 'foo',\n    },\n    cacheTwo: {\n      name: 'cacheTwo',\n      password: 'bar',\n    }\n  },\n  cacheOne: (import 'cloudflight-libsonnet/databases/redis.libsonnet').newRedis($._config.cacheOne),\n  cacheTwo: (import 'cloudflight-libsonnet/databases/redis.libsonnet').newRedis($._config.cacheTwo),\n}\n
"},{"location":"modules/databases/redis/#high-availability","title":"High Availability","text":"

If required, you can instead import the redis-sentinel module. This creates an additional sentinel deployment which fails over the master and replicas:

(import 'cloudflight-libsonnet/databases/redis-sentinel.libsonnet')\n+ {\n  _config+: {\n        redis: {\n          name: 'redis',\n          replicas: 3,\n          sentinels: 3,\n          image: 'quay.io/fedora/redis-6:20221012',\n          exporterImage: 'docker.io/oliver006/redis_exporter:v1.43.0',\n          password: error 'cfg.password must either be defined or set to null',\n          topologyKey: 'kubernetes.io/hostname',\n          storage: null,\n          resources:: {\n            limits: {\n              cpu: '100m',\n              memory: '1Gi',\n            },\n            requests: {\n              cpu: '50m',\n              memory: '1Gi',\n            },\n          },\n        },\n\n  }\n}\n
"},{"location":"modules/databases/redis/#exposed-values","title":"Exposed values","text":"

When using redis-sentinel, you also have access to the following values. They are exposed, but not exported.

Name Contents redis.sentinelNodes Array of sentinel host:port pairs"},{"location":"modules/infrastructure/cert-manager/","title":"Cert-Manager Module","text":"

This adds certmanager (see https://cert-manager.io/), located in the certmanager key.

It helpes you issuing and managing certificated using custom k8s resources only.

The following snippets lists all available configuration options alongside their default values:

(import 'cloudflight-libsonnet/infrastructure/cert-manager/cert-manager.libsonnet')\n+ {\n  _config+: {\n        certmanager: {\n          name: 'cert-manager',\n          aks: false,\n        },\n\n  }\n}\n
"},{"location":"modules/infrastructure/cert-manager/#example","title":"Example","text":"
(import 'cloudflight-libsonnet/infrastructure/cert-manager/cert-manager.libsonnet')\n+ {\n  _config+: {\n    certmanager: {\n      name: 'cert-manager',\n      namespace: 'cert-manager',\n      aks: true,\n    },\n  },\n}\n
"},{"location":"modules/infrastructure/cert-manager/#addons","title":"Addons","text":"

There is also a special set of utilities and extensions that can be used to make the setup process easier.

This example installs cert-manager, adds a lets-encrypt issuer and a ssl-protected ingress-rule:

local k = (import 'k.libsonnet');\nlocal ingress = k.networking.v1.ingress;\n\n(import 'cloudflight-libsonnet/infrastructure/cert-manager/cert-manager.libsonnet')\n+ {\n  issuer: k.util.certmanager.issuer.new('admin@example.com'),\n  ingress: ingress.new('test.example.com') + ingress.withCertMixin($.issuer),\n}\n
"},{"location":"modules/infrastructure/k8s-digester/","title":"k8s-digester Module","text":"

This module installs the k8s-digester in your cluster. It currently does not offer any customization options and is functionally equivalent to applying the digester_manifest.yaml.

The reason for this module is to have everything you need in one place without relying on manual kubectl apply steps.

"},{"location":"modules/infrastructure/nginx-ingress/","title":"Nginx-Ingress Module","text":"

This adds nginx-ingress-controller (see https://github.com/kubernetes/ingress-nginx), located in the nginxingress key.

This is helpful if no other ingress-controller is deployes (e.g. AKS without API Gateway).

The following snippets lists all available configuration options alongside their default values:

(import 'cloudflight-libsonnet/infrastructure/nginx-ingress/nginx-ingress.libsonnet')\n+ {\n  _config+: {\n        nginxingress: {\n          name: 'nginx-ingress',\n          type: 'external',\n          loadBalancerIP: error 'you need a static loadbalancer ip (public IP for external, internal IP for internal)',\n          internalSubnetAzure: null,\n          replicas: 2,\n          defaultTlsCertificate: null,\n        },\n\n  }\n}\n
"}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Home","text":"

Welcome to the documentation of the Cloudflight jsonnet library.

This library contains utilities and premade modules to ease working with Kubernets and OpenShift.

To get started, take a look at the guides or the module documentation.

If you know your way around jsonnet already, why not take a look at our complete library?

If you want support for your editor you should use one of the plugins listed on the tools page. We recommend plugins based on the jsonnet-language server.

Info

cloudflight-libsonnet is inteded to be used with Tanka. Other tools might work, however we do not test for them. If you're using kubecfg, take a look at our migration guide.

"},{"location":"guides/","title":"Index","text":"

This section contains guides for various usecases concerning our jsonnet library.

If you just want to get going, take a look at the quick start.

"},{"location":"guides/#external-resources","title":"External Resources","text":""},{"location":"guides/quickstart/","title":"Quick start","text":""},{"location":"guides/quickstart/#setting-up","title":"Setting up","text":"

To start using this library, first initialize the working directory using tk init.

This will create a directory structure similar to this:

.\n\u251c\u2500\u2500 environments\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 default\n\u251c\u2500\u2500 jsonnetfile.json\n\u251c\u2500\u2500 jsonnetfile.lock.json\n\u251c\u2500\u2500 lib\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 k.libsonnet\n\u2514\u2500\u2500 vendor\n    \u251c\u2500\u2500 1.23 -> github.com/jsonnet-libs/k8s-libsonnet/1.23\n    \u251c\u2500\u2500 github.com\n    \u2514\u2500\u2500 ksonnet-util -> github.com/grafana/jsonnet-libs/ksonnet-util\n

Next, we need to install the cloudflight-libsonnet library using jb:

jb install github.com/cloudflightio/cloudflight-libsonnet@main\n

The last step is to adapt the predefined k.libsonnet. When initializing, Tanka simply imports the k8s-libsonnet library here. Since some of our customizations depend on other libraries which have to be imported at this point (such as openshift-libsonnet or prometheus-libsonnet), you replace the contents of k.libsonnet with the following:

import 'github.com/cloudflightio/cloudflight-libsonnet/k.libsonnet'\n
"},{"location":"guides/quickstart/#using-the-library","title":"Using the library","text":"

To use the components provided by this library (or other Kubernetes components), import our prelude.libsonnet.

Let's use the library to deploy a simple java based application, backed by an MariaDB instance.

"},{"location":"guides/quickstart/#creating-the-application","title":"Creating the application","text":"

Applications should be defined in the lib folder. To configure a java application, we create a file called lib/test-java.libsonnet with the contents below.

local k = (import 'cloudflight-libsonnet/prelude.libsonnet');\n{\n  _config+:: {\n    myApplication: {\n      name: 'my-application',\n      image: error '$._config.myApplication.image must be defined',\n    },\n  },\n  myApplication: {\n    deployment: k.util.java.deployment.new(\n      name=$._config.myApplication.name,\n      image=$._config.myApplication.image,\n      containerMixin=k.core.v1.container.livenessProbe.withInitialDelaySeconds(60),\n    ),\n    service: k.util.serviceFor(self.deployment),\n    route: k.util.routeFor(self.service, 'hello.example.com'),\n  },\n}\n

Now we can import this into our environment file environments/default/main.jsonnet

(import 'test-java.libsonnet')\n+ {\n  _config+: {\n    myApplication+: {\n      image: 'helloworld:latest',\n    },\n  },\n}\n

Provided your .kube/config and environments/default/spec.json are set up correctly, you can deploy this by running tk apply environments/default.

"},{"location":"guides/quickstart/#adding-the-database","title":"Adding the database","text":"

Most applications want to store data somewhere so let's add a database next. First, we import the database of choice in the main.jsonnet file.

(import 'cloudflight-libsonnet/databases/mariadb.libsonnet')\n+ (import 'test-java.libsonnet')\n+ {\n  _config+: {\n    mariadb+: {\n      user: 'application-user',\n      password: 'hunter2',\n      database: 'my-application',\n    },\n    myApplication+: {\n      image: 'helloworld:latest',\n    },\n  },\n}\n

To connect our application to the database, we need to configure the deployment on a lower level. This is because of the fact, that the plain util.java.deployment does not make any assumptions about databases.

As documented in the java module, we build the deployment ourselves, but mix in some environment variables.

local k = (import 'cloudflight-libsonnet/prelude.libsonnet');\n{\n  _config+:: {\n    myApplication: {\n      name: 'my-application',\n      image: error '$._config.myApplication.image must be defined',\n      dbUser: error '$._config.myApplication.dbUser must be defined',\n      dbPasswordRef: error '$._config.myApplication.dbPasswordRef must be a valid secretSecretKeyRef',\n      dbUrl: error '$._config.myApplication.dbUrl must be defined',\n    },\n  },\n  myApplication: {\n    deployment: k.apps.v1.deployment.new(\n      name=$._config.myApplication.name,\n      replicas=1,\n      containers=[\n        k.util.java.container.new($._config.myApplication.name, $._config.myApplication.image)\n        + k.core.v1.container.withEnvMixin([\n          {\n            name: 'SPRING_DATASOURCE_PASSWORD',\n            valueFrom: { secretKeyRef: $._config.myApplication.dbPasswordRef },\n          },\n          {\n            name: 'SPRING_DATASOURCE_USERNAME',\n            value: $._config.myApplication.dbUser,\n          },\n          {\n            name: 'SPRING_DATASOURCE_URL',\n            value: $._config.myApplication.dbUrl,\n          },\n        ]),\n      ]\n    ),\n    service: k.util.serviceFor(self.deployment),\n    route: k.util.routeFor(self.service, 'hello.example.com'),\n  },\n}\n

In the last step, we fill the new config parameters with values.

(import 'cloudflight-libsonnet/databases/mariadb.libsonnet')\n+ (import 'test-java.libsonnet')\n+ {\n  _config+: {\n    mariadb+: {\n      user: 'application-user',\n      password: 'hunter2',\n      database: 'my-application',\n    },\n    myApplication+: {\n      image: 'helloworld:latest',\n      dbUser: $._config.mariadb.user,\n      dbPasswordRef: $.mariadb.passwordSecretKeyRef,\n      dbUrl: 'jdbc:mysql://' + $.mariadb.service.metadata.name + '/' + $._config.mariadb.database,\n    },\n  },\n  mariadb2: (import 'cloudflight-libsonnet/databases/mariadb.libsonnet') + {\n    _config+: {\n      mariadb+: {\n        name: 'foo',\n        user: 'foo-user',\n        password: 'foo-user',\n      },\n    },\n  },\n}\n

And we're done!

To recap: we have configured an application, added a database and connected it to our application. The way we connected the applications is transparent, and we could (as long as the application supports it) change the database entirely in our main.jsonnet. This way, we can use different database setups across environment, while keeping the application configuration the same.

For more information, check out the documentation of the java utilities and the MariaDB module.

"},{"location":"guides/tanka_migration/","title":"Migrating to Tanka","text":"

At Cloudflight we were previously using kubecfg to deploy our applications. As of 2022-02-21, tanka is our recommended tool for Kubernetes configurations. Reasoning for this can be found in ADR-0077.

If you're still using kubecfg you're in Luck! The migration to Tanka is very simple and can be done in under five minutes.

Tip

TL;DR:

"},{"location":"guides/tanka_migration/#verifying-your-current-setup","title":"Verifying your current setup","text":"

Before we can start to migrate to the new setup, we should be confident in the old one to avoid issues further down the line.

As a requirement, you should be able to view your configuration in the yaml format by running

kubecfg show $YOUR_STAGE_FILE\n
"},{"location":"guides/tanka_migration/#restructuring","title":"Restructuring","text":"

The main change required for a smooth workflow in Tanka, is a small restructuring of the directory. Our old layout prescribes a flat structure with everything in the root directory. Tanka on the other hand expects a folder per environment. To perform this step, you need to go from this:

.\n\u251c\u2500\u2500 jsonnetfile.json\n\u251c\u2500\u2500 production.jsonnet\n\u251c\u2500\u2500 resources\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 application.jsonnet\n\u2514\u2500\u2500 staging.jsonnet\n

to

.\n\u251c\u2500\u2500 jsonnetfile.json\n\u251c\u2500\u2500 environments\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 production\n\u2502\u00a0\u00a0 \u2502\u00a0\u00a0 \u2514\u2500\u2500 main.jsonnet # (1)\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 staging\n\u2502\u00a0\u00a0     \u2514\u2500\u2500 main.jsonnet # (2)\n\u2514\u2500\u2500 lib\n    \u2514\u2500\u2500 application.libsonnet\n
  1. The old production.jsonnet
  2. The old staging.jsonnet
"},{"location":"guides/tanka_migration/#configuring","title":"Configuring","text":"

Instead of relying on the current Kubernetes context, Tanka needs explicit information on the API Server as well as the namespace.

This information is saved in the spec.json file, contained in the respective environment. The complete layout can be found in the Tanka documentation

The syntax is as follows:

{\n  \"apiVersion\": \"tanka.dev/v1alpha1\",\n  \"kind\": \"Environment\",\n  \"metadata\": {\n    \"name\": \"environments/staging\"\n  },\n  \"spec\": {\n    \"apiServer\": \"openshift-dev.internal.cloudflight.io:6443\", // (1)\n    \"namespace\": \"762-example-staging\", // (2)\n    \"resourceDefaults\": {},\n    \"expectVersions\": {},\n    \"injectLabels\": true\n  }\n}\n
  1. API server URL. Excluding theh protocol, including the port
  2. Namespace of your project. Will be injected to all resources
"},{"location":"guides/tanka_migration/#fixing-imports","title":"Fixing Imports","text":"

Now that you moved around the files, you will also need to fix the imports contained within them. For convenience, Tanka automatically includes the lib and vendor directory in the jsonnet path. So instead of having to write ../../lib/application.libsonnet you can simply import application.libsonnet.

"},{"location":"guides/tanka_migration/#verifying-the-new-configuration","title":"Verifying the new configuration","text":"

After fixing the imports, you can show the new configuration with the following command:

tk show environments/staging\n
"},{"location":"guides/tanka_migration/#teamcity","title":"TeamCity","text":"

Tanka integration from TeamCity is supported from version 3.0.0 of the cloudflight-teamcity-dsl onwards.

Example:

subCloudflightProject {\n  name = \"Deployment\"\n  tankaApply {\n    openShiftConfig {\n        serviceAccountToken = \"credentialsJSON:...\"\n    }\n    contextDir = \".openshift\" // (1)\n  }\n}\n
  1. Default: deployment as is the case with our new configuration skeleton
"},{"location":"library/","title":"cloudflight-libsonnet","text":"

This library contains various utility modules for use with the jsonnet configuration language To get started, import the provided prelude which will composit the library for you.

local k = import ('cloudflight-libsonnet/prelude.libsonnet');\n

The prelude depends on a file called k.libsonnet being available for import. Either place it in your lib or environment folder. Using the environment folder allows for library level configuration options to be applied on an environment level.

This works, because import paths are ranked as highlighted in the Tanka documentation.

A pre-populated k.libsonnet is available in this library so a minimal k.libsonnet would look like this:

(import 'cloudflight-libsonnet/k.libsonnet')\n

This includes k8s-libsonnet, openshift-libsonnet as well as prometheus-libsonnet

For more information on customization options in k.libsonnet, take a look at the labeling extension.

"},{"location":"library/core/","title":"core","text":"

Contains extensions related to core kubernetes components

"},{"location":"library/core/#index","title":"Index","text":""},{"location":"library/core/#fields","title":"Fields","text":""},{"location":"library/core/#obj-v1","title":"obj v1","text":""},{"location":"library/core/#obj-v1container","title":"obj v1.container","text":""},{"location":"library/core/#fn-v1containernew","title":"fn v1.container.new","text":"
new(name, image, unprivileged='true')\n

new returns a new container of given name and image. By default it injects an openshift 4.11 compatible securityContext

"},{"location":"library/extensions/","title":"extensions","text":"

Extensions available to the standard library

"},{"location":"library/labeling/","title":"labeling","text":"

This extension allows you to label core kubernetes resources with useful labels.

"},{"location":"library/labeling/#usage","title":"Usage","text":"

To use this labeling function, edit your k.libsonnet to look something like this

(import 'cloudflight-libsonnet/k.libsonnet')\n+ {\n  _config+:: {\n    project: 'some-project-name'\n  }\n}\n

Afterwards, all resources created (provided they use cloudflight-libsonnet/prelude.libsonnet), will have the cloudflight.io/project=some-project-name label attached

If you need to set this on a per-environment basis, move the k.libsonnet file to your environment folder as described in the Tanka documentation.

"},{"location":"library/networking/","title":"networking","text":"

Contains extensions related to cert-manager

"},{"location":"library/networking/#index","title":"Index","text":""},{"location":"library/networking/#fields","title":"Fields","text":""},{"location":"library/networking/#obj-v1","title":"obj v1","text":""},{"location":"library/networking/#obj-v1ingress","title":"obj v1.ingress","text":""},{"location":"library/networking/#fn-v1ingresswithcertmixin","title":"fn v1.ingress.withCertMixin","text":"
withCertMixin(issuer, clusterwide)\n

withCertMixin instructs cert-manager to add an certificate to the ingress-resource.

"},{"location":"library/route/","title":"route","text":"

Contains extensions to the default route functions provided by openshift-libsonnet

"},{"location":"library/route/#index","title":"Index","text":""},{"location":"library/route/#fields","title":"Fields","text":""},{"location":"library/route/#obj-v1","title":"obj v1","text":""},{"location":"library/route/#obj-v1route","title":"obj v1.route","text":""},{"location":"library/route/#fn-v1routenew","title":"fn v1.route.new","text":"
new(name, host, path)\n

builds a route with a predefined host and TLS Edge termination

"},{"location":"library/util/","title":"util","text":"

The util package contains ease of use functions to simplify working with kubernetes and jsonnet

"},{"location":"library/util/#index","title":"Index","text":""},{"location":"library/util/#fields","title":"Fields","text":""},{"location":"library/util/#fn-ingressfor","title":"fn ingressFor","text":"
ingressFor(service, host='', path='/', port='service.spec.ports[0].port')\n

ingressFor constructs a ingress object, compatible with the automatic translation to openshift routes. It expects a value for the hostname and defaults to '/' for the path.

"},{"location":"library/util/#fn-routefor","title":"fn routeFor","text":"
routeFor(service, host='', path='/', port='service.spec.ports[0].port')\n

routeFor constructs a openshift route to the specified service. It expects a value for the hostname and defaults to '/' for the path.

"},{"location":"library/util/#fn-servicefor","title":"fn serviceFor","text":"
serviceFor(deployment, ignored_labels, nameFormat='%(port)s')\n

serviceFor constructs a service for the specified deployment.

Selector labels are taken from the pod spec but can be ignored using the ignored_labels parameter.

The ports of the service will have the same name as in the container spec to avoid confusion. This can be changed with the nameFormat parameter.

"},{"location":"library/util/#fn-weightedroutefor","title":"fn weightedRouteFor","text":"
weightedRouteFor(name, host='', port='', services, path='/')\n

weightedRouteFor constructs a openshift route to the specified services. It expects a value for the name, hostname, port, services and defaults to '/' for the path. services expects an array consisting of objects with the keys name (name of the service) and weight.

"},{"location":"library/util/#obj-certmanager","title":"obj certmanager","text":"

certman holds functions related to cert-manager (cert-manager.io)

"},{"location":"library/util/#obj-certmanagerissuer","title":"obj certmanager.issuer","text":""},{"location":"library/util/#fn-certmanagerissuernew","title":"fn certmanager.issuer.new","text":"
new(emain, ingressClassName='nginx', production=true, clusterwide=true, name='letsencrypt-production || letsencrypt-staging')\n

constructs a cert-manager issuer resource for letsencrypt with sensible default.

"},{"location":"library/util/#obj-java","title":"obj java","text":"

java holds my functions related to java based applications

"},{"location":"library/util/#obj-javacontainer","title":"obj java.container","text":""},{"location":"library/util/#fn-javacontainernew","title":"fn java.container.new","text":"
new(name, image, port=8080, actuatorPort='port+8080', env={})\n

constructs a container with reccomended settings for Java/Spring Boot applications. Includes liveness- and readiness probes, activates the kubernetes spring profile and sets sensible resource defaults.

"},{"location":"library/util/#obj-javadeployment","title":"obj java.deployment","text":""},{"location":"library/util/#fn-javadeploymentnew","title":"fn java.deployment.new","text":"
new(name, image, replicas=1, env={}, containerMixin={}, runtime='spring-boot', component='backend')\n

constructs a deployment using the java container. If you need more control, construct this deployment yourself.

containerMixin can be used to modify the application container. For example:

deployment.new(/*...*/,\n  containerMixin=k.core.v1.container.livenessProbe.withInitialDelaySeconds(60))\n
increases the initial delay seconds of the default liveness probe.

The runtime and component parameters are used to prefill recommended labels

"},{"location":"library/util/#obj-javalivenessprobe","title":"obj java.livenessProbe","text":""},{"location":"library/util/#fn-javalivenessprobenew","title":"fn java.livenessProbe.new","text":"
new(port=8080, initialDelaySeconds=30)\n

new constructs a fresh liveness probe, checking if the tcp port 8080 is open

"},{"location":"library/util/#obj-javareadinessprobe","title":"obj java.readinessProbe","text":""},{"location":"library/util/#fn-javareadinessprobenew","title":"fn java.readinessProbe.new","text":"
new(port=18080, path='/actuator/health')\n

new constructs a fresh readiness probe, checking if the application is up. The port and path of the actuator endpoint can be changed using the parameters.

"},{"location":"library/util/#obj-openshiftoauth","title":"obj openshiftOAuth","text":"

openshiftOAuth contains utilities to proxy an application using the OpenShift OAuth Proxy

"},{"location":"library/util/#obj-openshiftoauthcontainer","title":"obj openshiftOAuth.container","text":""},{"location":"library/util/#fn-openshiftoauthcontainernew","title":"fn openshiftOAuth.container.new","text":"
new(upstream, serviceAccount)\n

constructs a container proxying connections to the upstream parameter.

"},{"location":"library/util/#obj-openshiftoauthdeployment","title":"obj openshiftOAuth.deployment","text":""},{"location":"library/util/#fn-openshiftoauthdeploymentwithproxy","title":"fn openshiftOAuth.deployment.withProxy","text":"
withProxy(upstream, serviceAccount)\n

add a proxy sidecar to the container. This also sets the service account used by the pod. The ServiceAccount needs to have the correct redirect reference for the route. See openshiftOAuth.serviceAccount.new for an easy way to create a compliant service account

"},{"location":"library/util/#obj-openshiftoauthserviceaccount","title":"obj openshiftOAuth.serviceAccount","text":""},{"location":"library/util/#fn-openshiftoauthserviceaccountnew","title":"fn openshiftOAuth.serviceAccount.new","text":"
new(name, route)\n

constructs a serviceaccount annotated with a oauth-redirectreference pointing to the route parameter

"},{"location":"modules/","title":"What are modules?","text":"

Modules are ready-to-use setups of existing applications and services. To use them, import them into your main.libsonnet like so:

(import 'cloudflight-libsonnet/databases/mariadb.libsonnet') + {\n  _config+: {\n    mariadb+: {\n      user: 'foo',\n      password: 'bar',\n    }\n  }\n}\n
"},{"location":"modules/java_application/","title":"Java Applications","text":"

Even though not strictly a module, this library contains a lot of utility functions to help you deploy Java applications. This page contains some ways these functions can be used.

"},{"location":"modules/java_application/#all-in-one","title":"All-in-one","text":"

This example contains the deployment of a simple spring boot based application. It should be located somewhere like lib/my-application.libsonnet.

jsonnetyaml
local k = (import 'cloudflight-libsonnet/prelude.libsonnet');\n{\n  _config+:: {\n    myApplication: {\n      name: 'my-application',\n      image: error '$._config.myApplication.image must be defined',\n    },\n  },\n  myApplication: {\n    deployment: k.util.java.deployment.new(\n      name=$._config.myApplication.name,\n      image=$._config.myApplication.image,\n      containerMixin=k.core.v1.container.livenessProbe.withInitialDelaySeconds(60),\n    ),\n    service: k.util.serviceFor(self.deployment),\n    route: k.util.routeFor(self.service, 'hello.example.com'),\n  },\n}\n
apiVersion: v1\nkind: Service\nmetadata:\nlabels:\n    name: my-application\nname: my-application\nnamespace: test-java\nspec:\nports:\n- name: my-application-http\n    port: 8080\n    targetPort: 8080\n- name: my-application-actuator\n    port: 9080\n    targetPort: 9080\nselector:\n    name: my-application\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\nname: my-application\nnamespace: test-java\nspec:\nminReadySeconds: 10\nreplicas: 1\nrevisionHistoryLimit: 10\nselector:\n    matchLabels:\n    name: my-application\ntemplate:\n    metadata:\n    labels:\n        name: my-application\n    spec:\n    containers:\n    - env:\n        - name: SPRING_PROFILES_ACTIVE\n        value: kubernetes\n        image: helloworld:latest\n        imagePullPolicy: IfNotPresent\n        livenessProbe:\n        failureThreshold: 5\n        initialDelaySeconds: 30\n        periodSeconds: 10\n        successThreshold: 1\n        tcpSocket:\n            port: 8080\n        timeoutSeconds: 1\n        name: my-application\n        ports:\n        - containerPort: 8080\n        name: http\n        - containerPort: 9080\n        name: actuator\n        readinessProbe:\n        failureThreshold: 5\n        httpGet:\n            path: /actuator/health\n            port: 18080\n        initialDelaySeconds: 30\n        periodSeconds: 10\n        successThreshold: 1\n        timeoutSeconds: 1\n        resources:\n        limits:\n            cpu: 500m\n            memory: 1Gi\n        requests:\n            cpu: 100m\n            memory: 1Gi\n---\napiVersion: route.openshift.io/v1\nkind: Route\nmetadata:\nname: my-application\nnamespace: test-java\nspec:\nhost: hello.example.com\npath: /\nport:\n    targetPort: 8080\ntls:\n    insecureEdgeTerminationPolicy: Redirect\n    termination: Edge\nto:\n    kind: Service\n    name: my-application\n

Switch between the tabs to see the rendered output

"},{"location":"modules/java_application/#diy","title":"DIY","text":"

If you have the need for further customization, you can pick and choose parts of the library you would like to use.

In this example, we want to modify the container so we use the util.java.container.new() to get a base structure and extend it. This way, we still have the defaults set, but are able to customize them to our hearts content.

jsonnetyaml
local k = (import 'cloudflight-libsonnet/prelude.libsonnet');\n{\n  _config+:: {\n    myApplication: {\n      name: 'my-application',\n      image: error '$._config.myApplication.image must be defined',\n    },\n  },\n  myApplication: {\n    deployment: k.apps.v1.deployment.new(\n                  name=$._config.myApplication.name,\n                  replicas=2,\n                  containers=[\n                    k.util.java.container.new($._config.myApplication.name, $._config.myApplication.image)\n                    + k.core.v1.container.withVolumeMounts([\n                      k.core.v1.volumeMount.new(name='temp', mountPath='/opt/cache'),\n                    ]),\n                  ]\n                )\n                + k.apps.v1.deployment.spec.template.spec.withVolumes([\n                  k.core.v1.volume.fromEmptyDir(name='temp'),\n                ]),\n    service: k.util.serviceFor(self.deployment),\n    route: k.util.routeFor(self.service, 'hello.example.com'),\n  },\n}\n
apiVersion: v1\nkind: Service\nmetadata:\n  labels:\n    name: my-application\n  name: my-application\n  namespace: test-java-diy\nspec:\n  ports:\n  - name: my-application-http\n    port: 8080\n    targetPort: 8080\n  - name: my-application-actuator\n    port: 9080\n    targetPort: 9080\n  selector:\n    name: my-application\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: my-application\n  namespace: test-java-diy\nspec:\n  minReadySeconds: 10\n  replicas: 2\n  revisionHistoryLimit: 10\n  selector:\n    matchLabels:\n      name: my-application\n  template:\n    metadata:\n      labels:\n        name: my-application\n    spec:\n      containers:\n      - env:\n        - name: SPRING_PROFILES_ACTIVE\n          value: kubernetes\n        image: helloworld:latest\n        imagePullPolicy: IfNotPresent\n        livenessProbe:\n          failureThreshold: 5\n          initialDelaySeconds: 30\n          periodSeconds: 10\n          successThreshold: 1\n          tcpSocket:\n            port: 8080\n          timeoutSeconds: 1\n        name: my-application\n        ports:\n        - containerPort: 8080\n          name: http\n        - containerPort: 9080\n          name: actuator\n        readinessProbe:\n          failureThreshold: 5\n          httpGet:\n            path: /actuator/health\n            port: 18080\n          initialDelaySeconds: 30\n          periodSeconds: 10\n          successThreshold: 1\n          timeoutSeconds: 1\n        resources:\n          limits:\n            cpu: 500m\n            memory: 1Gi\n          requests:\n            cpu: 100m\n            memory: 1Gi\n        volumeMounts:\n        - mountPath: /opt/cache\n          name: temp\n      volumes:\n      - emptyDir: {}\n        name: temp\n---\napiVersion: route.openshift.io/v1\nkind: Route\nmetadata:\n  name: my-application\n  namespace: test-java-diy\nspec:\n  host: hello.example.com\n  path: /\n  port:\n    targetPort: 8080\n  tls:\n    insecureEdgeTerminationPolicy: Redirect\n    termination: Edge\n  to:\n    kind: Service\n    name: my-application\n
"},{"location":"modules/applications/mailhog/","title":"Mailhog","text":"

This module creates an instance of mailhog. Data is stored in memory only so messages will disappear after a pod restart.

The following snippet lists all available configuration options alongside their default values:

(import 'cloudflight-libsonnet/applications/mailhog.libsonnet')\n+ {\n  _config+: {\n        mailhog: {\n          name: 'mailhog',\n          image: 'docker.io/anatomicjc/mailhog:1.0.1',\n          host: error '$._config.mailhog.host must be defined',\n          resources:: {\n            limits: {\n              cpu: '20m',\n              memory: '64Mi',\n            },\n            requests: {\n              cpu: '10m',\n              memory: '64Mi',\n            },\n          },\n        },\n\n  }\n}\n
"},{"location":"modules/applications/spring-boot-admin/","title":"Spring Boot Admin","text":"

This module creates an instance of spring-boot-admin, preconfigured to discover endpoints via Kubernetes.

The following snippets lists all available configuration options alongside their default values:

(import 'cloudflight-libsonnet/applications/spring-boot-admin.libsonnet')\n+ {\n  _config+: {\n        springBootAdmin: {\n          name: 'spring-boot-admin',\n          image: 'ghcr.io/cloudflightio/spring-boot-admin-docker:2.7.3',\n          host: error '$._config.springBootAdmin.host must be defined',\n          serviceAccountName: 'default',\n          config: {\n            spring: {\n              cloud: {\n                kubernetes: {\n                  discovery: {\n                    enabled: true,\n                    'service-labels': {\n                      '[app.openshift.io/runtime]': 'spring-boot',\n                    },\n                    catalogServiceWatchDelay: 300,\n                    'primary-port-name': 'actuator',\n                  },\n                },\n              },\n            },\n          },\n          resources:: {\n            limits: {\n              cpu: '500m',\n              memory: '512Mi',\n            },\n            requests: {\n              cpu: '10m',\n              memory: '512Mi',\n            },\n          },\n        },\n\n  }\n}\n
"},{"location":"modules/applications/spring-boot-admin/#integration-and-service-discovery","title":"Integration and Service Discovery","text":"

When using our java helpers, spring-boot-admin will automatically discover provided services and their respective actuator endpoints.

To customize the discovery, modify $._config.springBootAdmin.config.spring.cloud.kubernetes.discovery to match your labels.

"},{"location":"modules/databases/mariadb/","title":"MariaDB Database Module","text":"

This module contains a MariaDB instance, located in the mariadb key.

The following snippets lists all available configuration options alongside their default values:

(import 'cloudflight-libsonnet/databases/mariadb.libsonnet')\n+ {\n  _config+: {\n        mariadb: {\n          name: 'mariadb',\n          storage: '5Gi',\n          user: error 'cfg.user must be defined',\n          password: error 'cfg.password must be defined',\n          database: self.user,\n          image: 'registry.redhat.io/rhel9/mariadb-105:1-105',\n          datadirAction: 'upgrade-warn',  // use 'upgrade-auto' to enable auto-upgrade when going to newer MariaDB version\n          exporterImage: 'docker.io/prom/mysqld-exporter:v0.15.1',\n          exporterPassword: std.md5(self.password),\n          resources:: {\n            limits: {\n              cpu: '500m',\n              memory: '1Gi',\n            },\n            requests: {\n              cpu: '200m',\n              memory: '1Gi',\n            },\n          },\n        },\n\n  }\n}\n
"},{"location":"modules/databases/mariadb/#exposed-values","title":"Exposed values","text":"

The following values are exposed, but not exported:

Name Contents mariadb.passwordSecretKeyRef A kubernetes secretKeyRef, referencing the user password"},{"location":"modules/databases/mariadb/#starting-multiple-instances","title":"Starting multiple instances","text":"

Another way to use this module, is by calling the newMariaDB function. This allows you to create multiple instances without polluting the global scope.

{\n  _config+:: {\n    dbOne: {\n      name: 'dbOne',\n      user: 'foo',\n      password: 'bar',\n    },\n    dbTwo: {\n      name: 'dbTwo',\n      user: 'foo',\n      password: 'bar',\n    }\n  }\n  dbOne: (import 'cloudflight-libsonnet/databases/mariadb.libsonnet').newMariaDB($._config.dbOne),\n  dbTwo: (import 'cloudflight-libsonnet/databases/mariadb.libsonnet').newMariaDB($._config.dbTwo),\n}\n
"},{"location":"modules/databases/mssql/","title":"MSSQL Database Module","text":"

This module contains a simple MSSQL instance, located in the mssql key.

The following snippets lists all available configuration options alongside their default values:

Info

You need to set acceptEula to true to accept the MSSQL EULA

(import 'cloudflight-libsonnet/databases/mssql.libsonnet')\n+ {\n  _config+: {\n        mssql: {\n          name: 'mssql',\n          storage: '5Gi',\n          // The password must be at least 8 characters long and contain characters from three of the following four sets: Uppercase letters, Lowercase letters, Base 10 digits, and Symbols\n          rootPassword: error 'cfg.rootPassword must be defined',\n          productId: 'Developer',\n          image: 'mcr.microsoft.com/mssql/rhel/server:2022-latest',\n          acceptEula: false,\n          resources:: {\n            limits: {\n              cpu: '500m',\n              memory: '2Gi',\n            },\n            requests: {\n              cpu: '200m',\n              memory: '2Gi',\n            },\n          },\n        },\n\n  }\n}\n
"},{"location":"modules/databases/mssql/#exposed-values","title":"Exposed values","text":"

The following values are exposed, but not exported:

Name Contents mssql.passwordSecretKeyRef A kubernetes secretKeyRef, referencing the SA password"},{"location":"modules/databases/redis/","title":"Redis Cache Module","text":"

This module contains a Redis Cache, located in the redis key.

The following snippets lists all available configuration options alongside their default values:

(import 'cloudflight-libsonnet/databases/redis.libsonnet')\n+ {\n  _config+: {\n        redis: {\n          name: 'redis',\n          image: 'registry.redhat.io/rhel8/redis-6:1-62',\n          exporterImage: 'docker.io/oliver006/redis_exporter:v1.43.0',\n          password: error 'cfg.password must either be defined or set to null',\n          storage: null,\n          resources:: {\n            limits: {\n              cpu: '100m',\n              memory: '1Gi',\n            },\n            requests: {\n              cpu: '50m',\n              memory: '1Gi',\n            },\n          },\n        },\n\n  }\n}\n
"},{"location":"modules/databases/redis/#starting-multiple-instances","title":"Starting multiple instances","text":"

Another way to use this module, is by calling the newRedis function. This allows you to create multiple instances without polluting the global scope.

{\n  _config+:: {\n    cacheOne: {\n      name: 'cacheOne',\n      password: 'foo',\n    },\n    cacheTwo: {\n      name: 'cacheTwo',\n      password: 'bar',\n    }\n  },\n  cacheOne: (import 'cloudflight-libsonnet/databases/redis.libsonnet').newRedis($._config.cacheOne),\n  cacheTwo: (import 'cloudflight-libsonnet/databases/redis.libsonnet').newRedis($._config.cacheTwo),\n}\n
"},{"location":"modules/databases/redis/#high-availability","title":"High Availability","text":"

If required, you can instead import the redis-sentinel module. This creates an additional sentinel deployment which fails over the master and replicas:

(import 'cloudflight-libsonnet/databases/redis-sentinel.libsonnet')\n+ {\n  _config+: {\n        redis: {\n          name: 'redis',\n          replicas: 3,\n          sentinels: 3,\n          image: 'quay.io/fedora/redis-6:20221012',\n          exporterImage: 'docker.io/oliver006/redis_exporter:v1.43.0',\n          password: error 'cfg.password must either be defined or set to null',\n          topologyKey: 'kubernetes.io/hostname',\n          storage: null,\n          resources:: {\n            limits: {\n              cpu: '100m',\n              memory: '1Gi',\n            },\n            requests: {\n              cpu: '50m',\n              memory: '1Gi',\n            },\n          },\n        },\n\n  }\n}\n
"},{"location":"modules/databases/redis/#exposed-values","title":"Exposed values","text":"

When using redis-sentinel, you also have access to the following values. They are exposed, but not exported.

Name Contents redis.sentinelNodes Array of sentinel host:port pairs"},{"location":"modules/infrastructure/cert-manager/","title":"Cert-Manager Module","text":"

This adds certmanager (see https://cert-manager.io/), located in the certmanager key.

It helpes you issuing and managing certificated using custom k8s resources only.

The following snippets lists all available configuration options alongside their default values:

(import 'cloudflight-libsonnet/infrastructure/cert-manager/cert-manager.libsonnet')\n+ {\n  _config+: {\n        certmanager: {\n          name: 'cert-manager',\n          aks: false,\n        },\n\n  }\n}\n
"},{"location":"modules/infrastructure/cert-manager/#example","title":"Example","text":"
(import 'cloudflight-libsonnet/infrastructure/cert-manager/cert-manager.libsonnet')\n+ {\n  _config+: {\n    certmanager: {\n      name: 'cert-manager',\n      namespace: 'cert-manager',\n      aks: true,\n    },\n  },\n}\n
"},{"location":"modules/infrastructure/cert-manager/#addons","title":"Addons","text":"

There is also a special set of utilities and extensions that can be used to make the setup process easier.

This example installs cert-manager, adds a lets-encrypt issuer and a ssl-protected ingress-rule:

local k = (import 'k.libsonnet');\nlocal ingress = k.networking.v1.ingress;\n\n(import 'cloudflight-libsonnet/infrastructure/cert-manager/cert-manager.libsonnet')\n+ {\n  issuer: k.util.certmanager.issuer.new('admin@example.com'),\n  ingress: ingress.new('test.example.com') + ingress.withCertMixin($.issuer),\n}\n
"},{"location":"modules/infrastructure/k8s-digester/","title":"k8s-digester Module","text":"

This module installs the k8s-digester in your cluster. It currently does not offer any customization options and is functionally equivalent to applying the digester_manifest.yaml.

The reason for this module is to have everything you need in one place without relying on manual kubectl apply steps.

"},{"location":"modules/infrastructure/nginx-ingress/","title":"Nginx-Ingress Module","text":"

This adds nginx-ingress-controller (see https://github.com/kubernetes/ingress-nginx), located in the nginxingress key.

This is helpful if no other ingress-controller is deployes (e.g. AKS without API Gateway).

The following snippets lists all available configuration options alongside their default values:

(import 'cloudflight-libsonnet/infrastructure/nginx-ingress/nginx-ingress.libsonnet')\n+ {\n  _config+: {\n        nginxingress: {\n          name: 'nginx-ingress',\n          type: 'external',\n          loadBalancerIP: error 'you need a static loadbalancer ip (public IP for external, internal IP for internal)',\n          internalSubnetAzure: null,\n          replicas: 2,\n          defaultTlsCertificate: null,\n        },\n\n  }\n}\n
"}]} \ No newline at end of file diff --git a/main/sitemap.xml.gz b/main/sitemap.xml.gz index a39daccec3235e9aa1e66e34a9e92d44c7413e35..3584e9f73c429ac8b67a6e1be4c652e32529eb92 100644 GIT binary patch delta 13 Ucmb=gXP58h;9$5SH<7&p02(I)!T