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
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
Steps
- Install Promises
- Request instances
- Run the deploy pipeline
- Test the application
- Summary
- 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
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 --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
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:
kubectl --context $WORKER get secret jenkins-operator-credentials-dev-example \
-o 'jsonpath={.data.user}' | base64 -d
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
- From the Dashboard page, click New Item in the left menu
- Enter a name for the pipeline, e.g.
todo-app-pipeline
- Select Pipeline from the Select item type dropdown
- Click OK
- In the Pipeline section, paste the contents of the Jenkinsfile in the Script field
- Click Save
- Click Build Now in the left menu
- Click on the running build
- 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:
- ✅ Installed all three Kratix Promises
- ✅ Requested an instance of each Kratix Promise
- ✅ Created and run a CI/CD pipeline for a new application
- ✅ 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.