Skip to main content

Using Multiple Promises

This is Part 3 of a series illustrating how Kratix works.
👈🏾   Previous: Install a Kratix Promise
👉🏾   Next: Writing and installing a Kratix Promise

Pre-requisites

If you completed the environment cleanup steps at the end of the previous workshop chapter your good to go! If you did not cleanup or ran into issues you can run the following from inside the Kratix repo to get a fresh environment:

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

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 $PLATFORM apply --filename https://raw.githubusercontent.com/syntasso/kratix-marketplace/main/postgresql/promise.yaml
kubectl --context $PLATFORM apply --filename https://raw.githubusercontent.com/syntasso/kratix-marketplace/main/knative/promise.yaml
kubectl --context $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 $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 $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 $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 $PLATFORM apply --filename https://raw.githubusercontent.com/syntasso/kratix-marketplace/main/postgresql/resource-request.yaml
kubectl --context $PLATFORM apply --filename https://raw.githubusercontent.com/syntasso/kratix-marketplace/main/knative/resource-request.yaml
kubectl --context $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 $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 $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 $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 $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 $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 $WORKER get secret jenkins-operator-credentials-dev-example \
-o 'jsonpath={.data.user}' | base64 -d
password
kubectl --context $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 $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 $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 $PLATFORM delete jenkins,knative,postgresqls --all

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

kubectl --context $WORKER get pods,namespaces

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

kubectl --context $PLATFORM delete promises --all

Verify the Worker Cluster resources are deleted from the Worker Cluster

kubectl --context $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.