1. The Promise Repository Structure#
A standard Kratix Promise consists of two primary components:
- The Pipeline Source Code: The bash, Python, or Go code that actually processes the developer’s claim.
- The Promise YAML Definition: The Custom Resource Definition (CRD) and the configuration that references the Pipeline’s compiled Docker image.
To manage this properly, you should organize your Git repository (e.g., acmecorp-promises) like a standard software project:
kratix-promises/
└── redis/
├── pipeline/
│ ├── Dockerfile
│ └── execute.sh
└── promise.yaml2. The CI Phase: Building the Pipeline#
When a Platform Engineer makes a change to execute.sh (for example, adding a new feature that automatically provisions a Grafana dashboard alongside the Redis database), they will open a Pull Request (PR) in GitHub.
We need GitHub Actions to automatically detect this PR, build the Docker image, and push it to our Docker registry, tagged dynamically with the Git commit hash.
Create a file at .github/workflows/ci.yml:
name: CI - Build Promise Pipelines
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build-redis-pipeline:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and Push Pipeline Image
uses: docker/build-push-action@v4
with:
context: ./redis/pipeline
push: true
# Crucial: Tag the image with the unique Git SHA!
tags: acmecorp/redis-pipeline:${{ github.sha }}3. The CD Phase: Releasing the Promise#
Once the new Docker image is pushed to the registry, we have a problem. The promise.yaml file in our repository is still hardcoded to look for an old image (e.g., image: acmecorp/redis-pipeline:v1).
We need to dynamically update that YAML file to point to our newly built github.sha image, and then automatically deploy that updated Promise to the Kratix Platform Cluster.
We can use yq (a powerful command-line YAML processor) inside our GitHub Action to rewrite the image tag on the fly.
Add this deployment job to your workflow file:
deploy-promise:
needs: build-redis-pipeline
runs-on: ubuntu-latest
# Only deploy to the cluster if the code is merged to main!
if: github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install yq
run: sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 && sudo chmod +x /usr/local/bin/yq
- name: Inject new Image Tag into Promise YAML
run: |
# This command searches for the specific container in the Promise and replaces its image tag
yq e -i '.spec.workflows.resource.configure[0].spec.containers[0].image = "acmecorp/redis-pipeline:${{ github.sha }}"' ./redis/promise.yaml
- name: Setup Kubeconfig
run: |
mkdir -p ~/.kube
echo "${{ secrets.KUBECONFIG }}" > ~/.kube/config
- name: Deploy Promise to Kratix Platform Cluster
run: |
kubectl apply -f ./redis/promise.yaml4. The Platform Release Workflow#
Let’s review the complete lifecycle of a Platform Engineering update:
- Feature Request: The E-Commerce Developers ask the Platform Team for Redis High-Availability (HA) support.
- Platform Engineering: A Platform Engineer edits the
execute.shbash script in thekratix-promisesrepository to output HA YAML if the developer selectssize: large. - Pull Request: The Engineer opens a PR.
- CI Build: GitHub Actions automatically builds the new Pipeline Docker image and tags it as
redis-pipeline:a1b2c3d. - Merge: The Platform Tech Lead reviews the bash script and merges the PR into
main. - CD Deploy: GitHub Actions updates the
promise.yamlwith the newa1b2c3dimage tag and runskubectl applyagainst the Platform Cluster.
Instantly, the API in the Platform Cluster is updated. The very next time an E-Commerce developer requests a Redis instance, Kratix will boot the brand new pipeline image, and the developer will receive an HA cluster.
Troubleshooting & Common Errors#
kubectl applyfails in GitHub Actions due to permissions- Root Cause: The
KUBECONFIGsecret you provided to GitHub Actions belongs to a Kubernetes Service Account that does not haveClusterAdminpermissions. Kratix Promises contain CRDs, which require cluster-wide RBAC privileges to install. - Solution: Ensure the CI/CD Service Account is bound to the
cluster-adminClusterRole inside the Platform Cluster.
- Root Cause: The
Existing Developer Claims are not updating to the new Pipeline
- Root Cause: Updating a Promise does not automatically trigger a re-run of existing claims. If a developer provisioned Redis v1 yesterday, they will stay on v1 until they manually edit their YAML (triggering an update), or until a Platform Engineer forces a reconciliation.
- Solution: This is intentional behavior designed to prevent breaking production environments. If you want to force all existing Redis instances to upgrade to v2, Kratix provides APIs to manually trigger pipeline re-runs across all claims.
Conclusion & Next Steps#
By automating the build and deployment of Promises, your Platform Team can iterate incredibly fast. You can treat your Internal Developer Platform like a true SaaS product, releasing new features, fixing bugs, and deploying updates securely.
However, as you deploy hundreds of workloads across dozens of clusters, how do you monitor them? If a pipeline fails in the Platform cluster, or ArgoCD fails in a Worker cluster, how do you know?
In Episode 10: Observability and Operations, we will instrument the Kratix ecosystem with Prometheus and Grafana to build a centralized monitoring dashboard for your entire IDP fleet.

