Skip to main content

Using Multiple Promises

Pre-requisites

You need a fresh installation of Kratix for this section. The simplest way to do so is by running the quick-start script from within the Kratix directory.

./scripts/quick-start.sh --recreate

Alternatively, you can go back to Installing Kratix and follow the appropriate guide.

In this tutorial, you will

  1. learn more about the power of Promises
  2. use Kratix Promises to build a paved path

The power of Promises

As covered previously, Promises are the building blocks that enable teams to design platforms that specifically meet their customer needs. Through writing and extending Promises, Platform teams can raise the value line of the platform they provide. They can use multiple simpler, low-level Promises to provide an experience tailored to their users needs.

Consider the task of setting up development environments for application teams. This task is usually repetitive and requires many cookie-cutter steps. It may involve wiring up Git repos, spinning up a CI/CD server, creating a PaaS to run the applications, instructing CI/CD to listen to the Git repos and push successful builds into the PaaS, and finally wiring applications to their required data services.

A Promise can encapsulate all the required steps and handle the toil of running those low-level tasks. It can be designed as a single Promise that does it all, or it can be a collection of Promises that, combined, deliver the desired functionality.

Now you will see the power of Kratix Promises by deploying a web app that uses multiple Promises.




Building a paved path using multiple Kratix Promises

Overview

Steps

  1. Install Promises
  2. Request instances
  3. Run the deploy pipeline
  4. Test the application
  5. Summary
  6. Cleanup environment

Install all required Promises

In order for an application team to deploy an application to a dev environment they require a relational datastore (postgres), networking for user traffic (Knative), and a CI/CD service for ongoing improvements (Jenkins). To deliver this functionality on-demand with Kratix install the required Promises on your Platform Cluster:

kubectl --context kind-platform apply --filename https://raw.githubusercontent.com/syntasso/kratix-marketplace/main/postgresql/promise.yaml
kubectl --context kind-platform apply --filename https://raw.githubusercontent.com/syntasso/kratix-marketplace/main/knative/promise.yaml
kubectl --context kind-platform apply --filename https://raw.githubusercontent.com/syntasso/kratix-marketplace/main/jenkins/promise.yaml

Verify the Promises are all installed on your Platform Cluster

kubectl --context kind-platform get promises

The above command will give an output similar to

NAME         AGE
jenkins 1m
knative 1m
postgresql 1m

Verify the CRDs are all installed on your Platform Cluster. Note that you know have jenkins, knative, and postgres available.

kubectl --context kind-platform get crds

The above command will give an output similar to

NAME                                CREATED AT
clusters.platform.kratix.io 2023-01-24T17:00:37Z
jenkins.marketplace.kratix.io 2023-01-24T17:22:50Z
knatives.marketplace.kratix.io 2023-01-24T17:23:50Z
postgresqls.marketplace.kratix.io 2023-01-24T17:23:51Z
promises.platform.kratix.io 2023-01-24T17:00:37Z
workplacements.platform.kratix.io 2023-01-24T17:00:37Z
works.platform.kratix.io 2023-01-24T17:00:37Z

Verify the workerClusterResources (more details in future steps) are installed on your Worker Cluster
(This may take a few minutes so --watch will watch the command. Press Ctrl+C to stop watching)

kubectl --context kind-worker get pods --watch

The above command will give an output similar to

NAME                                 READY   STATUS    RESTARTS   AGE
jenkins-operator-6c89d97d4f-r474w 1/1 Running 0 1m
postgres-operator-7dccdbff7c-2hqhc 1/1 Running 0 1m

Request instances

Overview-instances

Submit a set of Kratix Resource Requests to get a Knative Serving component, a Jenkins instance and a Postgres database.

kubectl --context kind-platform apply --filename https://raw.githubusercontent.com/syntasso/kratix-marketplace/main/postgresql/resource-request.yaml
kubectl --context kind-platform apply --filename https://raw.githubusercontent.com/syntasso/kratix-marketplace/main/knative/resource-request.yaml
kubectl --context kind-platform apply --filename https://raw.githubusercontent.com/syntasso/kratix-marketplace/main/jenkins/resource-request.yaml

By requesting these three resources, you will start three pods, one for the Jenkins server (named jenkins-dev-example), and two which create a postgres cluster (named per the Resource Request name,acid-example-postgresql). To verify you have all the necessary resources up and running
(This may take a few minutes so --watchwill watch the command. Press Ctrl+C to stop watching)

kubectl --context kind-worker get pods --watch

The above command will give an output similar to

NAME                                READY   STATUS      RESTARTS   AGE
acid-example-postgresql-0 1/1 Running 0 5m
jenkins-dev-example 1/1 Running 0 5m
...

Verify that knative has also installed its networking resources into two new namespaces

kubectl --context kind-worker get namespaces

The above command will give an output similar to

NAME                   STATUS   AGE
knative-serving Active 1h
kourier-system Active 1h
...

Verify that the Kratix Resource Request was issued on the Platform Cluster.

kubectl --context kind-platform get jenkins.marketplace.kratix.io

The above command will give an output similar to

NAME          AGE
example 1m

Run the application deploy pipeline

With all the necessary resources available, you will now change hats to be a part of the application team who can now design and run their own CI/CD pipeline using the provided Jenkins service. In this step, you will deploy a sample application through a Jenkins pipeline, that uses Postgres for persistence and Knative for serving the application.

First, create a service account on the Worker cluster, so Jenkins can create Knative Services from the pipeline:

kubectl --context kind-worker apply -f \
https://raw.githubusercontent.com/syntasso/sample-golang-app/main/k8s/service-account.yaml

Access the Jenkins UI in a browser, as in the previous step. Port forward for browser access to the Jenkins UI:

kubectl --context kind-worker port-forward jenkins-dev-example 8080:8080

Navigate to http://localhost:8080 and log in with the credentials you get from the commands below:

username
kubectl --context kind-worker get secret jenkins-operator-credentials-dev-example \
-o 'jsonpath={.data.user}' | base64 -d
password
kubectl --context kind-worker get secret jenkins-operator-credentials-dev-example \
-o 'jsonpath={.data.password}' | base64 -d

In the Jenkins UI, create a new pipeline using this Jenkinsfile and execute it.

For those that are less familiar with Jenkins, you can either expand the instructions below or watch the video to see how to navigate the UI for this task.

Configuring a Jenkins Pipeline
  1. From the Dashboard page, click New Item in the left menu
  2. Enter a name for the pipeline, e.g. todo-app-pipeline
  3. Select Pipeline from the Select item type dropdown
  4. Click OK
  5. In the Pipeline section, paste the contents of the Jenkinsfile in the Script field
  6. Click Save
  7. Click Build Now in the left menu
  8. Click on the running build
  9. Click Console Output to see the pipeline progress

Validate the deployment

Verify that the Knative Service for the application is ready:

kubectl --context kind-worker get services.serving.knative.dev

The above command will give an output similar to

NAME   URL                            LATESTCREATED   LATESTREADY   READY   REASON
todo http://todo.default.local.gd todo-00001 todo-00001 True

Test the deployed application

Now test the app.

On a separate terminal, you'll need to open access to the app by port-forwarding the kourier service:

kubectl --context kind-worker --namespace kourier-system port-forward svc/kourier 8081:80

Now go to http://todo.default.local.gd:8081 to see the app running.

Summary

Your platform has pieced together three different Promises to provide a complete solution for an application team to deploy a new service to dev using your suggested CI/CD and hosting solutions. Well done!

To recap the steps we took:

  1.   Installed all three Kratix Promises
  2.   Requested an instance of each Kratix Promise
  3.   Created and run a CI/CD pipeline for a new application
  4.   Viewed an endpoint from a newly deployed and networked application

This is only the beginning of working with Promises. Next you will learn how to write and update Promises, and in the final thoughts we will showcase the composability of Promises to further optimise this workflow from three requests down to one.

Cleanup environment

To clean up your environment first delete the Resource Requests for the Jenkins, Knative and Postgres Promises.

kubectl --context kind-platform delete jenkins,knative,postgresqls --all

Verify the resources belonging to the Resource Requests have been deleted in the Worker Cluster

kubectl --context kind-worker get pods,namespaces

Now all the Resource Requests have been deleted you can delete the Promises

kubectl --context kind-platform delete promises --all

Verify the Worker Cluster resources are deleted from the Worker Cluster

kubectl --context kind-worker get pods

🎉   Congratulations!

   You have deployed a web app that uses multiple Kratix Promises.
👉🏾   Now you will write your own Jenkins Promise to learn more about how Kratix Promises work.